# 基于G6.js封装拓扑图插件
随着业务的迅速发展,以前控制器中使用D3.js
实现的拓扑图功能渐渐地不能满足需求:
- 代码组织混乱,各功能未有序解耦,维护困难。
- 未插件化,不能供多个项目使用。
D3.js
使用svg
来实现,在数据量大时需要生成数量庞大的dom
结构。
因此,拓扑图急需一次大的升级。
# 插件选型
市面上有不少拓扑图插件,例如:
# 1. AntV G6
简介:G6 是一个图可视化引擎。它提供了图的绘制、布局、分析、交互、动画等图可视化的基础能力。 背景:蚂蚁金服 AntV、国产 官网:https://antv.vision/zh 示例:https://github.com/wenyuan/cceditor
- 优点
- 开源免费
- 上手简单,可扩展性强
- 功能丰富,支持各种自定义操作
- 由蚂蚁金服 AntV 团队开发,从维护性和生态圈角度考虑相对有保障
- 支持自动布局(早期借助 d3-force 实现,后期已经被内部支持)
- 缺点
- 有时候文档和版本会脱节(可以理解,问题不大)
- 建议
- 大厂团队开发维护,后期有保障,大小项目都可以使用
- 可以学习里面的一些编程思想和技巧
# 2. D3
只提供画图能力,画什么需要自己实现。
# 3. ECharts
简介:ECharts 关系图。 背景:百度、国产 官网:https://www.echartsjs.com/zh/index.html
- 优点
- 上手非常简单
- 文档齐全
- 缺点
- 扩展性弱(毕竟不是专做图编辑器的,关系图只是 ECharts 中的一项)
- 建议
- 可以用在定制化的需求中,不需要拖拉拽等功能
# 选型总结
除了上面提到的,还有一些国内外个人开发的插件,但普遍存在维护无保障、文档不齐全等问题。
另外D3之前就在用,存在的问题上面也讲过了。
Echarts拓展性不强,无法适应多变的需求。
加上深信服已经有基于G6.js
封装了插件,可以在其基础上快速实现功能,于是最终选定使用G6
进行开发。
# 功能实现
# 目录
└───docs // 文档
└───example // 示例
└───src
│ └───assets // 图片资源
│ └───behavior // 行为方法
│ └───config // 公共配置
│ └───controller // 注册类型
│ └───core // 插件核心代码
│ └───event // 事件
│ └───extends // 扩展G6
│ └───language // 国际化
│ └───layout // 布局
│ └───plugin // 插件
│ └───shapes // 自定义类型
│ └───style // 样式
│ └───utils // 公共方法
│ index.js
# 架构图
# 数据转换
各项目的数据格式肯定是不一致的,插件为了兼容各种数据格式,对外暴露了转换数据的方法,用户可自定义转换数据格式,将数据转成G6
的格式。
# 布局
# 树形交叉布局
项目的树形需求主要有几个难点:
- 需要不同父集的子集间能相互连接(交叉连线)
- 存在不在树结构里的元素
- 存在分支拓扑,即树拓扑中存在子树拓扑
G6
原生支持的树形拓扑十分死板,只能展示单纯的树形结构。
# 实现
本插件通过扩展dagre
布局,并实现展开收起功能,完美实现需求。
# 保持顺序
为了保持同层级节点的排列顺序,自动将每层中最多子节点的节点放在中间(为了美观),其余按数据传入的顺序进行排序。
# 展开收起
展开收起子节点,会自动更新节点的位置,达到类似xmind
的伸缩位置的效果。
# 自定义图形、事件
插件内置了各种图形、事件。
# 连线
扩展了三阶贝塞尔曲线,可根据传入的数据,显示传输速率、繁忙度、连接方式等信息。
# 网络设备
内置了控制器、接入点、盒式交换机、框式交换机等设备类型,用户可直接使用,需要额外自定义的设备类型可通过配置化的方式传入,插件会自动注册成G6
的自定义类型。
内置了多套尺寸的样式,随着缩放比例的变化自动切换显示。
# 事件系统
内置了一系列事件,统一在图实例发送接收,方便外部使用。
# 内置svg
内置了一系列设备图片,可像在vue
中使用svg
组件一样使用。
# 差量更新
针对周期性自动更新数据的场景,提供了差量对比、更新的功能。
# 坐标处理
# 全新
所有节点都没坐标,或者更新时配置了去计算坐标时,会走配置的layout的布局算法去计算位置。
如果感到计算速度缓慢,可以开启webwork
功能进行加速。
# 有新有旧
有坐标的节点使用旧坐标,无坐标的走布局算法。
# 全旧
全部都有坐标,则直接使用旧坐标,不走布局算法,节省性能。
# 文档
一个大型的项目,不能缺少了使用文档。
这里使用VuePress
作为静态网站生成器,可快速实现预览编写的.md
格式文档。
# 国际化
可在初始化拓扑图时,传入语言类型来控制文字显示。
内置了国际化方案,同时可接收使用外部的翻译转换逻辑。
# 开发体验
# mock数据
可配置化的生成指定层级、数量的假数据,方便测试及展示。
# 自定义console
可自定义console打印的样式,等级。
可方便的控制打印时机。
# 打印执行用时
在关键函数调用处,都添加了执行计时,可方便的看出性能瓶颈。
# 拓展G6.js
对G6.js
的原型方法进行拓展、补充。
# behavior
# brush-select
G6
内置的框选操作,是不支持在combo内部去拖动的。
插件通过重写该行为,实现在combo中进行框选。
# drag-canvas
拖动画布的操作。
在大数据量时,拖动画布及其卡顿,这里借鉴了vue
中nextTick
的原理,将更新汇总,一段时间只执行一次,达到优化性能的目的。
# zoom-canvas
滚轮进行缩放时,有时会到不了给定的最大最小缩放值。
插件这里判断达到极值时,直接使用该值,从而解决该bug。
# minimap
G6
有提供两种缩略图,minimap
和imageMinimap
。
区别就是minimap
是根据graph再用canvas画一次,而imageminimap
是将我们自己给的图片显示出来(但是需要自己监听变化并给出图片)。
可想而知,在大量数据的情况下,双倍渲染canvas肯定消耗更大的性能。
本插件通过修改imageminimap
,实现了自动监听graph变化,同时生成图片并渲染到缩略图上。
# 打包
使用webpack5
进行打包
# 开发环境
已内置两套开发环境(普通html和vue)。
通过npm run dev
即可启动开发环境,自动监听样例代码和拓扑图插件代码变化,热更新页面。
# 生产环境
提供umd
,esm
两种格式,方便使用。
# 新手指引
封装了新手指引功能,可让用户快速上手功能。
# 插件系统
所有插件均配置化,可传入配置进行启用、重写。
# 数据工具栏
# 刷新
自定义数据刷新时间。
# 选取方式
切换单选和框选模式。
# 对齐
类似于思维导图中的对齐功能,可对选中的节点进行水平、垂直、左、右等等对齐方式。
# 撤销
即上一步,支持无限步。
# 导出
将拓扑图以图片形式导出。
# 大数据量优化
插件针对大数据场景做了优化,G6
直出的图片在大数据时会导出失败(浏览器对canvas的最大尺寸的限制),所以我们对数据采用分批导出。
# 清晰度
G6
直出的图片清晰度不是很好,插件通过动态改变像素比来放大尺寸,从而提高清晰度。
# 显示设置
节点上的某些元素可通过配置去控制显示。
# 快速展开收起
可对节点快速的全部展开、全部收起、按层展开、按层收起。
# 视图
可保存多份坐标、显示、缩放等展示信息的视图,让用户可以快速切换到想看的设备处。
# 搜索
通过关键字搜索并高亮相关数据。
# 可配置
可配置需要搜索的字段
# 高亮
对搜索到的节点进行高亮显示。
同时,如果节点是被收起的状态,会自动打开其父级combo。
# 视图工具栏
对图进行放大、缩小、自适应缩放、缩略图、全屏等操作。
# tooltip
鼠标悬浮提示
# 背景
可配置画布的背景颜色、图片等。
# 右键菜单
可配置右键元素时显示菜单。
# 命令系统
操作动作都写入命令系统,在dom
元素上添加命令名即可实现动作。
并可配置命令快捷键。
# 图例
设备图片示例,可动态传入数据进行显示。
# 自动注册类型
图例自然包含所有的类型,所以当开启图例时,会自动根据配置项去注册节点类型。
# 筛选
可通过点击类型去筛选数据。
可与搜索功能组合进行筛选。
# loading
画布未渲染完成时,可配置显示loading动画。
# 对齐辅助线
G6
的snapLine
插件只有显示辅助线的功能。
插件对其进行扩展,添加了移动到附近节点时会进行吸附对齐的功能。
# 扩展性
插件、设备样式等均已配置化,可传入数据进行重写,十分方便的完成换肤、拓展等自定义需求。
# 兼容性
现代浏览器完美兼容。
ie10环境,内部使用polyfill兼容。