关于在项目中,将流程图G6替换为X6

lxf2023-03-19 20:33:01

任务

来到公司的第一个任务就是将公司项目中原来使用的流程图组件GGeditor替换为X6,公司前端的技术栈是react+antd+umi。

技术调研

曾考虑过xflow,但是因为公司依赖的antd版本为3.x,xflow的依赖的antd在4.x以上,最主要的是Form组件,会报错。为了尽量减少未知因素,还是选择使用x6自己封装一个流程图组件。

思路

关于在项目中,将流程图G6替换为X6

管理类

创建一个manager类,用来管理一些操作,创建一个CommandManager,其实就是设计模式中的命令模式,管理所有的命令,如缩放、复制、粘贴等等功能。

封装组件

最外层的GantFlow组件,用于创建manager实例,利用Context+hook往子组件传递manager实例

ToolBar组件,用于展示工具栏。安装react的思路,应该是要拿到当前点击的节点或边,以判断当前按钮是否可以操作的,但是因为所有的操作已封装为命令,在ToolBar组件中,其实是不需要知道用户点击的是哪个节点或边的,所以使用设计模式中的发布订阅模式做解耦,这里x6已经内置了

在x6的节点或边发生变化时,触发toolBar:forceUpdate,在ToolBar组件订阅toolBar:forceUpdate时间,强制根据ToolBar组件渲染

Stencil组件,Stencil本身其实是x6本身提供的一个展示可被拖拽的一系列内置节点的面板组件,但是不太适合当前项目,最终还是自己使用X6的DnD封装了一个被拖拽节点面板

Flow组件,用于创建x6的Graph实例,会调用GantFlow中Context传递的回调函数,将graph保存到state中,这是为了能重新渲染组件,另外也会保存到manager实例中

ContextMenu,右键菜单组件,这个组件用到了ahooks的useClickAway,可以传入一个dom的ref,可以响应传入的dom以外所有的dom事件

MiniApp小地图组件,目前X6好像只能在创建Graph实例的时候,传入miniapp属性来创建,不太好分离,所以没有用到,真实的miniapp是在Flow组件中和Graph实例是一起创建的

这一点可以参考XFlow的实现,将Graph的options拆分为在多个组件中定义,通过内置组件拿到所有的配置,再new Graph,我犯懒了

最后就是对之前项目中流程图数据和后台所需数据之间的转换了,其他的没什么难度

注意点

在G6中,对于节点的坐标计算是从中心点开始的,而X6是从左上角开始计算的。

总结

没有遇到太难的东西,需要注意的是嵌套组件中useEffect之间的执行顺序,会先执行子组件的useEffect。在之前的流程图中,G6遇到了拖拽、缩放卡顿的情况,节点并不多,按理来讲,是不会出现如此严重的卡顿现象的。在更换X6之后,流畅了许多。