Vue绘制业务流程图(附源码)
先给大家看一下效果图:图中每个节点的字体颜色,边框颜色,连接线,图例说明等都是可以进行动态配置的.项目源码在文章末尾。目录基本构成数据格式节点Nodesshape可选参数:animation可选参数:边Edges群组groups图例guids状态status项目实战前置条件导入工具类页面创建流程图容器绘制图形本...
·
先给大家看一下效果图:
图中每个节点的字体颜色,边框颜色,连接线,图例说明等都是可以进行动态配置的.
项目源码在文章末尾。
目录
本项目中使用绘制流程图的G6Utils.min.js是基于G6进行封装的。
关于G6的使用大家可以自行进入官网查看:G6官网
那么我们开始实战:
基本构成
数据格式
首先我们先简单了解一下使用该工具类绘制流程的数据格式:
元素 | 说明 |
Nodes | 节点 |
Edges | 边 |
Guides | 图例说明 |
Groups | 群组 |
Status | 状态说明 |
//基本构成
{
nodes:[],
edges:[],
groups: [],
guides: [],
status:[]
}
节点Nodes
nodes:[
{
id: 'chuzhi', //节点ID,唯一
shape:'node', //节点形状
raduis:5, //半径范围 若shape:'root'则有该属性,不填默认为5px,可选参数
name:'处置', //节点内文章描述,可选参数
status:'timeout', //节点状态,对应status中的配置,可选参数
animation:'flicker', //节点动画,可选参数
parent:'group1', //节点所属群组,可选参数
x: 400, //节点X坐标
y: 500, //节点Y坐标
},
...
]
shape可选参数:
- root 根节点
- node 处置节点
- 更多图形节点封装后续继续更新
animation可选参数:
- flicker 节点闪烁动画
- wave 节点背景波浪动画
注:
- status数组与基本构成中的status配置内容一样,详情可查看status说明;
- radius只在节点形状为root时有效,系统默认radius=5,属性效果同css样式中的border-raduis
- 注有可选参数则,该参数可选,其余为必选参数
边Edges
edges:[
{
id: 'edge1', //群组ID,唯一
source:'shenhe3', //边起始点节点ID
target: 'jianyi', //边结束点节点ID
label:'不通过', //边上描述,可选参数
controlPoints:[ //控制点(当边需要弯折时必须加入的参数,指边必须经过的点),可选参数
{
x:230,
y:150
},
{
x:130,
y:150
}
]
},
...
]
群组groups
groups:[
{
id:'group4', //群组ID,唯一
shape:'lane', //取值形状
label: '泳道一', //群组名称
},
...
]
图例guids
guides:[
{
id:'legend', //图例ID,唯一
shape:'legend', //图例形状
label:[{shape:'root',name:'开始/结束'},{shape:'node',name:'处置流程'}] //图例节点描述,对应nodes中所使用的节点
},
...
]
注:
- 图例中label为数组,可配置需要展示的图例节点,及说明文字
状态status
status:[
{
title:'done', //状态标题,对应nodes中的status
color:'green', //颜色,对应node节点的字体,边框颜色
name:'已完成' //状态名称
},
...
]
项目实战
前置条件
引入G6:
cnpm install @antv/g6 --save
导入工具类
在vue页面中使用G6Utils
import {init,update} from './utils/g6Utils.min.js'; //导入路径可变
注:
- init():图形初始化函数
- update:动态改变图形函数
页面创建流程图容器
<div id="mountNode">
</div>
绘制图形
<script>
import {init,update} from './utils/g6Utils.min.js';
export default {
name: 'App',
data () {
return {}
},
methods:{
toUpdate(){
...
}
},
mounted(){
const data = {
nodes: [
{
shape:'root',
id: 'begin',
name:'开始',
radius:15,
x: 400,
y: 100,
parent:'group1',
},
{
shape:'node',
id: 'shenhe1',
name:'审核',
status:'done',
x: 300,
y: 100,
parent:'group2',
},
{
shape:'node',
id: 'shenhe2',
name:'审核',
status:'done',
x: 200,
y: 100,
parent:'group3',
},
{
shape:'node',
id: 'qianshou1',
name:'签收',
status:'done',
x: 100,
y: 100,
parent:'group4',
},
{
shape:'node',
id: 'jianyi',
name:'建议',
status:'done',
x: 100,
y: 200,
parent:'group4',
},
{
shape:'node',
id: 'shenhe3',
name:'审核',
status:'done',
x: 200,
y: 200,
parent:'group3',
},
{
shape:'node',
id: 'xiafa1',
name:'下发',
status:'done',
x: 200,
y: 300,
parent:'group3',
},
{
shape:'node',
id: 'qianshou2',
name:'签收',
status:'done',
x: 300,
y: 300,
parent:'group2',
},
{
shape:'node',
id: 'xiafa2',
name:'下发',
status:'done',
x: 300,
y: 400,
parent:'group2',
},
{
shape:'node',
id: 'qianshou3',
name:'签收',
status:'done',
x: 400,
y: 400,
parent:'group1',
},
{
id: 'chuzhi',
shape:'node',
name:'处置',
status:'timeout',
animation:'flicker',
parent:'group1',
x: 400,
y: 500,
},
{
shape:'node',
id: 'shangbao',
name:'上报',
status:'ing',
animation:'wave',
x: 400,
y: 600,
parent:'group1',
},
{
shape:'node',
id: 'shenghe4',
name:'审核',
status:'',
x: 200,
y: 600,
parent:'group3',
},
{
shape:'root',
id: 'end',
name:'结束',
radius:15,
x: 100,
y: 600,
parent:'group4',
},
],
edges: [
{
id: 'edge1',
source:'begin',
target: 'shenhe1',
},
{
id: 'edge2',
source:'shenhe1',
target: 'shenhe2',
},
{
id: 'edge3',
source:'shenhe2',
target: 'qianshou1',
},
{
id: 'edge4',
source:'qianshou1',
target: 'jianyi',
},
{
id: 'edge6',
source:'shenhe3',
target: 'xiafa1',
},
{
id: 'edge66',
source:'shenhe3',
target: 'jianyi',
label:'不通过',
controlPoints:[
{
x:230,
y:150
},
{
x:130,
y:150
}
]
},
{
id: 'edge7',
source:'xiafa1',
target: 'qianshou2',
},
{
id: 'edge8',
source:'qianshou2',
target: 'xiafa2',
},
{
id: 'edge9',
source:'xiafa2',
target: 'qianshou3',
},
{
id: 'edge10',
source:'qianshou3',
target: 'chuzhi',
},
{
id: 'edge11',
source:'chuzhi',
target: 'shangbao',
label:'完成'
},
{
id: 'edge12',
source:'shangbao',
target: 'shenghe4',
},
{
id: 'edge13',
source:'shenghe4',
target: 'end',
},
],
groups:[
{
shape:'lane',
id:'group4',
label: '泳道一',
},
{
shape:'lane',
id:'group3',
label: '泳道二',
},
{
shape:'lane',
id:'group2',
label: '泳道三',
},
{
shape:'lane',
id:'group1',
label: '泳道四',
}
],
guides:[
{
id:'legend',
shape:'legend',
label:[{shape:'root',name:'开始/结束'},{shape:'node',name:'处置流程'}]
},
{
id:'states',
shape:'states',
},
],
status:[
{
title:'done',
color:'green',
name:'已完成'
},
{
title:'timeout',
color:'red',
name:'已超时'
},
{
title:'ing',
color:'#EE8262',
name:'进行中'
},
{
title:'default',
color:'gray',
name:'未开始'
}
]
};
init('mountNode',500,500,data);
}
}
注:
- init(容器ID,画布宽度,画布高度,数据源)
- 数据源设置参照上一节说明
- 支持图形拖拽,放缩
- 图形自动适应画布大小放缩,默认展示全部图形
运行项目后我们将看到如下图形:
下面我们再进行update动态修改数据源重新绘制图形:
在页面添加一个功能按钮,用于触发update函数:
<button @click="toUpdate">切换数据</button>
添加函数实现:
toUpdate(){
const data = {
nodes: [
{
shape:'root',
id: 'begin',
name:'开始',
x: 100,
y: 100,
},
{
shape:'node',
id: 'shenhe1',
name:'审核',
status:'done',
x: 200,
y: 200,
},
{
shape:'node',
id: 'xiafa',
name:'下发',
status:'done',
x: 200,
y: 300,
},
{
shape:'node',
id: 'qianshou',
name:'签收',
status:'done',
x: 300,
y: 300,
},
{
shape:'node',
id: 'chuzhi',
name:'处置',
status:'timeout',
x: 300,
y: 400,
},
{
shape:'node',
id: 'shangbao',
name:'上报',
status:'',
x: 300,
y: 500,
},
{
shape:'node',
id: 'shenhe2',
name:'审核',
status:'',
x: 200,
y: 500,
},
{
shape:'root',
id: 'end',
name:'结束',
status:'',
x: 100,
y: 500,
},
],
edges: [
{
id: 'edge1',
source:'begin',
target: 'shenhe1',
controlPoints: [
{
x: 230,
y: 115
}
],
},
{
id: 'edge2',
source:'shenhe1',
target: 'xiafa',
},
{
id: 'edge3',
source:'xiafa',
target: 'qianshou',
},
{
id: 'edge4',
source:'qianshou',
target: 'chuzhi',
},
{
id: 'edge5',
source:'chuzhi',
target: 'shangbao',
label:'完成',
},
{
id: 'edge6',
source:'shangbao',
target: 'shenhe2',
},
{
id: 'edge7',
source:'shenhe2',
target: 'end',
},
{
id: 'edge8',
source:'shenhe1',
target: 'begin',
label:'不通过',
controlPoints: [
{
x: 130,
y: 215
}
],
},
],
groups:[
],
guides:[
{
id:'states',
shape:'states',
},
],
status:[
{
title:'default',
color:'gray',
name:'未开始'
}
]
};
update(data);
}
当我们点击更新按钮时,流程图将会动态刷新:
注:
- 在更新函数中我去掉了很多数据源的可选参数,以便大家对比init()函数使用时配置的数据源
至此大功告成!
源码地址:码云地址
项目中的G6Utils.min.js大家自行在源码中拉取,谢谢。
欢迎大家评论,使用中有什么问题也可提出。
更多推荐
已为社区贡献6条内容
所有评论(0)