2

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处理这些事件,以实现对应的交互效果。
每次添加元件、删除元件、撤销操作、移动,都会触发对应的事件,外部只需要监听对应模块的对应事件,就可以做一些特殊判断等。

主要流程:

  1. mxGraph初始化,生成内部实例mxGraphView、mxGraphModel、各种需要的handler等
  2. mxGraph调用mxGraphView初始化dom容器,mxGraphView绑定鼠标点击事件,并生成背景网格
  3. 触发外部事件:
    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属性

  1. mxGraph
    代表一个画布实例,可以对画布放大、缩小、移动、撤销、
    使用到的方法介绍:

    • insertVertex: 插入元件
    • insertEdge: 插入连接线
    • setPanning:支持按住鼠标右键移动
    • groupCells:将元件封装成一个新的元件
    • cellsAdded:当新的元件添加到画布时触发
    • translateCell:移动指定元件
    • resizeCell: 缩放元件
    • getBoundingBoxFromGeometry:获取指定元件组成的范围大小
    • center: 将画布位置居中显示
    • setCellStyles: 给元件设置新的样式,改变元件颜色,宽高等
    • zoomIn: 放大画布
    • zoomOut: 缩小画布
  2. mxCellRenderer

    • redrawLabel: 控制元件的label是否显示
    • isShapeEvent: 控制是否响应元件的事件
    • redraw: 重新渲染单个元件
  3. mxConnectionHandler

    • connect:将2个元件连接在一起
  4. mxGraphView

    • validate:重新渲染画布
    • validateCellState: 重新计算元件的真实宽高
    • getPerimeterPoint: 计算连接点的起始点、终点位置
  5. mxGraphModel(这个模块的函数主要由mxGraph调用)

    • cloneCells: clone元件
    • remove: 删除元件
    • add: 添加元件
    • setVisible: 设置是否可见
    • beginUpdate: 开始一个事物(撤销功能)
    • endUpdate: 结束一个事物(撤销功能)
  6. mxCellMarker(引用mxCellHighlight实现高亮效果)

    • process: 处理鼠标事件,判断是否高亮元件
    • intersects: 判断鼠标是否在元件的中心
  7. mxCell(代表一个图形,包括元件和连接线)

    • value: 元件的label值
    • style: 当前图形的样式
    • vertex: 是否是元件
    • edge: 是否是连接线
    • children: 列表,当前图形的子图形

元件style属性列表,不同元件会有自己的私有属性,下面是通用的一些属性

  1. width 元件宽度
  2. height 元件高度
  3. shape 当前元件的形状
  4. fillColor 元件填充颜色
  5. strokeColor 元件图形颜色
  6. align label对齐方式
  7. opacity 透明度
  8. flipH 水平翻转
  9. rotation 选择角度

江雨
445 声望2 粉丝