vue中使⽤AntVG6编写树形结构图并实现节点增删改
效果图:
先在vue项⽬中安装antv G6
npm install --save @antv/g6
安装完之后引⼊,我是将整个结构图的某些相关配置进⾏了封装,写在了公共js⽂件⾥⾯,若是你们不想封装可以直接在你们相关的vue⽂件⾥⾯引⼊
import G6 from '@antv/g6';
然后封装名称为renderMap的函数,名字可以⾃定义
export function renderMap(data,graph){
const COLLAPSE_ICON = function COLLAPSE_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
];
};
const EXPAND_ICON = function EXPAND_ICON(x, y, r) {
return [
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
['M', x, y - 2 * r + 2],
['L', x, y - 2],
];
};
averseTree(data, (d) => {
d.leftIcon = {
style: {
fill: '#3759B0',
stroke: '#e6fffb',
},
};
return true;
});
options: {
size: [60, 20],
stroke: '#73D13D',
fill: '#fff'
},
draw(cfg, group) {
const styles = ShapeStyle(cfg)
const { labelCfg = {} } = cfg
const keyShape = group.addShape('rect', {        attrs: {
...styles,
x: 0,
y: 0
}
})
/**
* leftIcon 格式如下:
*  {
*    style: ShapeStyle;
*    img: ''
*  }
*/
// console.log('cfg.leftIcon', cfg.leftIcon);
if (cfg.leftIcon) {
const { style, img } = cfg.leftIcon
group.addShape('rect', {
attrs: {
x: 10,
y: 8,
width: 24,
radius: 12,
height: styles.height - 16,
fill: '#8c8c8c',
...style
}
})
group.addShape('text', {
attrs: {
text: cfg.name,
x: 22,
y: 21,
fill: '#ffffff',
fontSize: 12,
fontSize: 12,
textAlign: 'center',
textBaseline: 'middle',
fontWeight: 'bold',
},
name: 'text-shape',
});
group.addShape('image', {
attrs: {
x: 8,
y: 8,
width: 24,
height: 24,
},
name: 'image-shape',
});
}
// 如果不需要动态增加或删除元素,则不需要 add 这两个 marker      group.addShape('marker', {
attrs: {
x: 130,
y: 18,
r: 6,
stroke: '#707070',
cursor: 'pointer',
symbol: EXPAND_ICON
},
name: 'add-item'
})
group.addShape('marker', {
attrs: {
x: 130,
y: 36,
r: 6,
stroke: '#5C5C5C',
cursor: 'pointer',
symbol: COLLAPSE_ICON
},
name: 'remove-item'
})
if (cfg.label) {
group.addShape('text', {
attrs: {
...labelCfg.style,
text: cfg.label,
x: 50,
y: 25,
}
})
}
return keyShape
}
}, 'rect')
draw(cfg, group) {
const startPoint = cfg.startPoint;
const endPoint = dPoint;
const { style } = cfg
const shape = group.addShape('path', {
attrs: {
attrs: {
stroke: style.stroke,
endArrow: dArrow,
path: [
['M', startPoint.x, startPoint.y],
['L', startPoint.x, (startPoint.y + endPoint.y) / 2],
['L', endPoint.x, (startPoint.y + endPoint.y) / 2,],
['L', endPoint.x, endPoint.y],
],
},
});
return shape;
}
});
const width = ElementById('container').scrollWidth;
const height = ElementById('container').scrollHeight || 500;
graph.data(data);朱茵
graph.fitView();
<('node:mouseenter', evt => {
const { item } = evt
graph.setItemState(item, 'hover', true)
})
<('node:mouseleave', evt => {
const { item } = evt
graph.setItemState(item, 'hover', false)
})
}
然后需要在相关的vue⽂件中引⼊这个封装好的公共函数renderMap
import G6 from "@antv/g6";
import { renderMap } from "../../../assets/common/http";
直接呈上完整vue⽂件,⾥⾯有⼏个需要注意的点,⽤注释标注了
<template>
<div>
<div id="container"></div>
</div>
</template>
<script>
import G6 from "@antv/g6";  //注意引⼊
import G6 from "@antv/g6";  //注意引⼊
import { renderMap } from "../../../assets/common/http"; //朱茵引⼊封装的函数export default {
data() {
return {
graph: {}, //定义⼀个graph对象
data: {    //定义⼀个公共数据数组
id: "root",
label: "root",
name: 1,
children: [
{
id: "c1",
label: "c1",
name: 2,
children: [
{
id: "c1-1",
label: "c1-1",
name: 3
},
{
id: "c1-2",
label: "c1-2",
name: 3,
children: [
{
id: "c1-2-1",
label: "c1-2-1",
name: 4
},
{
id: "c1-2-2",
label: "c1-2-2",
name: 4
}
]
}
]
},
{
id: "c2",
label: "c2",
name: 2
},
{
id: "c3",
label: "c3",
name: 2,
children: [
{
id: "c3-1",
label: "c3-1",
name: 3
},
{
id: "c3-2",
label: "c3-2",
name: 3,
children: [
{
id: "c3-2-1",
label: "c3-2-1",