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图形化的资料请关注脚本之家其它相关文章!

相关文章

  • Vant的安装和配合引入Vue.js项目里的方法步骤

    Vant的安装和配合引入Vue.js项目里的方法步骤

    这篇文章主要介绍了Vant的安装和配合引入Vue.js项目里的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • hansontable在vue中的基本使用教程

    hansontable在vue中的基本使用教程

    handsontable是目前在前端界最接近excel的插件,可以执行编辑,复制粘贴,插入删除行列,排序等复杂操作,这篇文章主要介绍了hansontable在vue中的基本使用,需要的朋友可以参考下
    2022-10-10
  • vue登录以及权限验证相关的实现

    vue登录以及权限验证相关的实现

    这篇文章主要介绍了vue登录以及权限验证相关的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • Vue项目如何获取本地文件夹绝对路径

    Vue项目如何获取本地文件夹绝对路径

    这篇文章主要介绍了Vue项目如何获取本地文件夹绝对路径问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • vue3+Element Plus实现自定义穿梭框的详细代码

    vue3+Element Plus实现自定义穿梭框的详细代码

    找到一个好用的vue树形穿梭框组件都很难,又不想仅仅因为一个穿梭框在element-ui之外其他重量级插件,本文给大家分享vue3+Element Plus实现自定义穿梭框的示例代码,感兴趣的朋友一起看看吧
    2024-01-01
  • 解决Vue项目Network: unavailable的问题

    解决Vue项目Network: unavailable的问题

    项目只能通过Local访问而不能通过Network访问,本文主要介绍了解决Vue项目Network: unavailable的问题,具有一定的参考价值,感兴趣的可以了解一下
    2024-06-06
  • vue正确使用watch监听属性变化方式

    vue正确使用watch监听属性变化方式

    这篇文章主要介绍了vue正确使用watch监听属性变化方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vue使用lodash进行防抖节流的实现

    Vue使用lodash进行防抖节流的实现

    本文主要介绍了Vue使用lodash进行防抖节流的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 一文教你如何一个Vue指令搞定函数防抖

    一文教你如何一个Vue指令搞定函数防抖

    防抖(Debounce)在前端开发中是一种常用的技术,它的作用是限制某个操作在短时间内的频繁触发,下面我们就来看看如何一个Vue指令搞定函数防抖吧
    2024-02-02
  • vue实现的封装全局filter并统一管理操作示例

    vue实现的封装全局filter并统一管理操作示例

    这篇文章主要介绍了vue实现的封装全局filter并统一管理操作,结合实例形式详细分析了vue封装全局filter及相关使用技巧,需要的朋友可以参考下
    2020-02-02

最新评论