vue项目中绘制bpmn流程图

作者: 伴歌知行 | 来源:发表于2020-06-06 09:55 被阅读0次

    最近有个需求:在项目中绘制bpmn流程图,使用的插件是:bpmn-js
    实现的效果如下图所示

    image.png

    安装 bpmn-js

    npm install bpmn-js
    

    安装节点属性面板

    npm install bpmn-js-properties-panel
    

    新建vue单文件

    下面是html部分,注意楼主使用了element-ui的按钮组件,没有用element-ui的童鞋自行修改

    <template>
      <div class="work-flow-container">
        <div class="work-flow-canvas" id="workFlowCanvas"></div>
        <div class="properties-panel-parent" id="js-properties-panel"></div>
        <div class="buttons">
          <input type="file" ref="fileInput" v-show="false" accept=".bpmn" @change="getFile">
          <el-button icon="el-icon-folder-opened" type="primary" plain @click="openDiagram">打开bpmn文件</el-button>
          <el-button icon="el-icon-download" type="primary" plain @click="saveDiagram">BPMN diagram</el-button>
          <el-button icon="el-icon-picture" type="primary" plain @click="saveSvg">SVG图片</el-button>
        </div>
      </div>
    </template>
    

    在script中引入bpmn流程图和节点属性面板

    // 引入流程图
    import Modeler from "bpmn-js/lib/Modeler";
    // 引入节点属性面板
    import propertiesPanelModule from "bpmn-js-properties-panel";
    import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
    

    在mounted时创建bpmn实例,创建后新增流程定义,定义的方法写在methods里

    <script>
    // 引入流程图
    import Modeler from "bpmn-js/lib/Modeler";
    // 引入节点属性面板
    import propertiesPanelModule from "bpmn-js-properties-panel";
    import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
    
    export default {
      data() {
        return {
          modeler: null
        };
      },
      methods: {
        // 返回
        goBack() {
          this.$router.go(-1);
        },
        // 新增流程定义
        createNewDiagram() {
          // 自定义的xml模板,可以自己修改
          const diagramXML = `
                <?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="6.5.1">
                <process id="Process_1" name="流程" 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:BPMNEdge id="SequenceFlow_0h21x7r_di" bpmnElement="SequenceFlow_0h21x7r">
                        <omgdi:waypoint x="188" y="120" />
                        <omgdi:waypoint x="240" y="120" />
                    </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:BPMNPlane>
                </bpmndi:BPMNDiagram>
                </definitions>
            `;
          // 在实例中导入xml
          this.modeler.importXML(diagramXML, function(err) {
            if (err) {
              console.error(err);
            }
          });
        }
    //
    //
    //
    //
      },
      mounted() {
        // 生成实例
        this.modeler = new Modeler({
          container: "#workFlowCanvas",
          propertiesPanel: {
            parent: "#js-properties-panel"
          },
          additionalModules: [propertiesPanelModule, propertiesProviderModule]
        });
        // 新增流程定义
        this.createNewDiagram();
      }
    };
    </script>
    

    在style中引入bpmn的样式文件

    <style>
    /*左边工具栏以及编辑节点的样式*/
    @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";
    .work-flow-container {
      position: absolute;
      background-color: #ffffff;
      width: 100%;
      height: 100%;
    }
    .work-flow-canvas {
      width: 100%;
      height: 100%;
    }
    .bjs-powered-by {
      display: none;
    }
    .buttons {
      position: fixed;
      bottom: 20px;
      left: 20px;
    
      padding: 0;
      margin: 0;
      list-style: none;
    }
    
    .buttons > li {
      display: inline-block;
      margin-right: 10px;
    }
    .buttons > li > a {
      background: #ddd;
      border: solid 1px #666;
      display: inline-block;
      padding: 5px;
    }
    
    .buttons a {
      opacity: 0.3;
    }
    
    .buttons a.active {
      opacity: 1;
    }
    .properties-panel-parent {
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      width: 260px;
      z-index: 10;
      border-left: 1px solid #ccc;
      overflow: auto;
    }
    
    .properties-panel-parent:empty {
      display: none;
    }
    .properties-panel-parent > .djs-properties-panel {
      padding-bottom: 70px;
      min-height: 100%;
    }
    </style>
    

    楼主在项目中也加上了导入本地bpmn文件功能,下面方法写在methods中

        // 打开本地文件,调用input的click事件
        openDiagram() {
          this.$refs.fileInput.click();
        },
        // 打开本地文件
        getFile(e) {
          this.fileList = e.target.files || [];
          if (this.fileList.length === 0) {
            return false;
          } else {
            let file = this.fileList[0];
            // FileReader对象读取选择的本地文件
            let reader = new FileReader();
            let _this = this;
            reader.onload = function(e) {
              let xml = e.target.result;
              // 在bpmn实例中导入该本地文件
              _this.modeler.importXML(xml, function(err) {
                if(err) {
                  console.error(err);
                }
              })
            }
            reader.readAsText(file);
          }
        },
    

    同时楼主在项目中也加上了下载bpmn文件和svg图片的功能,下面方法写在methods中

        // 下载
        setEncoded(name, data) {
          // 将xml或svg作为 URI 组件进行编码
          let encodedData = encodeURIComponent(data);
          // 创建a链接进行下载
          if (data) {
            let a = document.createElement("a");
            a.download = name;
            a.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
            a.click();
          }
        },
        // 下载bpmn
        saveDiagram() {
          const _this = this;
          this.modeler.saveXML({ format: true }, function(err, xml) {
            _this.setEncoded("diagram.bpmn", err ? null : xml);
          });
        },
        // 下载svg
        saveSvg() {
          const _this = this;
          this.modeler.saveSVG(function(err, svg) {
            _this.setEncoded("diagram.svg", err ? null : svg);
          });
        }
    

    相关文章

      网友评论

        本文标题:vue项目中绘制bpmn流程图

        本文链接:https://www.haomeiwen.com/subject/myfgahtx.html