vue+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) => { 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图形化的资料请关注脚本之家其它相关文章!
相关文章
vue3+Element Plus实现自定义穿梭框的详细代码
找到一个好用的vue树形穿梭框组件都很难,又不想仅仅因为一个穿梭框在element-ui之外其他重量级插件,本文给大家分享vue3+Element Plus实现自定义穿梭框的示例代码,感兴趣的朋友一起看看吧2024-01-01解决Vue项目Network: unavailable的问题
项目只能通过Local访问而不能通过Network访问,本文主要介绍了解决Vue项目Network: unavailable的问题,具有一定的参考价值,感兴趣的可以了解一下2024-06-06
最新评论