vue專案中使用bpmn-自定義platter
內容概述
本系列“vue專案中使用bpmn-xxxx”分為七篇,均為自己使用過程中用到的例項,手工原創,目前陸續更新中。主要包括vue專案中bpmn使用例項、應用技巧、基本知識點總結和需要注意事項,具有一定的參考價值,需要的朋友可以參考一下。如果轉載或通過爬蟲直接爬的,格式特別醜,請來原創看:我是作者原文
前情提要
經過前四篇的學習,我們能夠實現bpmn基本繪圖、預覽、為節點加事件加顏色等效果,這一篇我們來說,如何自定義左側工具欄(platter),首先看一下自定義前後效果圖對比:
我們本次要實現的目標:基於左側platter原有元素型別,創建出一個新的自定義節點。暫且叫它“草莓蛋糕”節點,型別是 bpmn:Task, 樣式我們自己找一個好看的小草莓蛋糕圖案。所以,開動吧~首先新建一個“customPalette”資料夾,裡面放我們今天所有自定義的檔案。
步驟1:建立platter類函式,命名為CustomPalette.js
export default class CustomPalette { constructor(create, elementFactory, palette) { this.create = create; this.elementFactory = elementFactory; palette.registerProvider(this); } // 這個是繪製palette的核心,函式名不要變 getPaletteEntries() { const elementFactory = this.elementFactory; const create = this.create; function dragEventFactory(type) { return function (event) { const taskShape = elementFactory.create('shape', { type: type }); create.start(event, taskShape); }; } return { 'create.cake': { title: '我是自定義節點-草莓蛋糕', // 滑鼠懸浮到節點上顯示的文字 className: 'icon-custom bpmn-icon-cake', // 樣式名 action: { // 操作該節點時會觸發的事件,此時只註冊一個拖動事件即可,否則拖動時沒有效果 dragstart: dragEventFactory('bpmn:Task') } } }; } } CustomPalette.$inject = [ 'create', 'elementFactory', 'palette' ];
此時,我們已經註冊好了一個名稱為“create.cake”的節點,拖動它時,畫布中會出現一個"bpmn:Task"型別的節點,此時需要將該檔案匯出並在頁面中引入,否則沒有效果。
步驟2:在CustomPalette.js同級,建立一個index.js檔案將其匯出
import CustomPalette from './CustomPalette'; export default { __init__: ['customPalette'] customPalette: ['type', CustomPalette], };
步驟3:頁面中(index.vue)引入index.js
import customModule from './customPalette'; export default { mounted() { this.containerEl = document.getElementById('container'); this.bpmnModeler = new BpmnModeler({ additionalModules: [ customModule ] }); }
步驟4:為節點定義樣式
新建一個customPalette.scss檔案,在該檔案同級放一張“cake.png”的圖片,作為節點的背景圖寫入。背景圖引入的話,貌似只支援.png格式,親測:jpg報錯
.bpmn-icon-cake { background-image: url('./cake.png'); } .icon-custom { background-size: 65%; background-repeat: no-repeat; background-position: center center; }
並且在main.js中引入,注意,一定要在main.js中全域性引入,否則不生效。
import 'customPalette/customPalette.scss';
此時,我們便可以在左側工具欄中看到自定義的“草莓蛋糕”節點了,但是此時拖動該節點,右側只會產生一個“bpmn:Task”的節點,只有一個框框。
我們希望的是,拖動後畫布中也顯示自定義圖示,所以我們進行下一步:自定義渲染
步驟5:畫布渲染自定義節點
此時需要我們新建一個 CustomRenderer.js檔案,作用:自定義 renderer。因為我們是在bpmn原有的元素“bpmn:Task”基礎上進行修改,所以我們需要對將BaseRenderer進行繼承。
import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer'; // 引入預設的renderer const HIGH_PRIORITY = 1500; // 最高優先順序 export default class CustomRenderer extends BaseRenderer { // 繼承BaseRenderer constructor(eventBus, bpmnRenderer) { super(eventBus, HIGH_PRIORITY); this.bpmnRenderer = bpmnRenderer; } canRender(element) { return !element.labelTarget; } drawShape(parentNode, element) { const shape = this.bpmnRenderer.drawShape(parentNode, element); return shape; } getShapePath(shape) { return this.bpmnRenderer.getShapePath(shape); } } CustomRenderer.$inject = ['eventBus', 'bpmnRenderer'];View Code
此時, CustomRenderer.js檔案大概結構完成了,注意:HIGH_PRIORITY變數和canRender不可以刪掉,否則會有問題。重頭戲是裡面的drawShape函式。
步驟6:書寫drawShape函式
我們在CustomRenderer.js同級建立一個util檔案,記錄自定義型別節點的一些屬性。
import cake from './cake.png'; // 自定義元素的型別,此時我們只需要自定義一種節點,所以陣列只有一個元素 const customElements = ['bpmn:Task']; const customConfig = { // 自定義元素的配置 cake: { url: cake, attr: {x: 0, y: 0, width: 50, height: 50} } }; export {customElements, customConfig};
現在我們來書寫drawShape函式
import { customElements, customConfig } from './util'; import { append as svgAppend, create as svgCreate } from 'tiny-svg'; ... drawShape(parentNode, element) { const type = element.type; // 獲取到型別 // 所有節點都會走這個函式,所以此時只限制,需要自定義的才去自定義,否則仍顯示bpmn預設圖示 if (customElements.includes(type)) { const {url, attr} = customConfig['cake']; const customIcon = svgCreate('image', {...attr, href: url}); element['width'] = attr.width; element['height'] = attr.height; svgAppend(parentNode, customIcon); return customIcon; } const shape = this.bpmnRenderer.drawShape(parentNode, element); return shape; }
步驟7: 匯出並使用CustomRenderer
修改之前匯出CustomPalette的 index.js檔案
import CustomPalette from './CustomPalette'; import CustomRenderer from './CustomRenderer'; export default { __init__: ['customPalette', 'customRenderer'], customPalette: ['type', CustomPalette], customRenderer: ['type', CustomRenderer] };
注意:此時__init__內的屬性名都不可以改,不要問為什麼,因為改了報錯。
步驟3中已經將該index.js引入到了頁面中,此時無需再次引入,此時我們來看看效果。
後續
專案目錄:index.vue是畫布主頁面,同級customPalette資料夾下共有6個檔案,結構如下:
各個檔案的程式碼片段在文中已經展示過了,資料夾不知道怎麼上傳到部落格。如想獲取完整原始碼或有問題,公眾號聯絡我,掃下面二維碼或公眾號搜“Lemoncool”,即可獲取~
可愛的你可能還需要
- vue專案中使用bpmn-為節點新增顏色
- vue專案中使用bpmn-節點篇(為節點新增點選事件、根據id找節點例項、更新節點名字、獲取指定型別的所有節點)
- vue專案中使用bpmn-流程圖預覽篇
- vue專案中使用bpmn-基礎篇