vue+G6图形化实现功能示例

 更新时间:2023年07月03日 11:49:52   作者:忘れられたくない  
这篇文章主要为大家介绍了vue+G6图形化实现功能示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

g6安装 

g6安装

 npm install --save @antv/g6

初始化画布

plugins:存储的为插件容器
container:String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身
width:图的宽度
height:图的高度
fitView:视图居中
defaultNode:默认元素样式
defaultEdge:默认线样式(设置透明度为0.2,防止线太多,看着错乱)

this.graph = new G6.Graph({
    plugins: ['tooltip'], // 配置  插件
    container: "g-container", // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身
    width: 800, // Number,必须,图的宽度
    height: 500, // Number,必须,图的高度
    fitView: true,
    defaultNode: {
      size: [34, 34],
      style: {
        fill: "#ffffff",
        stroke: "rgba(0,0,0,.35)",
        lineWidth: 2,
        cursor: "pointer",
        radius: [2, 2],
        opacity: 0.2,
      },
      labelCfg: {
        style: {
          fontSize: 14,
        },
        position: "bottom",
        offset: 5,
      },
    },
    defaultEdge: {
      type: "line",
      color: "#999999",
      style: {
        opacity:0.2,
        cursor: "pointer",
        endArrow: {
          path: G6.Arrow.vee(6, 5, 0),
          d: 0,
          fill: "red",
          cursor: "pointer",
          lineDash: [0],
        },
      },
      labelCfg: {
        autoRotate: true,
        style: {
          background: {
            fill: "#ffffff",
            stroke: "#000000",
            padding: [2, 2, 2, 2],
            radius: 2,
            cursor: "pointer",
          },
        },
      },
    },
    },
    modes: {
      default: [
        {
          type: "zoom-canvas",
          enableOptimize: true,
          optimizeZoom: 0.9,
        },
        {
          type: "drag-canvas",
          enableOptimize: true,
        },
        "drag-node",
        "brush-select",
        "click-select",
      ],
    },
  });

读取 Step 2 中的数据源到图上

this.graph.data(this.data); // 读取 Step 2 中的数据源到图上

渲染图

this.graph.render(); // 渲染图

气泡悬浮提示(插件)

// 提示
  const tooltip = new G6.Tooltip({
    offsetX: 10,
    offsetY: 40,
    getContent: (e) => {
      const outDiv = document.createElement("div");
      outDiv.style.width = "fit-content";
      outDiv.style.height = "fit-content";
      const model = e.item.getModel();
      if (e.item.getType() === "node") {//判断是元素还是关系线
        outDiv.innerHTML = `${model.id}`;
      } else {
        const source = e.item.getSource();
        const target = e.item.getTarget();
        outDiv.innerHTML = `来源:${source.getModel().id}<br/>去向:${
          target.getModel().id
        }`;
      }
      return outDiv;
    },
  });

自定义元素

// 自定义一个名为 quadrilateral 的节点,通过数据type来判断元素
      G6.registerNode(
        "quadrilateral",
        {
          draw(cfg, group) {
            const size = this.getSize(cfg); // 转换成 [width, height] 的模式
            const color = cfg.color;
            const width = size[0];
            const height = size[1];
            //  / 1 \
            // 4     2
            //  \ 3 /
            const path = [
              ["M", -width / 4, 0 - height / 1.5], // 上部顶点
              ["L", width / 2, 0 - height / 1.5], // 右侧顶点
              ["L", width / 4, 0], // 下部顶点
              ["L", -width / 2, 0], // 左侧顶点
              ["Z"], // 封闭
            ];
            const style = { path: path, stroke: color, ...cfg.style };
            // 增加一个 path 图形作为 keyShape
            const keyShape = group.addShape("path", {
              attrs: {
                ...style,
              },
              draggable: true,
              name: "diamond-keyShape", // 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
            });
            // 返回 keyShape
            return keyShape;
          },
          afterDraw(cfg, group) {
            const size = this.getSize(cfg); // 转换成 [width, height] 的模式
            const color = cfg.color;
            const width = size[0];
            const height = size[1];
            //  / 1 \
            // 4     2
            //  \ 3 /
            const path = [
              ["M", -width / 4, 0 - height / 1.5], // 上部顶点
              ["L", width / 2, 0 - height / 1.5], // 右侧顶点
              ["L", width / 4, 0], // 下部顶点
              ["L", -width / 2, 0], // 左侧顶点
              ["Z"], // 封闭
            ];
            const style = { path: path, stroke: color, ...cfg.style };
            // 增加一个 path 图形作为 keyShape
            const keyShape = group.addShape("path", {
              attrs: {
                ...style,
              },
              draggable: true,
              name: "diamond-keyShape", // 在 G6 3.3 及之后的版本中,必须指定 name,可以是任意字符串,但需要在同一个自定义元素类型中保持唯一性
            });
            // 返回 keyShape
            return keyShape;
          },
        },
        // 注意这里继承了 'single-node'
        "rect"
      );

新增、编辑、删除

新增

从外部拖拽到画布上,先获取画布的位置坐标

point = this.graph.getPointByClient(e.clientX, e.clientY)

新增元素(rect为正方形)

this.graph.addItem("node", {
  x: point.x,//x坐标
  y: point.y,//y坐标
  label: "name",
  type: "rect",
  id:'123',
  size: [100, 100],//大小
  style: {//样式
    lineWidth: 2,
    stroke: "#00BBEF",
    fill: "#DAF3FF",
  },
  nodeStateStyles: {//状态样式
    selected: {//选中样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
    hover: {//悬浮样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
  },
 });

设置选中状态

this.graph.setItemState(item, "selected", true);

取消选中状态

this.graph.setItemState(item, "selected", false);

设置悬浮状态

this.graph.setItemState(item, "hover", true);

取消悬浮状态

this.graph.setItemState(item, "hover", false);

编辑更新元素

this.graph.updateItem("123", //id
{
  x: point.x,//x坐标
  y: point.y,//y坐标
  label: "name",
  type: "rect",
  id:'123',
  size: [100, 100],//大小
  style: {//样式
    lineWidth: 2,
    stroke: "#00BBEF",
    fill: "#DAF3FF",
  },
  nodeStateStyles: {//状态样式
    selected: {//选中样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
    hover: {//悬浮样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
  },
 });

删除

this.graph.removeItem('123')

关系线新增、编辑、删除

新增

this.graph.addItem("edge", {
  label: "name",
  type: "line",
  id:'edge123',
  target:'node1',//源
  source:'node2',//目标
  style: {//样式
    lineWidth: 2,
    lineDash:[8]//虚线
  },
  nodeStateStyles: {//状态样式
    selected: {//选中样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
    hover: {//悬浮样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
  },
 });

编辑更新关系

this.graph.updateItem("edge123", //id
{
  label: "name",
  type: "line",
  id:'edge123',
  target:'node1',//源
  source:'node2',//目标
  style: {//样式
    lineWidth: 2,
    lineDash:[8]//虚线
  },
  nodeStateStyles: {//状态样式
    selected: {//选中样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
    hover: {//悬浮样式
      lineWidth: 1,
      stroke: "#00BBEF",
    },
  },
 });

删除关系

this.graph.removeItem('edge123')

拖拽元素获取位置

// 拖动node节点
  this.graph.on("node:dragend", (ev) =&gt; {
    console.log(ev);
    let{x,y} = ev.item.getModel()
  })

元素显示与隐藏

//node为元素节点,123为元素的id
let node = this.graph.findById('123')
//隐藏
node.hide()
//显示
node.show()

悬停关联线高亮线两边元素

先监听关联线鼠标移入事件,再监听移除事件

鼠标移入时,高亮线及两边元素

鼠标移出时,取消线及两边元素高亮

//鼠标悬停线,高亮相关元素
  this.graph.on("edge:mouseenter", (e) => {
    e.stopPropagation();
    const source = e.item.getSource();
    const target = e.item.getTarget();
    //高亮
    this.graph.setItemState(source, "hover", true);
    this.graph.setItemState(target, "hover", true);
    this.graph.setItemState(e.item, "hover", true);
    //设置层级最前显示(防止被覆盖)
    source.toFront()
    target.toFront()
    e.item.toFront()
    //因为初始化了线透明的为0.2,所有这里把透明度设置1,方便查看
    this.graph.updateItem(e.item,{
        style:{opacity:1}
    })
  });
//鼠标悬停线,取消高亮相关元素
  this.graph.on("edge:mouseleave", (e) => {
    e.stopPropagation();
    const source = e.item.getSource();
    const target = e.item.getTarget();
    //取消高亮
    this.graph.setItemState(source, "hover", false);
    this.graph.setItemState(target, "hover", false);
    this.graph.setItemState(e.item, "hover", false);
    this.graph.updateItem(e.item,{
        style:{opacity:0.2}
    })
  });

选中元素高亮当前元素及关系兄弟节点及线

1、设置所有元素透明度0.2

2、高亮当时点击元素,透明度为1

3、判断线的源数据和目标数据是否和当前点击的节点有关系,有则高亮,无则显示暗度

this.graph.on("node:click",ev=>{
  if(!ev) return
  let {id} = ev.tem.getModel()
  this.graph.setItemState(id,'selected',true)
  ev.item.toFront();
  //用于存储id,清除之前的状态
  this.positionId = id
  //设置所有元素透明度0.2
  this.graph.getNodes().forEach(node=>{
    this.graph.updateItem(node,{style:{opacity:0.2}})
  })
  //高亮当前点击元素
  this.graph.updateItem(ev.item,{style:{opacity:1}})
  //元素居中
  this.graph.focusItem(ev.item)
  //高亮关联线及节点
  this.graph.getEdges().forEach(edge=>{
    if(edge.getSouce() === ev.item){
      this.graph.updateItem(edge.getTarget(),{style:{opacity:1}})
      this.graph.updateItem(edge,{style:{opacity:1}})
      edge.toFront()
    }else if(edge.getTarget() === ev.item){
      this.graph.updateItem(edge.getSouce(),{style:{opacity:1}})
      this.graph.updateItem(edge,{style:{opacity:1}})
      edge.toFront()
    }else{
      this.graph.updateItem(edge,{style:{opacity:0.2}})
    }
  })
})

点击空白处,清除标记状态

this.graph.on("canvas:click",()=>{
  this.graph.getNodes().forEach(node=>{
    if(this.positionId){
      //设置所有元素透明度0.2
      this.graph.updateItem(node,{style:{opacity:0.2}})
      }
    this.graph.clearItemStatus(node)
  })
  this.graph.getEdges().forEach(edge=>{
    if(this.positionId){
      //关联线0.2
      this.graph.updateItem(edge,{style:{opacity:0.2}})
      }
    this.graph.clearItemStatus(edge)
  })
})

以上就是vue+G6图形化实现功能示例的详细内容,更多关于vue G6图形化的资料请关注脚本之家其它相关文章!

相关文章

  • vue的代理配置pathRewrite重写不生效问题及解决

    vue的代理配置pathRewrite重写不生效问题及解决

    这篇文章主要介绍了vue的代理配置pathRewrite重写不生效问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • element UI 2.15.13与vue2.0表格勾选回显关键demo

    element UI 2.15.13与vue2.0表格勾选回显关键demo

    这篇文章主要为大家介绍了element UI 2.15.13与vue2.0表格勾选回显关键demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • vue中keep-alive组件的用法示例

    vue中keep-alive组件的用法示例

    众所周知keep-alive是Vue提供的一个抽象组件,主要是用来对组件进行缓存,从而做到节省性能,这篇文章主要给大家介绍了关于vue中keep-alive组件用法的相关资料,需要的朋友可以参考下
    2021-05-05
  • vue递归实现三级菜单

    vue递归实现三级菜单

    这篇文章主要为大家详细介绍了vue递归实现三级菜单,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • VUE 项目在IE11白屏报错 SCRIPT1002: 语法错误的解决

    VUE 项目在IE11白屏报错 SCRIPT1002: 语法错误的解决

    这篇文章主要介绍了VUE 项目在IE11白屏报错 SCRIPT1002: 语法错误的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • axios全局注册,设置token,以及全局设置url请求网段的方法

    axios全局注册,设置token,以及全局设置url请求网段的方法

    今天小编就为大家分享一篇axios全局注册,设置token,以及全局设置url请求网段的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • vue分割面板封装实现记录

    vue分割面板封装实现记录

    这篇文章主要为大家详细介绍了vue分割面板封装实现记录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Vue3中element-plus全局使用Icon图标的过程详解

    Vue3中element-plus全局使用Icon图标的过程详解

    我们在用vue开发网站的时候,往往图标是起着很重要的作,这篇文章主要给大家介绍了关于Vue3中element-plus全局使用Icon图标的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • 原生Vue 实现右键菜单组件功能

    原生Vue 实现右键菜单组件功能

    这篇文章主要介绍了Vue 原生实现右键菜单组件功能,本文给大家扩展知识点vue点击菜单以外区域,隐藏菜单操作,通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2019-12-12
  • vue实现codemirror代码编辑器中的SQL代码格式化功能

    vue实现codemirror代码编辑器中的SQL代码格式化功能

    这篇文章主要介绍了vue实现codemirror代码编辑器中的SQL代码格式化功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08

最新评论