# 基于X6.js
封装流程图
# 需求分析
支持自定义节点、边(支持通过前端框架进行自定义)
支持配置边的折线
支持布局算法
支持通过滚动条拖动画布
事件系统
缩放、导出等
支持
Echarts
渲染图表
# 插件选型
# G6.js
# 优点
丰富的插件系统及自定义效果,支持自动布局。
# 缺点
该插件定位更趋向于数据的展示,在流程图这个方向上不够专业。
且不支持通过前端框架自定义节点,只支持通过G2.js
渲染图表。
# logicFlow
相比之下该插件功能就比较单薄。
不支持自动布局
不支持框架渲染
自带插件少
# x6.js
# 优点
专门做流程图的,有很多专业的功能。
丰富的插件系统
支持通过前端框架进行渲染
支持使用Echarts
渲染图表
性能测试1000+节点无卡顿
# 缺点
无内置布局算法,需手动实现。
最终决定使用X6.js
来实现流程图。
# 项目架构
# 目录
└───demo // 示例
└───docs // 文档
└───src
│ └───event // 事件
│ └───hooks // 钩子函数
│ └───layout // 布局
│ └───method // 方法函数
│ └───shape // 自定义元素
│ const.ts // 常量
│ types.ts // 类型定义
│ useFlow.ts // 使用入口
# event
由于x6.js
已做好完善的事件系统,使用者通过:
graph.on('event', () => {});
graph.emit('event', () => {});
即可控制事件。
此处只针对edge
的hover效果进行了处理。
# hooks
初始化流程图的主要地方:
配置初始化、
数据初始化、
布局、
混入方法、
模拟数据、
使用插件
等等功能。
# layout
由于x6.js
无内置布局算法,所以这里自己封装了一套。
目前默认使用dagre
算法进行布局,用户可配置其属性,已有布局位置时可手动关闭自动布局。
# method
对graph
方法的补充
挂在其实例上,可直接调用。
# shape
已内置了部分节点、边、label
支持使用者在外部自定义。
# mock
为了测试性能,支持了模拟数据功能 。
可手动配置数量及层级去模拟出想要的数据。
# 技术难点
# 布局算法
如果有多个分支且数量不对等时,dagre
算法会靠下对齐,不符合设计。
这里通过查找出分支中x最小的坐标,进行手动对齐。
# 交叉连线
单个节点存在多连线、跨级连线的场景时,默认的线的路由的走向不理想。
这里手动计算出线的转折点,进行渲染。
# label位置
x6.js
对label的位置只支持配置百分比及绝对位置,无法根据节点类型进行区分。
这里通过分析节点类型,自动更换边类型,达到控制label位置的需求。
# label渲染
官方文档只给出了react.js
的案例,分析案例,发现原理是通过svg先渲染出容器,然后通过react
去挂载自定义内容到该容器中。
这种效果通过vue
也能实现。
在默认配置中增加onEdgeLabelRendered
方法,在渲染出容器后,通过vue
的h
、render
函数实现将vue
组件挂载到容器上。
# 点击事件透传
由于X6
在node_modules\@antv\x6\src\graph\view.ts
中直接监听了各种事件,导致在vue自定义节点中,会同时触发收起和点击两个事件。
通过查阅源码,发现有暴露guard
函数来控制事件冒泡。
通过在初始化Graph时传入guard
函数,迭代判断父节点的类名是否包含指定的需要停止冒泡的类名,从而解决同时触发点击事件的效果。