vue+antvg6+element-ui完整流程图
最近⼀直在研究流程图相关的技术,⼀次在逛GitHub时发现了⼀个技术栈为vue+g6+element-ui的项⽬,基础功能完好,如node与edge的托拉拽,主界⾯如下:
GitHub链接为:
线上访问地址为:
g6官⽅API⽂档:
但由于作者没有写代码的说明⽂档,本⽂仅仅只是我本⼈对读该源码的⼀些理解,如有不同理解还希望各位朋友指出订正。
⼀、本地运⾏
⾸先从上⾯的GitHub⽹址下载该项⽬,下载该项⽬需要的依赖包。这⾥很多⼈下载完依赖包之后发现启动报错⽆法运⾏,需要注意的是这⾥不要使⽤cnpm install,⼀定要使⽤npm install!!!具体为什么cnpm不⾏,我也不知道。
⼆、给连线加上⽂字[本⼈⾃⼰增加]
1、修改src/components/DetailPanel/index.vue
<template>
<div class="detailpannel">
<div>
<div v-if="status=='node-selected'" class="pannel" id="node_detailpannel">
<div class="pannel-title">模型详情</div>
<div class="block-container">
<el-row :gutter="10">
<el-col :span="8">名称</el-col>
<el-col :span="16">
<el-input v-model="node.label" @change="handleChangeName"/>
</el-col>
<el-col :span="8">任意属性</el-col>
<el-col :span="16">
<el-input v-model=""/>
</el-col>
</el-row>
</div>
</div>
<div v-if="status==='canvas-selected'" class="pannel" id="canvas_detailpannel">
<div class="pannel-title">画布</div>
<div class="block-container">
<el-checkbox v-model="showGrid" @change="changeGridState">⽹格对齐</el-checkbox>
</div>
</div>
   <!--我添加的-->
<div v-if="status === 'edge-selected'" id="edge_detailpannel" class="pannel">
<div class="pannel-title">连线</div>
<div class="block-container">
<el-col :span="8">内容</el-col>
<el-col :span="16">
<el-input v-model="edge.label" @change="handleChange"/>
</el-col>
<el-col :span="8">⽂字颜⾊</el-col>
<el-col :span="16">
<el-color-picker v-model="textColor" @change="handleChangeColor"/>
</el-col>
</div>
</div>
<!-- <div v-if="status==='group-selected'" class="pannel" id="node_detailpannel">        <div class="pannel-title">组详情</div>
<div class="block-container">
<div class="p">
名称:
<el-input v-model="name" />
</div>
<div class="p">
任意属性:
<el-input v-model="color" />
</div>
</div>
</div>
-->
</div>
</div>
</template>
<script>
import eventBus from "@/utils/eventBus";
import Grid from "@antv/g6/build/grid";
export default {
data() {
return {
status: "canvas-selected",
showGrid: false,
page: {},
graph: {},
item: {},
node: {},
    //【我添加的】
edge:{},
grid: null,
/
/【我添加的】
textColor: 'rgba(19, 206, 102, 0.8)'
};
},
created() {
this.init();
this.bindEvent();
},
methods: {
init() {},
bindEvent() {
let self = this;
eventBus.$on("afterAddPage", page => {
self.page = page;
eventBus.$on("nodeselectchange", item => {
if (item.select === true && Type() === "node") {
self.status = "node-selected";
self.item = item.target;
}
      //【我添加的】
      else if (item.select === true && Type() === "edge") {
self.status = "edge-selected";
self.item = item.target;
self.edge = Model();
}
      else {
self.status = "canvas-selected";
self.item = null;
}
});
});
},
handleChangeName(e) {
const model = {
label: e
};
},
changeGridState(value) {
if (value) {
} else {
}
},
  //【我添加的】
vuejs流程图插件
handleChange(e) {
const model = {
label: e
};
console.log(model)
},
handleChangeColor(e) {
const model = {
textColor: e
};
}
}
};
</script>
<style scoped>
.detailpannel {
height: 100%;
position: absolute;
right: 0px;
z-index: 2;
background: #f7f9fb;
width: 200px;
border-left: 1px solid #e6e9ed;
}
.detailpannel .block-container {
padding: 16px 8px;
}
.block-container .el-col {
height: 28px;
display: flex;
align-items: center;
margin-bottom: 10px;
}
.pannel-title {
height: 32px;
border-top: 1px solid #dce3e8;
border-bottom: 1px solid #dce3e8;
background: #ebeef2;
color: #000;
line-height: 28px;
padding-left: 12px;
}
</style>
2、修改src/components/Flow/customEdge.js import G6 from "@antv/g6/build/g6";
import { uniqueId } from '@/utils'
const MIN_ARROW_SIZE = 3
const customEdge = {
init() {
const dashArray = [
[0, 1],
[0, 2],
[1, 2],
[0, 1, 1, 2],
[0, 2, 1, 2],
[1, 2, 1, 2],
[2, 2, 1, 2],
[3, 2, 1, 2],
[4, 2, 1, 2]
]
;
const lineDash = [4,2,1,2];
const interval = 9;
draw(cfg, group) {
let sourceNode, targetNode, start, end
if (typeof (cfg.souxrce) === 'string') {
cfg.source = cfg.sourceNode
}
if(!cfg.start){
cfg.start={
x:0,
y:17
}
}
if(!d){
x:0,
y:-17
}
}
if (!cfg.source.x) {
sourceNode = Model()
start = { x: sourceNode.x + cfg.start.x, y: sourceNode.y + cfg.start.y }
} else {
start = cfg.source
}
if (typeof (cfg.target) === 'string') {
cfg.target = cfg.targetNode
}
if (!cfg.target.x) {
targetNode = Model()
end = { x: targetNode.x + d.x, y: targetNode.y +  d.y }
} else {
end = cfg.target
}
let path = []
let hgap = Math.abs(end.x - start.x)
if (end.x > start.x) {
path = [
['M', start.x, start.y],
[
'C',
start.x,
start.y + hgap / (hgap / 50),
end.x,
end.y - hgap / (hgap / 50),
end.x,
end.y - 4
],
[
'L',
end.x,
end.y
]
]
} else {
path = [
['M', start.x, start.y],
[
'C',
start.x,
start.y + hgap / (hgap / 50),
end.x,
end.y - hgap / (hgap / 50),
end.x,
end.y - 4
],
[
'L',
end.x,
end.y
]
]
}
let lineWidth = 1;
lineWidth = lineWidth > MIN_ARROW_SIZE ? lineWidth : MIN_ARROW_SIZE;        const width = lineWidth * 10 / 3;
const halfHeight = lineWidth * 4 / 3;
const radius = lineWidth * 4;
const endArrowPath = [
['M', -width, halfHeight],
['L', 0, 0],
['L', -width, -halfHeight],
['A', radius, radius, 0, 0, 1, -width, halfHeight],
['Z']
];
const keyShape = group.addShape('path', {
attrs: {
id: 'edge' + uniqueId(),
path: path,
stroke: '#b8c3ce',
lineAppendWidth: 10,
endArrow: {
path: endArrowPath,
}
}
});
     //此处是我修改的,增加连线的样式即线上⽂本
if (cfg.label) {
group.addShape('text', {
attrs: {
id: 'edgeText' + uniqueId(),
x: end.x - (end.x - start.x) / 2,
y: end.y - (end.y - start.y) / 2,
text: cfg.label,
fill: Color ? Color : '#000000'
}
})
}
return keyShape
},
afterDraw(cfg, group) {
if (Model().isDoingStart && Model().isDoingEnd) {          const shape = ('children')[0];
const length = TotalLength(); // G 增加了 totalLength 的接⼝
let totalArray = [];
for (var i = 0; i < length; i += interval) {
totalArray = at(lineDash);
}
let index = 0;
shape.animate({
onFrame() {
const cfg = {
lineDash: dashArray[index].concat(totalArray)
};
index = (index + 1) % interval;
return cfg;
},
repeat: true
}, 3000);
}
},
setState(name, value, item) {
const group = Container();
const shape = ("children")[0];
const selectStyles = () => {
shape.attr("stroke", "#6ab7ff");
};
const unSelectStyles = () => {
shape.attr("stroke", "#b8c3ce");
};
switch (name) {
case "selected":
case "hover":
if (value) {
selectStyles()
} else {
unSelectStyles()
}
break;
}
}
});
draw(cfg, group) {
let sourceNode, targetNode, start, end
if (!cfg.source.x) {
sourceNode = Model()
start = { x: sourceNode.x + cfg.start.x, y: sourceNode.y + cfg.start.y }
} else {
start = cfg.source
}
if (!cfg.target.x) {
targetNode = Model()
end = { x: targetNode.x + d.x, y: targetNode.y + d.y }
} else {
end = cfg.target
}
let path = []
path = [
['M', start.x, start.y],