vue中使用bpmn.js预览流程图,自适应父元素尺寸显示,设置已完成步骤高亮颜色,放大缩小功能

在vue项目中使用bpmn.js,显示后端获取到的xml流程图数据,对特殊步骤设置高亮颜色,流程图放大缩小功能

我遇到的问题主要是初始化时图片的尺寸很小,后来在创建canvas的时候给他一个高度就解决了,还有一个自定义高亮样色无效的问题,是因为vue中style使用了scope导致的,使用>>>解决的。其实在vue项目中大多数的ui框架修改样式无效多半是scope影响的,使用深度选择器就可以解决。
1.安装bpmn.js,运行npm install --save bpmn-js,
2.在需要使用bpmn.js的页面引入bpmn-js的组件,需要编辑就引入Modeler,如果只需要预览就引入Viewer就可以。
3.上代码,代码中对关键部分和需要注意的地方都作了注释。

<template>
  <div class="main-box">
    <el-button type="success"
               size="small"
               @click="handleZoom(0.2)">放大</el-button>
    <el-button type="warning"
               size="small"
               @click="handleZoom(-0.2)">缩小</el-button>
    <div class="canvas"
         ref="canvas"></div>
  </div>
</template>

<script>
// 这里只需要预览引入Viewer就可以,如果需要编辑则引入"bpmn-js/lib/Modeler",并且还需要引入左侧编辑栏panel等
import BpmnViewer from "bpmn-js/lib/Viewer";
export default {
  data() {
    return {
      bpmnViewer: null,
      scale: 1,
      xmlUrl: '<?xml version="1.0" encoding="UTF-8"?>\n<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:bioc="http://bpmn.io/schema/bpmn/biocolor/1.0" id="Definitions_0niqij2" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">\n  <bpmn:collaboration id="TEST1">\n    <bpmn:participant id="Participant_1cvrbkh" name="测试2" processRef="TEST2" />\n  </bpmn:collaboration>\n  <bpmn:process id="TEST2" name="测试 2" isExecutable="true">\n    <bpmn:laneSet id="LaneSet_1c6qhor">\n      <bpmn:lane id="Lane_06s1mba" name="sdfsd">\n        <bpmn:flowNodeRef>Activity_1d2rrr0</bpmn:flowNodeRef>\n        <bpmn:flowNodeRef>StartEvent_1</bpmn:flowNodeRef>\n      </bpmn:lane>\n      <bpmn:lane id="Lane_103btcx" name="sdfsd">\n        <bpmn:flowNodeRef>Activity_1d2wp4b</bpmn:flowNodeRef>\n        <bpmn:flowNodeRef>Event_0a8jrau</bpmn:flowNodeRef>\n      </bpmn:lane>\n    </bpmn:laneSet>\n    <bpmn:userTask id="Activity_1d2rrr0" name="ddd" camunda:formKey="form1" camunda:assignee="yang">\n      <bpmn:extensionElements>\n        <camunda:inputOutput>\n          <camunda:inputParameter name="Input_1" />\n          <camunda:outputParameter name="Output_1">aaa</camunda:outputParameter>\n        </camunda:inputOutput>\n        <camunda:formData>\n          <camunda:formField id="id" label="iddd" type="string" defaultValue="2" />\n        </camunda:formData>\n      </bpmn:extensionElements>\n      <bpmn:incoming>Flow_0gr7pas</bpmn:incoming>\n      <bpmn:outgoing>Flow_1ayl0cy</bpmn:outgoing>\n    </bpmn:userTask>\n    <bpmn:startEvent id="StartEvent_1">\n      <bpmn:outgoing>Flow_0gr7pas</bpmn:outgoing>\n    </bpmn:startEvent>\n    <bpmn:userTask id="Activity_1d2wp4b" name="dfdsfds" camunda:assignee="ddd">\n      <bpmn:incoming>Flow_1ayl0cy</bpmn:incoming>\n      <bpmn:outgoing>Flow_1gvp9xx</bpmn:outgoing>\n    </bpmn:userTask>\n    <bpmn:endEvent id="Event_0a8jrau">\n      <bpmn:incoming>Flow_1gvp9xx</bpmn:incoming>\n    </bpmn:endEvent>\n    <bpmn:sequenceFlow id="Flow_0gr7pas" sourceRef="StartEvent_1" targetRef="Activity_1d2rrr0" />\n    <bpmn:sequenceFlow id="Flow_1ayl0cy" sourceRef="Activity_1d2rrr0" targetRef="Activity_1d2wp4b" />\n    <bpmn:sequenceFlow id="Flow_1gvp9xx" sourceRef="Activity_1d2wp4b" targetRef="Event_0a8jrau" />\n  </bpmn:process>\n  <bpmndi:BPMNDiagram id="BPMNDiagram_1">\n    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="TEST1">\n      <bpmndi:BPMNShape id="Participant_1cvrbkh_di" bpmnElement="Participant_1cvrbkh" isHorizontal="true">\n        <dc:Bounds x="152" y="80" width="838" height="510" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNShape id="Lane_103btcx_di" bpmnElement="Lane_103btcx" isHorizontal="true">\n        <dc:Bounds x="182" y="370" width="808" height="220" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNShape id="Lane_06s1mba_di" bpmnElement="Lane_06s1mba" isHorizontal="true">\n        <dc:Bounds x="182" y="80" width="808" height="290" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNEdge id="Flow_1gvp9xx_di" bpmnElement="Flow_1gvp9xx">\n        <di:waypoint x="640" y="500" />\n        <di:waypoint x="732" y="500" />\n      </bpmndi:BPMNEdge>\n      <bpmndi:BPMNEdge id="Flow_1ayl0cy_di" bpmnElement="Flow_1ayl0cy">\n        <di:waypoint x="590" y="277" />\n        <di:waypoint x="590" y="460" />\n      </bpmndi:BPMNEdge>\n      <bpmndi:BPMNEdge id="Flow_0gr7pas_di" bpmnElement="Flow_0gr7pas" bioc:stroke="rgb(142, 36, 170)" bioc:fill="rgb(225, 190, 231)">\n        <di:waypoint x="308" y="237" />\n        <di:waypoint x="540" y="237" />\n      </bpmndi:BPMNEdge>\n      <bpmndi:BPMNShape id="Activity_04admi2_di" bpmnElement="Activity_1d2rrr0" bioc:stroke="rgb(30, 136, 229)" bioc:fill="rgb(187, 222, 251)">\n        <dc:Bounds x="540" y="197" width="100" height="80" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1" bioc:stroke="rgb(67, 160, 71)" bioc:fill="rgb(200, 230, 201)">\n        <dc:Bounds x="272" y="219" width="36" height="36" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNShape id="Activity_0gs7hci_di" bpmnElement="Activity_1d2wp4b" bioc:stroke="rgb(0, 0, 0)" bioc:fill="rgb(255, 205, 210)">\n        <dc:Bounds x="540" y="460" width="100" height="80" />\n      </bpmndi:BPMNShape>\n      <bpmndi:BPMNShape id="Event_0a8jrau_di" bpmnElement="Event_0a8jrau">\n        <dc:Bounds x="732" y="482" width="36" height="36" />\n      </bpmndi:BPMNShape>\n    </bpmndi:BPMNPlane>\n  </bpmndi:BPMNDiagram>\n</bpmn:definitions>\n',  // 从接口获取的xml文件
    };
  },
  watch: {},
  created() {
    this.getImg();
  },
  methods: {
    getImg() {
      // 初始时清除图层
      this.bpmnViewer && this.bpmnViewer.destroy();
      this.$refs.canvas.innerHTML = "";
      this.scale = 1; // 放大缩小比例
      // 初始化canvas
      this.bpmnViewer = new BpmnViewer({
        container: this.$refs.canvas,
        height: 540, // 根据实际情况设置高度,宽度的话设置父元素的宽度就可以,会自适应的
      });
      const self = this;
      const bpmnXmlStr = this.xmlUrl; // 从接口获取的xml文件
      this.bpmnViewer.importXML(bpmnXmlStr, function (err) {
        if (err) {
          console.error(err);
        } else {
          let canvas = self.bpmnViewer.get("canvas");
          canvas.zoom("fit-viewport", "auto");
          // nodeCodes为需要设置高亮颜色的部分的id的集合(xml文件中<flowNodeRef>****</flowNodeRef>标签里的部分),这个数据也是从接口获取,这里从xml中随便取出几个测试用
          let nodeCodes = [
            "Activity_1d2rrr0",
            "StartEvent_1",
            "Activity_1d2wp4b",
          ];
          // 调用设置高亮颜色class方法,这里可以根据接口获取的id集合情况,对不同的部分设置不同的class名,然后在css中设置样式
          self.setNodeColor(nodeCodes, "nodeSuccess", canvas);
        }
      });
    },
    // 设置高亮颜色的class
    setNodeColor(nodeCodes, colorClass, canvas) {
      for (let i = 0; i < nodeCodes.length; i++) {
        canvas.addMarker(nodeCodes[i], colorClass);
      }
    },
    // 放大缩小,这里尽量设置flag的值小一点,这样每次放大缩小不会很多,避免放大超出父元素
    handleZoom(flag) {
      // 放大缩小倍数flag可以自行设置
      if (flag < 0 && this.scale <= 1) {
        return;
      }
      this.scale += flag;
      this.$nextTick(() => {
        this.bpmnViewer.get("canvas").zoom(this.scale);
      });
    },
  },
};
</script>

<style scoped lang="scss">
.canvas {
  margin: 10px;
}
>>> .nodeSuccess:not(.djs-connection) {
  .djs-visual {
    > :nth-child(1) {
      stroke: #f70e0e !important;
      stroke-width: 3px !important;
    }
  }
}
</style>

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,下面是Vue3整合bpmn.js实现flowable流程设计器的代码实现。 首先,需要安装依赖: ``` npm install bpmn-js@8.0.1 npm install bpmn-js-properties-panel@0.44.0 npm install bpmn-js-properties-panel-provider@0.23.0 npm install camunda-bpmn-moddle@6.2.0 npm install vue-bpmn ``` 接着,在Vue组件引入需要的文件: ```javascript import BpmnModeler from 'bpmn-js/lib/Modeler'; import propertiesPanelModule from 'bpmn-js-properties-panel'; import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'; import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'; import 'bpmn-js-properties-panel/styles/properties.less'; import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'; ``` 然后,在Vue组件定义bpmn.js的Modeler和其他必要的变量: ```javascript data() { return { bpmnModeler: null, propertiesPanel: null, xml: null, }; }, ``` 接下来,在Vue组件的mounted生命周期函数初始化bpmn.js的Modeler和其他必要的变量: ```javascript mounted() { this.bpmnModeler = new BpmnModeler({ container: '#canvas', propertiesPanel: { parent: '#properties', }, additionalModules: [ propertiesPanelModule, propertiesProviderModule, ], moddleExtensions: { camunda: camundaModdleDescriptor, }, }); this.propertiesPanel = this.bpmnModeler.get('propertiesPanel'); }, ``` 然后,在Vue组件的methods定义一些必要的方法,比如打开一个流程图、保存一个流程图、导出一个流程图: ```javascript methods: { openDiagram(xml) { this.bpmnModeler.importXML(xml, (err) => { if (err) { console.log(err); } else { console.log('success'); } }); }, saveDiagram() { this.bpmnModeler.saveXML({ format: true }, (err, xml) => { if (err) { console.log(err); } else { console.log(xml); } }); }, exportDiagram() { this.bpmnModeler.saveSVG((err, svg) => { if (err) { console.log(err); } else { console.log(svg); } }); }, }, ``` 最后,在Vue组件的template定义UI界面: ```html <template> <div> <div id="canvas"></div> <div id="properties"></div> <button @click="saveDiagram">保存</button> <button @click="exportDiagram">导出</button> </div> </template> ``` 在这个例子,我们使用Vue3和bpmn.js来实现了flowable流程设计器。通过这个例子,你可以了解到如何在Vue3整合bpmn.js以及如何定义UI界面、打开、保存和导出流程图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值