https://blog.csdn.net/u013253924/article/details/85784002
通過本文逐步熟悉bpmn-js。
快速介紹:
bpmn.js是一個BPMN2.0渲染工具包和web建模器。使用JavaScript編寫,在不需要后端服務器支持的前提下向現代瀏覽器內嵌入BPMN2.0流程圖。這使得它很容易的嵌入到任何web應用中。
這個庫既可以是web查看器也可以是web建模器。使用查看器將BPMN2.0流程圖嵌入到你的應用中並可以使用數據豐富你的流程圖。使用建模器在你的應用內部創建BPMN2.0流程圖。
下文將向您介紹如何使用該庫,並深入了解其內部結構。也就是說,這兩個組件促成了該庫的高度模塊化和可擴展的結構。
本文包含以下內容:
● 如何使用庫
• 嵌入查看器(預打包)
• 自己制作模型(通過npm)
● 理解bpmn-js內部
• 流程圖交互/建模(流程圖-js)
• BPMN元模型(bpmn-moddle)
• 將事物整合在一起(bpmn-js)
● 進一步探索
如何使用庫
有兩種方法在你的應用中使用bpmn.js。庫的預打包版本可以讓你在任何網站中快速添加BPMN。npm版本的設置更加復雜,但允許您訪問單個庫組件,並更容易擴展。
本節將概述這兩種方法。首先我們來介紹如何向網站中嵌入一個預打包的BPMN查看器。之后,展示如何通過npm創建一個BPMN建模器。
嵌入預打包查看器
通過一個簡單的script標簽引入就可以將預打包的BPMN查看器嵌入你的網站
-
<!-- BPMN 流程圖容器 -->
-
<div id="canvas"></div>
-
<!-- 使用 CDN 路徑 或者本地 bpmn-js 路徑 -->
-
<script src="https://unpkg.com/bpmn-js@0.27.0-1/dist/bpmn-viewer.development.js"></script>
通過引入的BPMNjs變量,可以使BPMN查看器可用。我們可以通過下面這段js來引入一個BPMN流程圖。
-
<script>
-
// 你即將要展示的流程圖
-
var bpmnXML;
-
// BpmnJS是BPMN查看器實例
-
var viewer = new BpmnJS({ container: '#canvas' });
-
// 導入BPMN 2.0流程圖
-
viewer.importXML(bpmnXML, function(err) {
-
if (err) {
-
//導入失敗 !
-
} else {
-
// 導入成功!
-
var canvas = viewer.get('canvas');
-
canvas.zoom( 'fit-viewport');
-
}
-
});
-
</script>
該代碼片段使用Viewer#importXML API顯示預加載的BPMN 2.0圖。導入圖是異步的,一旦完成,查看器將通過回調通知我們結果。
導入后,我們可以通過Viewer#get訪問各種圖表服務。在上面的代碼片段中,我們與畫布交互以使圖適合當前可用的視圖大小。
通常,通過AJAX動態加載BPMN 2.0圖更實用。這可以使用純JavaScript(如下所示)或通過實用程序庫(如jQuery)實現,后者提供了更方便的api。
-
<script>
-
var xhr = new XMLHttpRequest();
-
xhr.onreadystatechange = function() {
-
if (xhr.readyState === 4) {
-
viewer.importXML(xhr.response, function(err) {
-
// ...
-
});
-
}
-
};
-
xhr.open( 'GET', 'path-to-diagram.bpmn', true);
-
xhr.send( null);
-
</script>
查看預打包的示例以及我們的初學者示例,了解更多信息。
創建屬於自己的建模器
如果你想要圍繞庫做一些定制化,需要使用npm來使用庫。這種方法有很多優點,比如可以訪問單個庫組件。它還使我們能夠更好地控制部分打包查看器/建模器。需要使用Webpack (>=2) or Rollup來打包bpmn-js和我們的應用。
以下大致遵循modeler示例,使用該庫創建BPMN建模器。
引入庫
首先,通過npm安裝bpmn.js
npm install bpmn-js
然后,通過ES import獲得BPMN建模器
import Modeler from 'bpmn-js/lib/Modeler';
// 創建一個建模器
var modeler = new Modeler({ container: '#canvas' });
// 導入流程圖
-
modeler.importXML(bpmnXML, function(err) {
-
// ...
-
});
同樣的,需要在你的html中提供一個id聲明的畫布元素,以便建模器能夠向畫布內渲染。
添加樣式
當將建模器嵌入網頁時,要引入diagram-js樣式以及BPMN圖標字體。它們都隨bpms -js發行版一起在dist/assets文件夾下提供。
-
<link rel="stylesheet" href="bpmn-js/dist/assets/diagram-js.css" />
-
<link rel="stylesheet" href="bpmn-js/dist/assets/bpmn-font/css/bpmn-.css" />
添加樣式表可以確保圖元素獲得適當的樣式化,背景板以及畫板顯示BPMN圖標
瀏覽器打包
bpmn.js及其依賴由ES模塊分發。使用ES模塊打包器Webpack (>=2) 或者 Rollup來打包bpmn.js和你的應用。可以通過打包例子來學習更多相關。
與生命周期事件掛鈎
事件允許您鈎入建模器的生命周期以及圖交互。下面的代碼片段展示了一般情況下如何捕獲元素的更改和建模操作。
-
modeler.on( 'commandStack.changed', function() {
-
// 建模或執行撤銷/重做操作
-
});
-
modeler.on( 'element.changed', function(event) {
-
var element = event.element;
-
// 元素改變觸發
-
})
使用Viewer#on注冊事件或者擴展模塊中的事件總線。使用 Viewer#off 來停止監聽事件。請查看交互示例,以查看監聽動作中的事件。
建模器的擴展
在實際使用的過程中,你可以用additionalModules選項來擴展查看器和建模器。允許您使用自定義模塊來修改或替換現有的功能。
import OriginModule from 'diagram-js-origin';
-
// 創建一個建模器
-
var modeler = new Modeler({
-
container: '#canvas',
-
additionalModules: [
-
OriginModule,
-
require('./custom-rules'),
-
require('./custom-context-pad')
-
]
-
});
-
一個模塊(比較:模塊系統部分)是一個單元,定義了一個或多個服務。這些服務配置了bpmn.js或者提供了額外的功能。也就是通過接入流程圖的生命周期來實現的。
一些模塊,例如: diagram-js-origin 或 diagram-js-minimap提供了通用的用戶界面添加。內置的bpmn-js模塊,例如:such as bpmn rules 或 modeling提供了高定制的BPMN功能。
常用擴展BPMN建模器的方法是添加“自定義建模規則”。這樣,您可以限制或擴展用戶的建模操作。
擴展的其他例子有:
● 添加自定義元素
● 自定義面板/內容面板
● 自定義形狀的渲染
查看bpms -js-example項目,了解更多工具包擴展展示案例。
構建自定義發行版
如果你想要針對你自定義的建模器和查看器創建預打包版本,請參 custom-bundle example這個例子。如果你定制了大量的功能但是希望以簡單的方式交付給用戶的話,這可能會給到你幫助。
理解bpmn-js內部
本節探討一些bpmn-js的內部結構。
如下面的架構圖所示,bpmn-js構建在兩個重要的庫之上:diagram-js和bpmn-moddle。
我們使用diagram-js 來繪制形狀和連接。它為我們提供了與這些圖形元素交互的方法,同時也提供了額外的工具例如overlays來幫助用戶構建更為強大的查看器。對於更高級的建模情況,提供了提供了背景板、調色板和重做/撤消等功能。
bpmn-moddle清楚BPMN2.0元模型,元模型定義在BPMN2.0規范之上。它允許我們讀寫BPMN 2.0模式兼容的XML文檔,獲得關於圖形和連接的相關信息並繪制出來。
在這兩個庫之上,bpmn.js定義了BPMN的細節,比如外觀、建模規則和工具(如調色板)。我們將在下面的段落中詳細介紹各個組件。
圖交互/建模(diagram-js)
diagram-js是一個工具箱,用於在web上顯示和修改圖表。它允許我們渲染視覺元素並在它們之上構建交互體驗。它為我們提供了一個非常簡單的模塊系統,用於構建特殊的服務和服務的依賴注入。這個系統還提供了一些核心服務,這些服務實現了圖的基本內容。
此外,diagram-js為圖形元素及其關系定義了一個數據模型。
模塊系統
再下一層,diagram-js使用依賴注入(DI)來連接和發現圖組件。這個機制是建立在node-di之上的。
在diagram-js上下文中討論模塊時,我們指的是提供命名服務及其實現的單元。從這個意義上說,服務是一個函數或實例,它可以使用其他服務在圖的上下文中執行某些操作。
下面顯示了一個與生命周期事件掛鈎的服務。它通過eventBus注冊一個事件來實現,eventBus是另一個著名的服務:
-
function MyLoggingPlugin(eventBus) {
-
eventBus.on( 'element.changed', function(event) {
-
console.log('element ', event.element, ' changed');
-
});
-
}
// 確保依賴項名稱在縮小后仍然可用
MyLoggingPlugin.$inject = [ 'eventBus' ];
我們必須使用模塊定義唯一名稱發布服務:
import CoreModule from 'diagram-js/lib/core';
-
// 作為一個模塊導入
-
export default {
-
__depends__: [ CoreModule ], // {2}
-
__init__: [ 'myLoggingPlugin' ], // {3}
-
myLoggingPlugin: [ 'type', MyLoggingPlugin ] // {1}
-
};
該定義告訴DI基礎設施,該服務名為myLoggingPlugin {1},它依賴於diagram-js核心模塊{2} 並且服務應該在創建關系圖{3}時初始化。要了解更多細節,請查看node-di的文檔。
我們現在可以通過我們的自定義模塊引導diagram-js
要將模塊插入bpmn-js,可以使用additionalModules選項,如擴展Modeler部分所示。
核心服務
bpmn-js核心是圍繞一些基本服務構建的:
● Canvas -提供了添加和刪除圖形元素的api;處理元素生命周期,並提供用於縮放和滾動的api。
● EventBus -該庫的全局通信通道具有防火和遺忘策略。可以訂閱各種事件,並在事件發出后立即采取行動。事件總線幫助我們解耦關注點並模塊化功能,以便新特性能夠輕松地與現有行為掛鈎。
● ElementFactory -根據bpmn-js的內部數據模型創建形狀和連接的工廠。
● ElementRegistry—知道添加到圖中的所有元素,並提供api來根據id檢索元素及其圖形表示。
● GraphicsFactory -負責創建圖形和連接的圖形表示。實際的外觀是由渲染器定義的,即繪制模塊中的DefaultRenderer。
數據模型
實際上,diagram-js實現了一個由形狀和連接組成的簡單數據模型。
數據模型要點:形狀和連接
一個形狀有父節點、子節點列表以及傳入和傳出連接列表。
一個連接有父節點、源節點和目標節點,指向一個形狀。
ElementRegistry負責根據該模型創建形狀和連接。
在建模過程中,建模服務將根據用戶操作更新元素關系。
輔助服務(即工具箱)
除了數據模型及其核心服務之外,diagram-js還提供了豐富的輔助工具工具箱。
CommandStack-負責建模過程中的重做和撤銷。
● ContextPad-提供一個元素的上下文操作。
● Overlays——提供api來附加額外的信息到圖元素。
● Modeling——提供用於更新畫布上的元素(移動、刪除)的api
● Palette
…
讓我們繼續討論幕后發生的BPMN魔法。
BPMN元模型(bpmn-moddle)
bpmn-moddle封裝了BPMN 2.0元模型,為我們提供了讀寫BPMN 2.0 XML文檔的工具。在導入時,它將XML文檔解析為JavaScript對象樹。在建模過程中對該樹進行編輯和驗證,然后在用戶希望保存圖時將其導出回BPMN 2.0 XML。因為bpmn-moddle封裝了有關BPMN的知識,我們能夠在導入和建模期間進行驗證。根據結果,我們可以約束某些建模操作,並向用戶輸出有用的錯誤消息和警告。
就像bpmn-js一樣,bpmn-moddle的基礎也是建立在兩個庫之上的:
● moddle提供了一種用JavaScript定義元模型的簡潔方法
● 基於moddle讀寫XML文檔的model-xml
從本質上講,bpmn-moddle將BPMN規范作為元模型添加進來,並為BPMN模式驗證提供了一個簡單的接口。從庫的角度來看,它提供了以下API:
● fromXML -從給定的XML字符串創建BPMN樹
● toXML - 向BPMN 2.0 XML編寫BPMN對象樹
BPMN元模型對於bpmn -js是必不可少的,因為它允許我們驗證我們使用的BPMN 2.0文檔,提供正確的建模規則,並導出所有遵循BPMN模型的人都能理解的有效BPMN文檔。
把東西連接起來(bpmn-js)
我們學過bpms -js是建立在diagram-js和bpms -moddle之上的。它將兩者聯系在一起,並添加BPMN外觀。這包括BPMN調色板、BPMN背景板以及BPMN 2.0特定規則。在本節中,我們將解釋它在建模的不同階段是如何工作的。
當我們導入BPMN 2.0文檔時,bpmn-moddle會將其從XML解析為對象樹。bpmn-js呈現該樹的所有可見元素,即在畫布上創建各自的形狀和連接。因此,它將BPMN元素和圖形元素聯系在一起。這將產生一個結構,如下所示,用於初始事件形狀。
{
id: 'StartEvent_1',
x: 100,
y: 100,
width: 50,
height: 50,
businessObject: {
$attrs: Object
$parent: {
$attrs: Object
$parent: ModdleElement
$type: 'bpmn:Process'
flowElements: Array[1]
id: 'Process_1'
isExecutable: false
}
$type: 'bpmn:StartEvent'
id: 'StartEvent_1'
}
}
您可以通過businessObject屬性從每個圖形元素訪問底層BPMN類型。
由於BpmnRenderer,bpmn -js也知道每個BPMN元素的樣子。通過插入渲染周期,您還可以定義單個BPMN元素的自定義表示。
一旦導入完成,我們就可以開始建模了。我們使用規則來允許或不允許某些建模操作。這些規則由BpmnRules定義。我們將這些規則基於OMG定義的BPMN 2.0標准。然而,正如前面提到的,其他人也可能與規則評估掛鈎,以貢獻不同的行為。
建模模塊捆綁了BPMN 2.0相關的建模功能。它添加了BPMN 2.0特定的建模行為,並負責在用戶執行的每個建模操作中更新BPMN 2.0文檔樹(cf. BpmnUpdater)。請查看它,以更深入地了解規則、行為和BPMN更新周期。
當純粹從庫的角度來看bpmn-js時,值得一提的是它可以有三種形式:
● Viewer展示圖
● NavigatedViewer顯示和導航BPMN圖
● Modeler 建模BPMN圖
版本之間的唯一區別是它們捆綁了不同的功能集。NavigatedViewer添加了用於導航畫布的模塊,Modeler添加了大量用於創建、編輯和與畫布上的元素交互的功能。