Bpmn.js的简单使用

Bpmn.js有两种功能:
(1)将XML格式字符串文件和.bpmn为后缀的文件转化为流程图。
(2)作为建模工具包,在网页上显示,绘制流程图。

一、将字符串转为流程图
安装
npm install --save bpmn-js
代码
<!--vue文件-->
<template>
  <div class="containers">
    <div class="canvas" ref="canvas"></div>
  </div>
</template>

<script>
// 引入相关的依赖
import BpmnModeler from 'bpmn-js/lib/Modeler'
import { xmlStr } from '../mock/xmlStr'//xml字符串文件
export default {
  name: '',
  components: {},
// 生命周期 - 创建完成(可以访问当前this实例)
  created() {},
// 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成,一般在该过程进行 Ajax 交互
  mounted() {
    this.init()
  },
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null
    }
  },
// 方法集合
  methods: {
    init () {
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas
      })
      this.createNewDiagram()
		},
		createNewDiagram () {
			// 将字符串转换成图显示出来
			this.bpmnModeler.importXML(xmlStr, (err) => {
				if (err) {
					// console.error(err)
				}
				else {
					// 这里是成功之后的回调, 可以在这里做一系列事情
					this.success()
                    console.log('success!');
                    // 让图能自适应屏幕
                    var canvas = bpmnJS.get('canvas')
                    canvas.zoom('fit-viewport')
				}
			})
		},
		success () {
			// console.log('创建成功!')
          
		}
  },
// 计算属性
  computed: {}
}
</script>

<style scoped>
.containers{
	background-color: #ffffff;
	width: 100%;
	height: calc(100vh - 52px);
}
.canvas{
	width: 100%;
	height: 100%;
}
.panel{
	position: absolute;
	right: 0;
	top: 0;
	width: 300px;
}
</style>

xml字符串文件格式
// js文件
export var xmlStr = `<?xml version="1.0" encoding="UTF-8"?>
<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_1y45yut" name="开始">
    <outgoing>SequenceFlow_0h21x7r</outgoing>
    </startEvent>
    <task id="Task_1hcentk">
    <incoming>SequenceFlow_0h21x7r</incoming>
    </task>
    <sequenceFlow id="SequenceFlow_0h21x7r" sourceRef="StartEvent_1y45yut" targetRef="Task_1hcentk" />
</process>
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
    <bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
    <bpmndi:BPMNShape id="StartEvent_1y45yut_di" bpmnElement="StartEvent_1y45yut">
        <omgdc:Bounds x="152" y="102" width="36" height="36" />
        <bpmndi:BPMNLabel>
        <omgdc:Bounds x="160" y="145" width="22" height="14" />
        </bpmndi:BPMNLabel>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape id="Task_1hcentk_di" bpmnElement="Task_1hcentk">
        <omgdc:Bounds x="240" y="80" width="100" height="80" />
    </bpmndi:BPMNShape>
    <bpmndi:BPMNEdge id="SequenceFlow_0h21x7r_di" bpmnElement="SequenceFlow_0h21x7r">
        <omgdi:waypoint x="188" y="120" />
        <omgdi:waypoint x="240" y="120" />
    </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>`
二、将.bpmn后缀的文件转化为流程图
安装
npm install --save bpmn-js
代码
<!--html文件-->
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    <style type="text/css">
        html, body, #canvas, #canvas > div {
            height: 100%;
        }
    </style>
    <!--
      this is an example of how to use bpmn-js in a standalone application built with
      CommonJS modules + browserify
      这是一个如何在一个独立的应用程序中使用bpmn-js的例子
      CommonJS模块+ browserify
    -->
    <title>npm/browserify example - bpmn-js-examples</title>
</head>
<body>
    <h1>Pizza Collaboration Viewer</h1>
    <div id="canvas"></div>
<script src="./app.bundled.js"></script><!--引入所需要的js文件-->
<script>
    // we use stringify to inline an example XML document
    import pizzaDiagram from './mock/diagram.bpmn';//bpmn文件
    import BpmnViewer from 'bpmn-js';
    var viewer = new BpmnViewer({
        container: '#canvas'
    });
    viewer.importXML(pizzaDiagram).then(function(result) {
        const { warnings } = result;
        console.log('success !', warnings);
        // 让图能自适应屏幕
        viewer.get('canvas').zoom('fit-viewport');
    }).catch(function(err) {
        const { warnings, message } = err;
        console.log('something went wrong:', warnings, message);
    });
</script>
</body>
</html>

app.bundled.js文件
文件较大,已上传到我的资源,点击下方链接免费下载

资源链接地址

diagram.bpmn文件
<!-- bpmn文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<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="9.0.0-alpha.2">
  <process id="Process_1" isExecutable="false">
    <startEvent id="StartEvent_1y45yut" name="hunger noticed">
      <outgoing>SequenceFlow_0h21x7r</outgoing>
    </startEvent>
    <task id="Task_1hcentk" name="choose recipe">
      <incoming>SequenceFlow_0h21x7r</incoming>
      <outgoing>SequenceFlow_0wnb4ke</outgoing>
      <outgoing>Flow_0vb2qdm</outgoing>
    </task>
    <sequenceFlow id="SequenceFlow_0h21x7r" sourceRef="StartEvent_1y45yut" targetRef="Task_1hcentk" />
    <exclusiveGateway id="ExclusiveGateway_15hu1pt" name="desired dish?">
      <incoming>SequenceFlow_0wnb4ke</incoming>
    </exclusiveGateway>
    <sequenceFlow id="SequenceFlow_0wnb4ke" sourceRef="Task_1hcentk" targetRef="ExclusiveGateway_15hu1pt" />
    <sequenceFlow id="Flow_0vb2qdm" sourceRef="Task_1hcentk" targetRef="Activity_1vmikw3" />
    <endEvent id="Event_0rjtki8">
      <incoming>Flow_1uq72u0</incoming>
    </endEvent>
    <sequenceFlow id="Flow_1uq72u0" sourceRef="Activity_1vmikw3" targetRef="Event_0rjtki8" />
    <sendTask id="Activity_1vmikw3">
      <incoming>Flow_0vb2qdm</incoming>
      <outgoing>Flow_1uq72u0</outgoing>
    </sendTask>
  </process>
  <bpmndi:BPMNDiagram id="BpmnDiagram_1">
    <bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
      <bpmndi:BPMNEdge id="SequenceFlow_0wnb4ke_di" bpmnElement="SequenceFlow_0wnb4ke">
        <omgdi:waypoint x="340" y="120" />
        <omgdi:waypoint x="395" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="SequenceFlow_0h21x7r_di" bpmnElement="SequenceFlow_0h21x7r">
        <omgdi:waypoint x="188" y="120" />
        <omgdi:waypoint x="240" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0vb2qdm_di" bpmnElement="Flow_0vb2qdm">
        <omgdi:waypoint x="340" y="120" />
        <omgdi:waypoint x="370" y="120" />
        <omgdi:waypoint x="370" y="230" />
        <omgdi:waypoint x="400" y="230" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1uq72u0_di" bpmnElement="Flow_1uq72u0">
        <omgdi:waypoint x="500" y="230" />
        <omgdi:waypoint x="562" y="230" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="StartEvent_1y45yut_di" bpmnElement="StartEvent_1y45yut">
        <omgdc:Bounds x="152" y="102" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <omgdc:Bounds x="134" y="145" width="73" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Task_1hcentk_di" bpmnElement="Task_1hcentk">
        <omgdc:Bounds x="240" y="80" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="ExclusiveGateway_15hu1pt_di" bpmnElement="ExclusiveGateway_15hu1pt" isMarkerVisible="true">
        <omgdc:Bounds x="395" y="95" width="50" height="50" />
        <bpmndi:BPMNLabel>
          <omgdc:Bounds x="388" y="152" width="65" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_0rjtki8_di" bpmnElement="Event_0rjtki8">
        <omgdc:Bounds x="562" y="212" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_05uvuhz_di" bpmnElement="Activity_1vmikw3">
        <omgdc:Bounds x="400" y="190" width="100" height="80" />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

三、搭建建模工具包
安装
npm install --save bpmn-js
如需要使用右侧的属性栏就得安装上一个名为bpmn-js-properties-panel的插件了.
npm i bpmn-js-properties-panel --save-D
代码
<!--vue文件-->
<template>
  <div class="containers" ref="content">
    <div class="canvas" ref="canvas"></div>
    <div id="js-properties-panel" class="panel"></div>
  </div>
</template>

<script>
// 引入相关的依赖
import BpmnViewer from 'bpmn-js';
import BpmnModeler from 'bpmn-js/lib/Modeler'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import propertiesPanelModule from 'bpmn-js-properties-panel'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import { xmlStr } from '../mock/xmlStr'
export default {
  name: '',
  components: {},
// 生命周期 - 创建完成(可以访问当前this实例)
  created() {},
// 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成,一般在该过程进行 Ajax 交互
  mounted() {
    this.init()
  },
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null
    }
  },
// 方法集合
  methods: {
    init () {
      // 获取到属性ref为“content”的dom节点
      this.container = this.$refs.content
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        //添加控制板
        propertiesPanel: {
          parent: '#js-properties-panel'
        },
        additionalModules: [
          // 左边工具栏以及节点
          propertiesProviderModule,
          // 右边的工具栏
          propertiesPanelModule
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      })
      this.createNewDiagram()
    },
    createNewDiagram () {
      // 将字符串转换成图显示出来
      this.bpmnModeler.importXML(xmlStr, (err) => {
        if (err) {
          // console.error(err)
        }
        else {
          // 这里是成功之后的回调, 可以在这里做一系列事情
          this.success()
        }
      })
    },
    success () {
      console.log('success!');
      // 让图能自适应屏幕
      var canvas = BpmnViewer.get('canvas')
      canvas.zoom('fit-viewport')
    }
  },
// 计算属性
  computed: {}
}
</script>

<style scoped>
.containers{
  background-color: #ffffff;
  width: 100%;
  height: calc(100vh - 52px);
}
.canvas{
  width: 100%;
  height: 100%;
}
.panel{
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
}
</style>

同时在main.js文件中需要添加bpmn工作流绘图工具

// 以下为bpmn工作流绘图工具的样式
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'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
// 右边工具栏样式
import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'
四、注意
html文件可以直接访问,vue文件需要在router文件中配置路由即可访问。(vue格式的有时也可以写成html的样式)

此文借鉴自全网最详bpmn.js教材-基础篇

Logo

前往低代码交流专区

更多推荐