使用 Viewer 模式仅供展示,不可编辑。编辑请使用 Modeler
npm install bpmn-js --save
// 如果想要从本地导入bpmn格式的流程文件,需要配置 raw-loader
npm install raw-loader --save
// 用来实现拖动功能
npm i diagram-js --save
bpmn-js 的 Viewer 模式默认并不支持拖动功能,但提供了 diagram-js 插件来实现,这里直接写了一个自定义 Viewer (custom-bpmn) 用来实现拖动功能,使用时直接引入 custom-bpmn 即可。
import inherits from 'inherits'
import Viewer from 'bpmn-js/lib/Viewer'
import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll'
import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'
function CustomViewer (options) {
Viewer.call(this, options)
}
inherits(CustomViewer, Viewer)
CustomViewer.prototype._modules = [].concat(Viewer.prototype._modules, [
ZoomScrollModule,
MoveCanvasModule
])
export { CustomViewer }
除了使用本地bpmn格式的流程文件外,也可以将bpmn流程图内容作为字符串赋予给变量xmlStr,在渲染时通过importXML(xmlStr)直接读取xmlStr变量的内容从而实现绘图
<template>
<div class="containers">
<div class="canvas" ref="canvas" style="height: 30vh"></div>
</div>
</template>
<script>
// 引入自定义 Viewer
import {CustomViewer} from '@/util/custom-bpmn'
export default {
name: "bpmnViewer",
mounted() {
this.init();
},
data() {
return {
bpmnViewer: null,
container: null,
canvas: null
};
},
methods: {
init () {
const canvas = this.$refs.canvas
this.bpmnViewer = new CustomViewer({
container: canvas
})
this.createNewDiagram()
},
async createNewDiagram() {
try {
// 本地 .bpmn 文件地址
const bpmnXml = require('@/bpmns/test.bpmn')
const result = await this.bpmnViewer.importXML(bpmnXml.default)
const { warnings } = result;
console.log(warnings);
this.addMarker()
} catch (err) {
console.log(err.message, err.warnings);
}
}
}
};
</script>
js
addMarker () {
let canvas = this.bpmnViewer.get('canvas')
// 需要高亮的节点id
const value = {
highLine: [],
highPoint: []
}
// 高亮线
value.highLine.forEach((e) => {
if (e) {
canvas.addMarker(e, 'highlightFlow')
}
})
// 高亮任务
value.highPoint.forEach((e) => {
if (e) {
canvas.addMarker(e, 'highlight')
}
})
// 高亮我执行过的任务
value.ido.forEach((e) => {
if (e) {
canvas.addMarker(e, 'highlightIDO')
}
})
// 高亮下一个任务
value.waitingToDo.forEach((e) => {
if (e) {
canvas.addMarker(e, 'highlightTODO')
}
})
}
css 样式
/*流程高亮*/
.highlight .djs-visual > :nth-child(1) {
stroke: green !important;
fill: rgba(0, 80, 0, 0.4) !important;
}
.highlightFlow .djs-visual > :nth-child(1) {
stroke: green !important;
}
.highlightIDO .djs-visual > :nth-child(1) {
stroke: rgb(255, 196, 0) !important;
fill: rgba(255, 196, 0, 0.4) !important;
}
.highlightTODO .djs-visual > :nth-child(1) {
stroke: rgb(30, 144, 255) !important;
fill: rgba(255, 255, 255, 0.4) !important;
}
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="5.1.2">
<process id="Process_1" isExecutable="false">
<startEvent id="StartEvent_ops_coffee" name="开始">
<outgoing>Flow_0jfbnmboutgoing>
startEvent>
<sequenceFlow id="Flow_0jfbnmb" sourceRef="StartEvent_ops_coffee" targetRef="Activity_0pih3d0" />
<task id="Activity_0pih3d0" name="流程1">
<incoming>Flow_0jfbnmbincoming>
<outgoing>Flow_0ow8zy1outgoing>
task>
<task id="Activity_07b4aeg" name="流程2">
<incoming>Flow_0ow8zy1incoming>
<outgoing>Flow_0iaccmioutgoing>
task>
<sequenceFlow id="Flow_0ow8zy1" sourceRef="Activity_0pih3d0" targetRef="Activity_07b4aeg" />
<task id="Activity_11xlozw" name="流程3">
<incoming>Flow_0iaccmiincoming>
<outgoing>Flow_0bax3n1outgoing>
task>
<sequenceFlow id="Flow_0iaccmi" sourceRef="Activity_07b4aeg" targetRef="Activity_11xlozw" />
<sequenceFlow id="Flow_0bax3n1" sourceRef="Activity_11xlozw" targetRef="Event_07dyz8d" />
<endEvent id="Event_07dyz8d" name="結束">
<incoming>Flow_0bax3n1incoming>
endEvent>
process>
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
<bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNEdge id="Flow_0jfbnmb_di" bpmnElement="Flow_0jfbnmb">
<omgdi:waypoint x="188" y="120" />
<omgdi:waypoint x="300" y="120" />
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0ow8zy1_di" bpmnElement="Flow_0ow8zy1">
<omgdi:waypoint x="400" y="120" />
<omgdi:waypoint x="530" y="120" />
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0iaccmi_di" bpmnElement="Flow_0iaccmi">
<omgdi:waypoint x="630" y="120" />
<omgdi:waypoint x="780" y="120" />
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0bax3n1_di" bpmnElement="Flow_0bax3n1">
<omgdi:waypoint x="880" y="120" />
<omgdi:waypoint x="1032" y="120" />
bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="StartEvent_1y45yut_di" bpmnElement="StartEvent_ops_coffee">
<omgdc:Bounds x="152" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="159" y="153" width="22" height="14" />
bpmndi:BPMNLabel>
bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0pih3d0_di" bpmnElement="Activity_0pih3d0">
<omgdc:Bounds x="300" y="80" width="100" height="80" />
bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_11xlozw_di" bpmnElement="Activity_11xlozw">
<omgdc:Bounds x="780" y="80" width="100" height="80" />
bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_07b4aeg_di" bpmnElement="Activity_07b4aeg">
<omgdc:Bounds x="530" y="80" width="100" height="80" />
bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_07dyz8d_di" bpmnElement="Event_07dyz8d">
<omgdc:Bounds x="1032" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="1039" y="145" width="22" height="14" />
bpmndi:BPMNLabel>
bpmndi:BPMNShape>
bpmndi:BPMNPlane>
bpmndi:BPMNDiagram>
definitions>
https://bpmn.ops-coffee.cn/#/bpmn-modeler
https://blog.csdn.net/qq_35664308/article/details/110469247
https://juejin.cn/post/6844904017567416328