天天看點

Bpmn.js 中文文檔(一)Bpmn.js 中文文檔(一)

Bpmn.js 中文文檔(一)

由于工作需要(其實不是很需要),在公司項目的基礎上開源了一個基于 bpmn-js + Vue 2.x + ElementUI 的一個流程編輯器 Bpmn Process Designer, 預覽位址 MiyueFE blog, 歡迎 fork 和 star。

一. 引入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參數
“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)元素,并賦予各種屬性。

使用方式:

方法與傳回值:

/**
 * 根據傳入參數建立新的元素
 * 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事件總線。

使用方式:

方法與傳回值:

/**
 * 插入新的系統資料庫
 * @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系統資料庫。

該類型幾乎不直接使用

使用方式:

方法與傳回值:

/**
 * 傳回建立後的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" }
})
           

本文首發于“掘金”

作者:MiyueFE

連結:https://juejin.cn/post/6900793894263488519

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

繼續閱讀