摘要
本文解析 bpmn - js 中的 ElementFactory、ElementRegistry 和 GraphicsFactory 模块功能、依赖、源码等,包括元素创建、SVG 操作、关系管理,也涉及 object - refs 库、BaseRenderer、DefaultRenderer 和 Styles 模块相关内容。
1. ElementRegistry 模块
ElementRegistry 是一个实例注册表,依赖 EventBus。内部通过 _elements 属性以对象形式保存所有可见元素与 SVG 节点之间的对应关系,还提供多种查找方法。 例如通过 Canvas 创建图形时,会在 ElementRegistry 中注册相关元素实例,包括根元素。 它的方法可分为查询类(如 get、getAll、getGraphics)、更新类(如 updateId、updateGraphics)、新增类(add)和移除类(remove)等,每种方法有各自的功能和参数要求。 像查询类方法中的 get 和 getAll 用于获取元素实例,getGraphics 用于获取指定元素的 SVG 节点。更新类方法 updateId 和 updateGraphics 分别用于更新元素的 ID 和 SVG 节点。新增的 add 方法用于注册元素与实例联系,remove 方法用于移除这种联系。
2. GraphicsFactory 模块
2.1 SVG 节点的创建与更新
这是 SVG 节点的控制部分。在 create 方法创建新节点时,主要创建一系列 g 标签(作为实际节点的容器)。其执行过程涉及查找元素挂载对象节点等操作,如通过 _getChildrenContainer 和 _createContainer 方法创建“包装节点”并挂载。 update 方法则不是更新 create 创建的 SVG 分组节点,而是清空对应的 g 分组标签,然后在内部创建对应的类型节点,并且能接收 hidden 参数控制显示和隐藏。
2.2 形状节点绘制与形状路径获取
包含 getShapePath、getConnectionPath(用于获取形状/连线的 path 路径)、drawShape 和 drawConnection(用于绘制形状/连线)这四个方法。这些方法内部通过 eventBus 接收对应事件函数的计算结果,自身不进行节点的路径计算和 SVG 实例创建,只做渲染。
2.3 清空和移除
_clear 方法用于清除 g.djs - visual 节点下的内容并返回清空后的 g 标签实例,remove 方法通过 ElementRegistry 找到对应的 SVG 节点,然后从父节点中清除内容。
3. ElementFactory 模块
这是 diagram.js 的基础图元定义模块,不依赖其他模块,提供了几个实例创建方法,如 createRoot、createLabel、createShape、createConnection 和 create 等。核心逻辑在 model 中的 create 方法里,model 中定义了基础类 Base 与四个衍生类 Shape、Root、Label、Connection,它们有各自特殊的属性定义,如 businessObject 用于保存元素实例业务配置,label 用于绑定元素的外部名称节点实例等。
4. object - refs 库
这是由 nikku 编写的实现 JavaScript 中对象之间双向引用的库。主要实现了构造函数 Refs,接收两个配置对象,引用关系的实际绑定通过 bind 方法。bind 方法根据属性是否为集合类型分别通过 defineCollectionProperty 和 defineProperty 来处理属性值的获取和更新。对数组属性和对象属性的处理方式不同,例如数组属性会新增 add、remove、contains 操作方法并设置标识属性。
5. BaseRenderer 与 DefaultRenderer
BaseRenderer 是实现 Shape 和 Connection 绘制的基础类,可看作抽象类,定义了五个元素绘制相关方法,并在实例化过程中定义了元素绘制的对应事件处理函数。 DefaultRenderer 是 BaseRenderer 的实现类,内部定义了三个默认样式并实现了对应的五个方法,如 drawShape、drawConnection 等方法,根据不同元素类型进行不同的操作,如非连线元素默认绘制 rect 矩形元素,连线元素默认绘制 polyline 折线元素等。
6. Styles 样式管理模块
主要提供了三个类名 -> 样式合并计算的方法,有默认类名与样式的对应关系。在实际开发中可通过重写该模块来调整默认样式或通过包装公共方法预处理样式。例如其 style 方法可进行样式合并,cls 方法可添加 class 属性到合并样式中,computeStyle 方法可合并自定义样式。还可以仿照其模式进行改写,在 new Diagram(config)时覆盖原有的 Style 模块以实现自定义需求。
7. 模块间关系与章节小结
在 diagram.js 的核心模块中,Canvas 是最核心的模块,ElementRegistry 与 GraphicsFactory 为其提供补充方法。ElementRegistry 连接 SVG 元素操作与 JavaScript 对象,GraphicsFactory 负责 SVG 节点相关操作。model.js 定义图元实例属性,ElementFactory 提供图元实例创建方法,在 bpmn.js 中对 ElementFactory 进行扩展以适配 BPMN2.0 规范元素创建。