共计 23018 个字符,预计需要花费 58 分钟才能阅读完成。
Bpmn.js 中文文档
因为工作须要(其实不是很须要),在公司我的项目的根底上开源了一个基于 bpmn-js + Vue 2.x + ElementUI 的一个流程编辑器 Bpmn Process Designer, 预览地址 MiyueFE blog, 欢送 fork 和 star。
文章首发于 掘金 Bpmn.js 中文文档(一),转载请注明出处。
一. 引入 Bpmn.js 并初始化建模器
/* 基于 vue2.x,省略了 template 模板与局部 data */
import BpmnModeler from "bpmn-js/lib/Modeler"
export default {
methods: {initModeler() {
this.bpmnModeler = new BpmnModeler({container: document.getElementById("bpmn-container")
})
}
},
mounted() {this.initModeler();
}
}
进入到源文件 Modeler.js,能够找到创立 Modeler 建模器的时候需的参数。
this.bpmnModeler = new BpmnModeler(options: Options);
interface Options {
container: DomElement; // 渲染容器
width:string | number;// 查看器宽度
height: string | number;// 查看器高度
moddleExtensions:object;// 须要用的扩大包
modules:<didi.Module>[]; // 自定义且须要笼罩默认扩大包的模块列表
additionalModules: <didi.Module>[]; // 自定义且与默认扩大包一起应用的模块列表}
初始化实现之后,在控制台打印 this.bpmnModeler
,能够发现BpmnModeler
类继承了多个根底类。
Modeler
-> BaseModeler
-> BaseViewer
-> Diagram
-> Object
Bpmn.js 提供的默认扩大包名称,能够在 this.bpmnModeler.__proto__._modules
内找到,一共凋谢了 32 个扩大包。扩大包名称能够在 this.bpmnModeler.injector._providers
内,包名即键名。
须要调用这些扩大包时,能够应用如下形式:
const xxxModule = this.bpmnModeler.get("xxx"); // xxx 代表扩大包名称
Modeler 实例化之后可间接调用的办法:
/**
* 返回 name 对应的模块实例
* @param {string} name 模块名
* @param {boolean} strict 启用严格模式。false:短少的模块解析为 null 返回;true:抛出异样
*/
this.bpmnModeler.get(name, strict);
// 创立空白流程图
// 外部调用了 importXML 办法,读取外部的默认 xml 字符串
this.bpmnModeler.createDiagram();
// 将图形 dom 挂载到指标节点
this.bpmnModeler.attachTo(parentNode);
// 清空
this.bpmnModeler.clear()
// 销毁
this.bpmnModeler.destroy()
// 脱离 dom
this.bpmnModeler.detach()
// 获取流程定义
this.bpmnModeler.getDefinitions()
// 获取扩大功能模块列表
this.bpmnModeler.getModules()
/**
* 导入解析的定义并出现 BPMN 2.0 图。实现后,查看器将后果报告回给提供的回调函数(谬误,正告)* @param {ModdleElement<Definitions>} definitions 模块名
* @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] 要出现的 BPMN 图或图的 ID(如果未提供,将出现第一个)*/
this.bpmnModeler.importDefinitions(definitions, bpmnDiagram)
/**
* 导入 xml(字符串模式),返回导入后果
* 后续会勾销传入回调函数的形式
* 举荐应用 async/await 或者链式调用
* @param {string} xml 流程图 xml 字符串
* @param {Promise} callback 回调函数,出错时返回{warnings,err}
*/
this.bpmnModeler.importXML(xml, callback)
// 登记事件监听器
this.bpmnModeler.off(eventName, callback)
// 注册事件监听,同名将删除以前的监听器,privorty 可不传,程序会主动替换回调函数
this.bpmnModeler.on(eventName, priority, callback, target)
// em。。。不理解
this.bpmnModeler.open()
// 保留为 svg 文件,与 importXML 办法一样,后续会勾销传入 callback 的形式
this.bpmnModeler.saveSVG(callback)
// 保留为 xml 文件,与 importXML 办法一样,后续会勾销传入 callback 的形式
this.bpmnModeler.saveXML(callback)
二. 根底性能
应用过程中,罕用的组件次要蕴含:palette 左侧元素栏、contentPad 元素操作块、propertiesPanel 右侧元素属性编辑栏
。
1. palette 与 contentPad
这两个组件在实例化建模器的时候曾经渲染到了页面上,只须要引入对应的款式文件即可。
import "bpmn-js/dist/assets/diagram-js.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
2. propertiesPanel
应用这个组件须要在实例化建模器时批改配置项,并引入对应款式文件
import "bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css"; // 左边工具栏款式
import propertiesPanelModule from "bpmn-js-properties-panel";
import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
export default {
methods: {initModeler() {
this.bpmnModeler = new BpmnModeler({container: document.getElementById("bpmn-container"),
propertiesPanel: {parent: "#attrs-panel"},
additionalModules: [propertiesPanelModule, propertiesProviderModule]
})
}
},
mounted() {this.initModeler();
}
}
3. 汉化
在汉化之前,能够在 github 或者码云上找到很多大佬的翻译文件,将翻译文件下载下载保留到本地。
// 1. 创立翻译文件 zh.js(命名随便),导出英文关键字对应的中文翻译
export default {
"Append EndEvent": "追加完结事件",
"Append Gateway": "追加网关",
"Append Task": "追加工作",
"Append Intermediate/Boundary Event": "追加两头抛出事件 / 边界事件",
...
}
// 2. 建设翻译模块办法 customTranslate.js
import translations from "./zh";
export default function customTranslate(template, replacements) {replacements = replacements || {};
// Translate
template = translations[template] || template;
// Replace
return template.replace(/{([^}]+)}/g, function(_, key) {let str = replacements[key];
if (translations[replacements[key]] !== null &&
translations[replacements[key]] !== "undefined"
) {
// eslint-disable-next-line no-mixed-spaces-and-tabs
str = translations[replacements[key]];
// eslint-disable-next-line no-mixed-spaces-and-tabs
}
return str || "{" + key + "}";
});
}
// 3. 在实例化建模器时以自定义模块的形式传入参数
import customTranslate from "./pugins/customTranslate";
export default {
methods: {initModeler() {
this.bpmnModeler = new BpmnModeler({container: document.getElementById("bpmn-container"),
additionalModules: [{ translate: ["value", customTranslate] }
]
})
}
}
}
翻译文件来自码云,然而遗记了作者的信息了,如果作者发现请您分割我更改或者删除
4. 其余性能(非自定义的功能模块配置项)
增加键盘快捷键:
this.bpmnModeler = new BpmnModeler({container: document.getElementById("bpmn-container"),
keyboard: {bindTo: document // 或者 window,留神与内部表单的键盘监听事件是否抵触}
});
三. 事件
Bpmn.js 提供了 EventBus 事件总线模块来治理监听事件,并预设了 244 个事件。
上面的元素对象指蕴含 element 元素的对象,其余属性不定(局部事件返回的对象也不蕴含 element)。
“–”短横线示意临时没有找到何时触发该事件
以下事件均可应用
this.bpmnModeler.on(eventName, callback)
或者eventBus.on(eventName, callback)
的模式注册。
// 通过事件总线收回的事件
interface InternalEvent {
type: string; // 产生的事件名称,然而很快会被置为 undefined
element: Shape | Connection;
elements: Element[];
shape: Shape;
context: object; // 有点简单,有趣味的敌人能够钻研
gfx?: SVGElement;
svg?: SVGElement;
viewport?: SVGElement;
viewbox?: Viewbox;
pad?: object; // 见 Element.pad
}
interface Element {
element: Shape | Connection;
gfx?: SVGElement;
pad?: {
id: string;
html: DOMElement;
position: {right: number; top: number};
scale: {max: number; min: number};
show: object | null;
type: string; // 个别是 "context-pad"
}
}
interface Elements {elements: Array<Shape | Connection>}
interface Canvas {
svg?: SVGElement;
viewport?: SVGElement;
}
interface Viewbox {
viewbox: {
height: number;
width: number;
x: number;
y: number;
inter: object; // 蕴含 x,y,width,height 的一个对象
outer: object; // 蕴含 x,y,width,height 的一个对象
scale: number; // 以后缩放比例(小数)}
}
序号 | 事件名 | 阐明 | callback 参数 |
---|---|---|---|
0 | “diagram.destroy” | 流程编辑器销毁 | event:InternalEvent |
1 | “render.shape” | 调用 GraphicsFactory.drawShape 时触发,开始渲染形态 | |
2 | “render.connection” | 调用 GraphicsFactory.drawConnection 时触发,开始渲染连线 | |
3 | “render.getShapePath” | 调用 GraphicsFactory.getShapePath 时触发,开始获取形态门路 | |
4 | “render.getConnectionPath” | 调用 GraphicsFactory.getConnectionPath 时触发 | |
5 | “diagram.init” | 批示画布已筹备好在其上进行绘制 | |
6 | “shape.added” | 已更新到 xml 内,触发渲染办法,返回值为插入的新元素 | event:InternalEvent, element: Element |
7 | “connection.added” | 已更新到 xml 内,触发渲染办法,返回值为插入的新元素 | event:InternalEvent, element: Element |
8 | “shape.removed” | 形态移除实现,返回值为被移除元素 | event:InternalEvent, element: Element |
9 | “connection.removed” | 连线移除实现,返回值为被移除元素 | |
10 | “elements.changed” | 元素产生扭转并更改实现 | event: InternalEvent, element: Elements |
11 | “diagram.clear” | 流程编辑器元素及画布已清空 | event:InternalEvent |
12 | “canvas.destroy” | 画布销毁 | event:InternalEvent |
13 | “canvas.init” | 画布初始化实现 | |
14 | “shape.changed” | 形态属性更新,返回以后元素 | event:InternalEvent, element: Element |
15 | “connection.changed” | 连线属性更新,返回以后元素 | event:InternalEvent, element: Element |
16 | “interactionEvents.createHit” | shape.added,connection.added 之后触发 | |
17 | “interactionEvents.updateHit” | shape.changed,connection.changed 之后触发 | |
18 | “shape.remove” | 形态被选中移除,返回被移除的元素对象 | event:InternalEvent, element: Element |
19 | “connection.remove” | 连线被选中移除 | event:InternalEvent, element: Element |
20 | “element.hover” | 鼠标挪动到元素上,返回鼠标地位处元素对象 | event:InternalEvent, element: Element |
21 | “element.out” | 鼠标移出元素,返回鼠标最近移入的元素对象 | event:InternalEvent, element: Element |
22 | “selection.changed” | 选中元素变动时,返回新选中的元素对象 | event:InternalEvent, element: Element |
23 | “create.end” | 从 palette 中新建的元素创立实现(不分明为什么有两个雷同的参数) | event:InternalEvent, event:InternalEvent |
24 | “connect.end” | 从 palette 中或者从选中节点中新建的连线元素创立实现(不分明为什么有两个雷同的参数) | event:InternalEvent, event:InternalEvent |
25 | “shape.move.end” | 形态元素挪动完结后 | event:InternalEvent, element: Element |
26 | “element.click” | 元素单击事件 | event:InternalEvent, element: Element |
27 | “canvas.viewbox.changing” | 视图缩放过程中 | event:InternalEvent |
28 | “canvas.viewbox.changed” | 视图缩放实现 | event:InternalEvent, viewbox: Viewbox |
29 | “element.changed” | 元素产生扭转时触发,返回产生扭转的元素 | event:InternalEvent, element: Element |
30 | “element.marker.update” | 元素标识更新时触发 | |
31 | “attach” | 画布或者根节点从新挂载时 | |
32 | “detach” | 画布或者根节点移除挂载时 | |
33 | “editorActions.init” | 流程编辑模块加载实现 | |
34 | “keyboard.keydown” | 键盘按键按下 | |
35 | “element.mousedown” | 鼠标在元素上按下时触发 | event:InternalEvent, element: Element |
36 | “commandStack.connection.start.canExecute” | 连线开始时检测是否能够创立连线,点击创立连线的按钮时触发 | |
37 | “commandStack.connection.create.canExecute” | 连线开始时检测是否能够创立连线, | |
38 | “commandStack.connection.reconnect.canExecute” | 检测连线是否能够批改 | |
39 | “commandStack.connection.updateWaypoints.canExecute” | 检测是否能够更新连线拐点 | |
40 | “commandStack.shape.resize.canExecute” | 检测形态是否能够更改大小 | |
41 | “commandStack.elements.create.canExecute” | 检测是否能够创立元素 | |
42 | “commandStack.elements.move.canExecute” | 检测是否能够挪动元素 | |
43 | “commandStack.shape.create.canExecute” | 检测是否能够创立形态 | |
44 | “commandStack.shape.attach.canExecute” | 检测元素是否能够挂载到指标上 | |
45 | “commandStack.element.copy.canExecute” | 检测元素是否能够被复制 | |
46 | “shape.move.start” | 形态开始挪动 | event:InternalEvent, element: Element |
47 | “shape.move.move” | 形态挪动过程中 | event:InternalEvent, element: Element |
48 | “elements.delete” | 元素被删除,返回被删除的元素 | event:InternalEvent, element: Element |
49 | “tool-manager.update” | ||
50 | “i18n.changed” | ||
51 | “drag.move” | 元素拖拽过程中 | event:InternalEvent, event:InternalEvent |
52 | “contextPad.create” | 当 contextPad 呈现的时候触发 | event:InternalEvent, element: Element |
53 | “palette.create” | 左侧 palette 开始创立 | |
54 | “autoPlace.end” | 主动对齐完结 | |
55 | “autoPlace” | 触发主动对齐办法时 | |
56 | “drag.start” | 元素拖拽开始 | event:InternalEvent, event:InternalEvent |
57 | “drag.init” | 点击了元素行将进行拖拽(包含点击 palette 和画布内的元素) | event:InternalEvent, event:InternalEvent |
58 | “drag.cleanup” | 元素拖拽完结 | event:InternalEvent, event:InternalEvent |
59 | “commandStack.shape.create.postExecuted” | 当创立形节点的时候触发 | event:InternalEvent, event:InternalEvent |
60 | “commandStack.elements.move.postExecuted” | 当元素挪动的时候触发 | event:InternalEvent, event:InternalEvent |
61 | “commandStack.shape.toggleCollapse.postExecuted” | 当可折叠的节点开展 / 折叠的时候触发 | event:InternalEvent, event:InternalEvent |
62 | “commandStack.shape.resize.postExecuted” | 当节点大小产生扭转的时候触发 | event:InternalEvent, event:InternalEvent |
63 | “commandStack.element.autoResize.canExecute” | 当节点大小产生主动调整的时候触发 | event:InternalEvent, event:InternalEvent |
64 | “bendpoint.move.hover” | 鼠标点击连线折点并进行挪动时触发 | event:InternalEvent, event:InternalEvent |
65 | “bendpoint.move.out” | 返回工夫不定,可能在拖动时触发,也可能在拖动过程中 | event:InternalEvent, event:InternalEvent |
66 | “bendpoint.move.cleanup” | 鼠标点击连线折点时或者挪动折点实现 | event:InternalEvent, event:InternalEvent |
67 | “bendpoint.move.end” | 鼠标点击连线折点并挪动实现 | event:InternalEvent, event:InternalEvent |
68 | “connectionSegment.move.start” | 鼠标选中连线进行拖动开始 | event:InternalEvent, event:InternalEvent |
69 | “connectionSegment.move.move” | 鼠标选中连线进行拖动过程中 | event:InternalEvent, event:InternalEvent |
70 | “connectionSegment.move.hover” | 鼠标选中连线进行拖动开始 | event:InternalEvent, event:InternalEvent |
71 | “connectionSegment.move.out” | 鼠标选中连线,按下鼠标时 | event:InternalEvent, event:InternalEvent |
72 | “connectionSegment.move.cleanup” | 鼠标选中连线后放开鼠标时 | event:InternalEvent, event:InternalEvent |
73 | “connectionSegment.move.cancel” | 选中连线之后勾销连贯 | event:InternalEvent, event:InternalEvent |
74 | “connectionSegment.move.end” | 选中连线并拖拽完结 | event:InternalEvent, event:InternalEvent |
75 | “element.mousemove” | 鼠标移除元素后 | |
76 | “element.updateId” | 更新元素 id 时触发 | |
77 | “bendpoint.move.move” | 连线上的拐点被拖拽挪动时触发 | |
78 | “bendpoint.move.start” | 连线上的拐点被拖拽挪动开始时触发 | |
79 | “bendpoint.move.cancel” | 连线上的拐点被点击并勾销拖拽 | |
80 | “connect.move” | 连线被挪动时 | |
81 | “connect.hover” | ||
82 | “connect.out” | ||
83 | “connect.cleanup” | ||
84 | “create.move” | ||
85 | “create.hover” | ||
86 | “create.out” | ||
87 | “create.cleanup” | ||
88 | “create.init” | ||
89 | “copyPaste.copyElement” | ||
90 | “copyPaste.pasteElements” | ||
91 | “moddleCopy.canCopyProperties” | ||
92 | “moddleCopy.canCopyProperty” | ||
93 | “moddleCopy.canSetCopiedProperty” | ||
94 | “copyPaste.pasteElement” | ||
95 | “popupMenu.getProviders.bpmn-replace” | ||
96 | “contextPad.getProviders” | ||
97 | “resize.move” | ||
98 | “resize.end” | ||
99 | “commandStack.shape.resize.preExecute” | ||
100 | “spaceTool.move” | ||
101 | “spaceTool.end” | ||
102 | “create.start” | ||
103 | “commandStack.connection.create.postExecuted” | ||
104 | “commandStack.connection.layout.postExecuted” | ||
105 | “shape.move.init” | ||
106 | “resize.start” | ||
107 | “resize.cleanup” | ||
108 | “directEditing.activate” | ||
109 | “directEditing.resize” | ||
110 | “directEditing.complete” | ||
111 | “directEditing.cancel” | ||
112 | “commandStack.connection.updateWaypoints.postExecuted” | ||
113 | “commandStack.label.create.postExecuted” | ||
114 | “commandStack.elements.create.postExecuted” | ||
115 | “commandStack.shape.append.preExecute” | ||
116 | “commandStack.shape.move.postExecute” | ||
117 | “commandStack.elements.move.preExecute” | ||
118 | “commandStack.connection.create.postExecute” | ||
119 | “commandStack.connection.reconnect.postExecute” | ||
120 | “commandStack.shape.create.executed” | ||
121 | “commandStack.shape.create.reverted” | ||
122 | “commandStack.shape.create.preExecute” | ||
123 | “shape.move.hover” | ||
124 | “global-connect.hover” | ||
125 | “global-connect.out” | ||
126 | “global-connect.end” | ||
127 | “global-connect.cleanup” | ||
128 | “connect.start” | ||
129 | “commandStack.shape.create.execute” | ||
130 | “commandStack.shape.create.revert” | ||
131 | “commandStack.shape.create.postExecute” | ||
132 | “commandStack.elements.create.preExecute” | ||
133 | “commandStack.elements.create.revert” | ||
134 | “commandStack.elements.create.postExecute” | ||
135 | “commandStack.connection.layout.executed” | ||
136 | “commandStack.connection.create.executed” | ||
137 | “commandStack.connection.layout.reverted” | ||
138 | “commandStack.shape.move.executed” | ||
139 | “commandStack.shape.delete.executed” | ||
140 | “commandStack.connection.move.executed” | ||
141 | “commandStack.connection.delete.executed” | ||
142 | “commandStack.shape.move.reverted” | ||
143 | “commandStack.shape.delete.reverted” | ||
144 | “commandStack.connection.create.reverted” | ||
145 | “commandStack.connection.move.reverted” | ||
146 | “commandStack.connection.delete.reverted” | ||
147 | “commandStack.canvas.updateRoot.executed” | ||
148 | “commandStack.canvas.updateRoot.reverted” | ||
149 | “commandStack.shape.resize.executed” | ||
150 | “commandStack.shape.resize.reverted” | ||
151 | “commandStack.connection.reconnect.executed” | ||
152 | “commandStack.connection.reconnect.reverted” | ||
153 | “commandStack.connection.updateWaypoints.executed” | ||
154 | “commandStack.connection.updateWaypoints.reverted” | ||
155 | “commandStack.element.updateAttachment.executed” | ||
156 | “commandStack.element.updateAttachment.reverted” | ||
157 | “commandStack.shape.delete.postExecute” | ||
158 | “commandStack.canvas.updateRoot.postExecute” | ||
159 | “spaceTool.selection.init” | ||
160 | “spaceTool.selection.ended” | ||
161 | “spaceTool.selection.canceled” | ||
162 | “spaceTool.ended” | ||
163 | “spaceTool.canceled” | ||
164 | “spaceTool.selection.end” | ||
165 | “commandStack.shape.delete.postExecuted” | ||
166 | “commandStack.connection.create.preExecuted” | ||
167 | “commandStack.shape.replace.preExecuted” | ||
168 | “bpmnElement.added” | ||
169 | “commandStack.element.updateProperties.postExecute” | ||
170 | “commandStack 或者.label.create.postExecute” | ||
171 | “commandStack.connection.layout.postExecute” | ||
172 | “commandStack.connection.updateWaypoints.postExecute” | ||
173 | “commandStack.shape.replace.postExecute” | ||
174 | “commandStack.shape.resize.postExecute” | ||
175 | “shape.move.rejected” | ||
176 | “create.rejected” | ||
177 | “elements.paste.rejected” | ||
178 | “commandStack.shape.delete.preExecute” | ||
179 | “commandStack.connection.reconnect.preExecute” | ||
180 | “commandStack.element.updateProperties.postExecuted” | ||
181 | “commandStack.shape.replace.postExecuted” | ||
182 | “commandStack.shape.toggleCollapse.executed” | ||
183 | “commandStack.shape.toggleCollapse.reverted” | ||
184 | “spaceTool.getMinDimensions” | ||
185 | “commandStack.connection.delete.preExecute” | ||
186 | “commandStack.canvas.updateRoot.preExecute” | ||
187 | “commandStack.spaceTool.preExecute” | ||
188 | “commandStack.lane.add.preExecute” | ||
189 | “commandStack.lane.resize.preExecute” | ||
190 | “commandStack.lane.split.preExecute” | ||
191 | “commandStack.elements.delete.preExecute” | ||
192 | “commandStack.shape.move.preExecute” | ||
193 | “commandStack.spaceTool.postExecuted” | ||
194 | “commandStack.lane.add.postExecuted” | ||
195 | “commandStack.lane.resize.postExecuted” | ||
196 | “commandStack.lane.split.postExecuted” | ||
197 | “commandStack.elements.delete.postExecuted” | ||
198 | “commandStack.shape.move.postExecuted” | ||
199 | “saveXML.start” | ||
200 | “commandStack.connection.create.preExecute” | ||
201 | “commandStack.connection.move.preExecute” | ||
202 | “shape.move.out” | ||
203 | “shape.move.cleanup” | ||
204 | “commandStack.elements.move.preExecuted” | ||
205 | “commandStack.shape.delete.execute” | ||
206 | “commandStack.shape.delete.revert” | ||
207 | “spaceTool.selection.start” | ||
208 | “spaceTool.selection.move” | ||
209 | “spaceTool.selection.cleanup” | ||
210 | “spaceTool.cleanup” | ||
211 | “lasso.selection.init” | ||
212 | “lasso.selection.ended” | ||
213 | “lasso.selection.canceled” | ||
214 | “lasso.ended” | ||
215 | “lasso.canceled” | ||
216 | “lasso.selection.end” | ||
217 | “lasso.end” | ||
218 | “lasso.start” | ||
219 | “lasso.move” | ||
220 | “lasso.cleanup” | ||
221 | “hand.init” | ||
222 | “hand.ended” | ||
223 | “hand.canceled” | ||
224 | “hand.move.ended” | ||
225 | “hand.move.canceled” | ||
226 | “hand.end” | ||
227 | “hand.move.move” | ||
228 | “hand.move.end” | ||
229 | “global-connect.init” | ||
230 | “global-connect.ended” | ||
231 | “global-connect.canceled” | ||
232 | “global-connect.drag.ended” | ||
233 | “global-connect.drag.canceled” | ||
234 | “palette.getProviders” | ||
235 | “propertiesPanel.isEntryVisible” | ||
236 | “propertiesPanel.isPropertyEditable” | ||
237 | “root.added” | ||
238 | “propertiesPanel.changed” | ||
239 | “propertiesPanel.resized” | ||
240 | “elementTemplates.changed” | ||
241 | “canvas.resized” | ||
242 | “import.parse.complete” | 读取模型(xml)实现 | |
243 | “commandStack.changed” | 产生任意可撤销 / 复原操作时触发,可用来实时更新 xml |
四. Moddles
1. ElementFactory Diagram 元素工厂
用于创立各种 Diagram(djs.model)元素,并赋予各种属性。
应用形式:
const ElementFactory = this.bpmnModeler.get("ElementFactory")
办法与返回值:
/**
* 依据传入参数创立新的元素
* type:"root" | "label" | "connection" | "shape"
* attrs?: object
*/
ElementFactory.create(type, attrs);
衍生办法:
依据 create 办法传入的不同 type,衍生了四种创立图形元素的办法。
// attrs 非必传参数
ElementFactory.createRoot(attrs);
ElementFactory.createLabel(attrs);
ElementFactory.createConnection(attrs);
ElementFactory.createShape(attrs);
Bpmn.js 补充办法:
因为 diagram.js
默认只配置了 Shape, Connection, Root, Label
四种元素,不足以撑持整个流程编辑器须要的元素类型。所以 Bpmn.js 在原来的根底上减少了其余办法来定义别的流程元素节点。
// 创立 bpmn 对应的模型元素
// elementType: string
// attrs?: 自定义属性
ElementFactory.createBpmnElement(elementType, attrs)
// 创立参与者
// attrs?: object 自定义属性
ElementFactory.createParticipantShape(attrs)
2. ElementRegistry 图形注册表
用于追踪所有元素。注入了 EventBus 事件总线。
应用形式:
const ElementRegistry = this.bpmnModeler.get("ElementRegistry")
办法与返回值:
/**
* 插入新的注册表
* @param element:Shape | Connection
* @param gfx: SVGElement
* @param secondaryGfx?:SVGElement
*/
ElementRegistry.add(element, gfx, secondaryGfx);
// 移除元素
ElementRegistry.remove(element)
// 更新元素模型的 id,同时触发事件 'element.updateId'
ElementRegistry.updateId(element, newId)
// 获取对应 id 的元素模型
ElementRegistry.get(id)
// 依据传入的过滤办法返回符合条件的元素模型数组
ElementRegistry.filter(fn(element, gfx))
// 依据传入的过滤办法返回符合条件的第一个元素模型
ElementRegistry.find(fn(element, gfx))
// 返回所有已渲染的元素模型
ElementRegistry.getAll()
// 遍历所有已渲染元素模型,执行传入办法
ElementRegistry.forEach(fn(element, gfx))
/**
* 返回对应的 SVGElement
* @param filter:string | Model id 或者元素模型
* @param secondary?: boolean = false 是否返回辅助连贯的元素
*/
ElementRegistry.getGraphics(filter, secondary)
3. GraphicsFactory 图形元素工厂
用于创立可显示的图形元素。注入了 EventBus 事件总线与 ElementRegistry 注册表。
该类型简直不间接应用
应用形式:
const GraphicsFactory = this.bpmnModeler.get("GraphicsFactory")
办法与返回值:
/**
* 返回创立后的 SVGElement
* @param type:"shape" | "connection" 元素类型
* @param element?: SVGElement
* @param parentIndex?: number 地位
*/
GraphicsFactory.create(type, element, parentIndex)
// 绘制节点,触发 "render.shape"
GraphicsFactory.drawShape(visual, element)
// 获取元素的尺寸等,触发 "render.getShapePath"
GraphicsFactory.getShapePath(element)
// 绘制连线,触发 "render.connection"
GraphicsFactory.drawConnection(visual, element)
// 获取连线的尺寸等,触发 "render.getConnectionPath"
GraphicsFactory.getConnectionPath(waypoints)
// 更新元素显示成果(element.type 只容许 "shape" 或者 "connaction")
GraphicsFactory.update(element)
GraphicsFactory.remove(element)
4. Canvas 画布
外围模块之一,解决所有的元素绘制与显示。注入了 ”canvas.config”, “EventBus”, “GraphicsFactory”, “ElementRegistry”。
应用形式:
const Canvas = this.bpmnModeler.get("Canvas")
外部办法:
/**
* 画布初始化,依据 config 配置为 svg 元素创立一个 div class="djs-container" 的父容器。并挂载到制订的 dom 节点上
* 并在这个 div 节点下创立一个 svg 元素,挂载前面所有节点
* 之后触发 "diagram.init" 与 "canvas.init"
* 同时注册 'shape.added', 'connection.added', 'shape.removed', 'connection.removed', 'elements.changed', 'diagram.destroy', 'diagram.clear'
* config: object 默认继承实例化 BpmnModeler 的配置
*/
Canvas._init(config)
/**
* 画布销毁
* 触发 "canvas.destroy"
* 删除 Canvas 外部属性,并移除初始化时宣称的 dom 节点
*/
Canvas._destroy()
/**
* 按类型创立新的元素对象, 同时触发对应的 "[shape | connection].add" 和 "[shape | connection].added" 事件,返回创立的元素对象(衍生的 addShape,addConnection 办法)
* @param type: "shape" | "connection" 元素类型
* @param element: object | djs.model
* @param parent?: object | djs.model 父元素,默认为根元素对象
* @param parentIndex?: number
* @return element: object | djs.model
*/
Canvas._addElement(type, element, parent, parentIndex)
/**
* 移除对应的元素, 同时触发对应的 "[shape | connection].remove" 和 "[shape | connection].removed" 事件,返回被删除的元素对象(衍生的 addShape,addConnection 办法)
* @param type: "shape" | "connection" 元素类型
* @param element: object | djs.model
* @param parent?: object | djs.model 父元素,默认为根元素对象
* @param parentIndex?: number
* @return element: object | djs.model
*/
Canvas._removeElement(element, type)
办法与返回值:
// 返回最上层的 SVGElement
Canvas.getDefaultLayer()
// 返回用于在其上绘制元素或正文的图层(这个不怎么了解。。。)
Canvas.getLayer(name, index)
// 返回蕴含画布的 Dom 节点
Canvas.getContainer()
/**
* 将标记更新包 element 上(基本上是 css 类),同时触发 "element.marker.update", 无返回值
* @param element:Shape | Connaction | string(元素 id)
* @param marker: string
*/
canvas.addMarker(element, marker)
/**
* 移除元素上的标记,同时触发 "element.marker.update", 无返回值
* @param element:Shape | Connaction | string(元素 id)
* @param marker: string
*/
canvas.removeMarker(element, marker)
/**
* 检测元素是否具备某个标记
* @param element:Shape | Connaction | string(元素 id)
* @param marker: string
* @return status: boolean
*/
Canvas.hasMarker(element, marker)
/**
* 切换元素的标记状态,存在即 remove,不存在则 add
* @param element:Shape | Connaction | string(元素 id)
* @param marker: string
*/
Canvas.toggleMarker(element, marker)
/**
* 返回画布的根元素
* @return element: Object|djs.model
*/
Canvas.getRootElement()
/**
* 设置新的画布的根元素,返回新的根元素
* @param element:object | djs.model
* @param override: boolean 是否要笼罩以前的根元素
* @return element: Object|djs.model
*/
Canvas.setRootElement(element, override)
/**
* 增加新的节点(形态)图形元素
* @param shape: object | djs.model 插入的元素 model 或者属性配置对象
* @param parent?: djs.model 父元素,默认根节点(画布下第一级 SVG | Root)* @param parentIndex?: number
* @return Element: djs.model
*/
Canvas.addShape(shape, parent, parentIndex)
/**
* 增加新的连线元素
* @param Connaction: object | djs.model 插入的元素 model 或者属性配置对象
* @param parent?: djs.model 父元素,默认根节点(画布下第一级 SVG | Root)* @param parentIndex?: number
* @return Element: djs.model
*/
Canvas.addConnection(Connaction, parent, parentIndex)
/**
* 移除节点元素, 返回被移除的节点
* @param shape:string | djs.model 节点 id 或者 model
* @return element: djs.model
*/
Canvas.removeShape(shape)
/**
* 移除连线元素, 返回被移除的对象
* @param shape:string | djs.model 节点 id 或者 model
* @return element: djs.model
*/
Canvas.removeConnaction(connection)
/**
* 查问图形元素的 SVGElement,即 ElementRegistry.getGraphics()办法。* @param shape:string | djs.model 节点 id 或者 model
* @param secondary?:boolean
* @return element: SVGElement
*/
Canvas.getGraphics(element, secondary)
/**
* 获取或者设置新的画布的视图框。该办法的 getter 可能会返回一个缓存中的 viewbox(如果以后时刻视图正在产生扭转)* 如果要强制从新计算,请先执行 Canvas.viewbox(false)
* @param box: Box 新的视图框配置
* @param box.x: number = 0 视图框可见的画布区域在 x 轴坐标(原点左上角)* @param box.y: number = 0 视图框可见的画布区域在 y 轴坐标(原点左上角)* @param box.width: number 视图框可见宽度
* @param box.height: number 视图框可见高度
* @return box 以后视图区域
*/
Canvas.viewbox(box)
/**
* 具备滚动条时调整滚动地位
* @param delta:Delta 新的滚动地位
* @param delta.dx:number x 轴方向的位移大小
* @param delta.dy:number y 轴方向的位移大小
* @return
*/
Canvas.scroll(delta)
/**
* 设置新的缩放比例或者核心地位,返回以后的缩放比例
* @param newScale?:number 新的缩放比例
* @param center?:Point | "auto" | null
* @param center.x: number
* @param center.y: number
* @return scale: number
*/
Canvas.zoom(newScale, center)
// 被动触发 "canvas.resized" 事件
Canvas.resized()
// 返回画布元素的大小
Canvas.getSize()
// 返回画布的相对边界
// @return BBox {
// x: x;
// y: y;
// width: width;
// height: height;
// }
Canvas.getAbsoluteBBox()
5. EventBus 事件总线
外围模块之一,通用事件总线,该组件用于跨图实例进行通信。图的其余局部能够应用它来侦听和播送事件。
应用形式:
const EventBus = this.bpmnModeler.get("eventBus");
外围办法:
/**
* 注册事件监听器
* @param events: string | string[] 事件名称(s)* @param priority?: number 优先级,默认 1000
* @param callback: Function 回调函数
* @param that?: object 上下文中的 this,会将其传递给 callback
*/
EventBus.on(events, priority, callback, that)
/**
* 注册只执行一次的事件监听器
* @param events: string | string[] 事件名称(s)* @param priority?: number 优先级,默认 1000
* @param callback: Function 回调函数
* @param that?: object 上下文中的 this,会将其传递给 callback
*/
EventBus.once(events, priority, callback, that)
/**
* 敞开、删除事件监听器
* @param events
* @param callback
*/
EventBus.off(events, callback)
/**
* 创立一个能够让 EventBus 辨认的事件,并返回这个事件
* @param data: object
* @return event: object
*/
EventBus.createEvent(data)
/**
* 被动触发事件
* @param type: string | object 事件名称 / 嵌套事件名称的对象({type:string})* @param data: any 传递给回调函数的参数
* @return status: boolean | any 事件返回值(如果指定);如果侦听器阻止了默认操作,则返回 false
*/
EventBus.fire(type, data)
6. InternalEvent 事件
指通过事件总线收回来的事件实例。
/**
* A event that is emitted via the event bus.
*/
function InternalEvent() {}
// 阻止事件流传给其余接收者
InternalEvent.prototype.stopPropagation = function() {this.cancelBubble = true;};
// 阻止事件的默认后果
InternalEvent.prototype.preventDefault = function() {this.defaultPrevented = true;};
InternalEvent.prototype.init = function(data) {assign(this, data || {});
};
事件能够联合事件总线对事件监听器做自定义解决。
比方:
EventBus.on("foo", function(event) {console.log(event.type) // "foo"
event.stopPropagation(); // 进行事件持续流传
event.preventDefault(); // 阻止事件原来的返回值,返回 false})
// 传入自定义信息
const payload = {fooPayload: "foo"}
EventBus.on("foo", function(event, payload) {console.log(payload) // {fooPayload: "foo"}
})