mxgraph介绍
github地址:https://github.com/jgraph/mxg...,源码地址:https://github.com/jgraph/mxg...
效果可以参考 [https://app.diagrams.net/],实现类似 visio 画图的效果,流程图是它主要的一个用途
mxgraph 是一个绘图框架,除了javascript版本,还有java版本,c#版本等
我们使用的是javascript版本用于web端,mxgraph 只实现了画图最核心的功能, 官方内置了很多简单的demo,也有grapheditor等复杂的带快捷键、工具栏,菜单功能的demo
mxgraph 能兼容 ie8 等比较老的浏览器,因此代码中也有很多处理兼容性的代码,在主流浏览器中使用 svg 实现绘图,但代码中使用了 canvas 作为变量,可能容易误以为是 canvas 来实现的。
根据业务需求,我们需要进行大量的自定义扩展(oop方式),所以需要进行大量的源码阅读,理解其实现方式,并扩展实现自己的功能。
网上关于mxgraph的介绍可参考: [mxGraph 入门实例教程]: https://segmentfault.com/a/11...
官方文档: https://jgraph.github.io/mxgr...
官方api说明:https://jgraph.github.io/mxgr...
mxgraph源码目录结构
1. view
负责图形的渲染,内部逻辑控制,对外提供api
- 核心类 mxGraph,使用了调停者模式,通过扩展这个类,可以自定义很多功能, 我们外部使用的很多 api 都在这个文件内
- mxGraphView: 元件重新渲染逻辑,计算元件位置、背景网格等
- mxCell:保存元件的位置信息(geometry)
- mxCellState: 根据mxCell数据,保存元件真实位置,mxGraphView每次重新渲染会重新生成
- mxCellRenderer: 根据mxCellState信息渲染出svg图形、label、control
- mxEdgeStyle: 连接线的形状,支持直线、折线等其他形状,目前使用的是 elbowEdgeStyle
- mxPerimeter: 不同形状的边缘位置计算方法
2. util
主要工具类实现:日志打印、底层画图api、工具栏、撤销、请求、拖拽
mxPoint、mxRectangle等基本数据类型
mxEventSource,mxEventObject 实现发布订阅模式
3. model
核心模块mxGraphModel,所有对mxCell的操作都都由这个模块负责,改变mxCell的geometry、父元素、value、style等,撤销功能主要由mxUndoManager、mxUndoableEdit、和这个目录下的文件实现
4. handle
文件夹内包含了处理鼠标事件的类,比如鼠标选中、图形放大、缩小、鼠标拖动选中多个图形效果等
5. shape
文件夹下包含了常见的形状、正方形、圆形、椭圆、多边形、还可以自定义各种形状、基类 mxShape
mxSwimlane 是流程图中比较常见的一种形状:泳道,目前没有使用到,代码中有出现相关逻辑,需要注意下
6. layout
包含了处理图形展示的类,各种布局方式,树形布局、圆形布局等,暂时不需要了解
7. io
内部的序列化实现,采用xml形式,目前已实现了json格式的序列化方式,暂不需要关心这部分
8. editor
简单快捷键、菜单支持,这部分功能将自己实现,暂不需要关心这部分
mxgraph架构及运行流程
- mxGraph: 启动模块,负责关联内部其他模块,实现整体功能,控制画布的api都在这个模块
- mxGraphView: 计算元件位置,调用mxCellRenderer渲染元件,控制整体渲染逻辑
- mxGraphModel:处理mxCell属性,元件父子关系,实现撤销功能等,所有对mxCell的修改操作都由这个模块完成
- mxCell: 代表一个图形元件,可以是图形,也可以是边,vertex代表元件,edge代表边
- mxCellState: 根据mxCell中的位置,计算出的真实位置保存在这个模块
- mxConnectionHandler: 负责2个元件之前的连接线,自带的鼠标hover连接点效果
- mxGraphHandler: 元件选中效果
- mxVertexHandler: 元件resize效果
- mxRubberband: 鼠标按住左键,批量选中效果
- mxPanningHandler: 鼠标按住右键拖动画布效果
- mxEdgeHandler:连接线移动,改变线段位置
- mxCellMarker: 元件高亮效果
- mxPerimeter: 计算元件的边缘,用来计算连接线的起始点位置和终点位置
- mxGeometry: 坐标、宽度、高度,用于mxCell,relative属性表示相对于父容器布局,区间为0-1,[0,0]代表父容器左上角,[1,1]代表父容器右下角
- mxGuide:元件和其他元件出现水平或垂直对齐时,将出现对齐线段
- mxConstraintHandler: 框架内置的元件连接点,目前没有使用这个功能,不满足需求
- mxUndoManager:配合mxGraphModel、mxUndoableEdit实现撤销功能
其中很多模块都继承了mxEventSource,以实现发布订阅模式,内部也非常多的使用了这个模式。
比如mxGraphView监听鼠标事件,然后通知所有的handler处理这些事件,以实现对应的交互效果。
每次添加元件、删除元件、撤销操作、移动,都会触发对应的事件,外部只需要监听对应模块的对应事件,就可以做一些特殊判断等。
主要流程:
- mxGraph初始化,生成内部实例mxGraphView、mxGraphModel、各种需要的handler等
- mxGraph调用mxGraphView初始化dom容器,mxGraphView绑定鼠标点击事件,并生成背景网格
- 触发外部事件:
3.1 外部添加、删除元件,调用mxGraph.importCells、removeCells等方法,触发mxGraphModel修改mxCell属性,然后通知mxGraphView重新渲染整个画布,重新计算mxCellState,调用mxCellRenderer渲染单个元件
3.2 鼠标选中等事件,mxGraphView监听鼠标事件,通知对应的handler模块,handler模块调用mxGraph模块,mxGraph通知mxGraphModel修改mxCell属性,重新渲染
撤销功能实现原理:
- mxGraphModel有2个使用频率很高的api,beginUpdate和endUpdate,各个demo中都使用了这2个api,可以嵌套使用,用来记录一次操作,以支持撤销。
- 由于mxCell保存了画布所有元件,每次新增元件、移动位置操作都将通过mxGraphModel生成一个mxUndoableEdit对象,里面维护了多个修改操作,由各种Change组成,
model文件夹下的各个Change模块是实际执行撤销操作的,内部维护了previous属性,用来进行撤销操作。
mxgraph 常用函数、属性、style属性
mxGraph
代表一个画布实例,可以对画布放大、缩小、移动、撤销、
使用到的方法介绍:- insertVertex: 插入元件
- insertEdge: 插入连接线
- setPanning:支持按住鼠标右键移动
- groupCells:将元件封装成一个新的元件
- cellsAdded:当新的元件添加到画布时触发
- translateCell:移动指定元件
- resizeCell: 缩放元件
- getBoundingBoxFromGeometry:获取指定元件组成的范围大小
- center: 将画布位置居中显示
- setCellStyles: 给元件设置新的样式,改变元件颜色,宽高等
- zoomIn: 放大画布
- zoomOut: 缩小画布
mxCellRenderer
- redrawLabel: 控制元件的label是否显示
- isShapeEvent: 控制是否响应元件的事件
- redraw: 重新渲染单个元件
mxConnectionHandler
- connect:将2个元件连接在一起
mxGraphView
- validate:重新渲染画布
- validateCellState: 重新计算元件的真实宽高
- getPerimeterPoint: 计算连接点的起始点、终点位置
mxGraphModel(这个模块的函数主要由mxGraph调用)
- cloneCells: clone元件
- remove: 删除元件
- add: 添加元件
- setVisible: 设置是否可见
- beginUpdate: 开始一个事物(撤销功能)
- endUpdate: 结束一个事物(撤销功能)
mxCellMarker(引用mxCellHighlight实现高亮效果)
- process: 处理鼠标事件,判断是否高亮元件
- intersects: 判断鼠标是否在元件的中心
mxCell(代表一个图形,包括元件和连接线)
- value: 元件的label值
- style: 当前图形的样式
- vertex: 是否是元件
- edge: 是否是连接线
- children: 列表,当前图形的子图形
元件style属性列表,不同元件会有自己的私有属性,下面是通用的一些属性
- width 元件宽度
- height 元件高度
- shape 当前元件的形状
- fillColor 元件填充颜色
- strokeColor 元件图形颜色
- align label对齐方式
- opacity 透明度
- flipH 水平翻转
- rotation 选择角度
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。