在angular中引入bpmn(1)【引入基礎bpmn】

因爲之前公司的angular項目中需要用到bpmn,網上教程不多,我是參照下面這個博主寫的教程才學會使用的:他寫的特別棒
BPMN-JS與Angular集成(1)
BPMN-JS與Angular集成(2)
BPMN-JS與Angular集成(3)
我這篇博客只能算自己總結學習筆記,在angular中引入bpmn的步驟:
按照下面的步驟操作,會出現左側的工具欄和右側的屬性欄

1、 首先在項目中使用兩個命令:

npm install bpmn-js
 npm install --save bpmn-js-properties-panel

2、在angular.json文件中的styles ,添加bpmn-js-properties-panel樣式 :

"styles": [
              "src/styles.less",
              "node_modules/bpmn-js/dist/assets/diagram-js.css",
              "node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css",
              "node_modules/bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css"
            ],

3、在需要用到bpmn的頁面HTML寫下一下代碼:

<div class="content with-diagram" id="js-drop-zone" style="height: 1600px;">    
    <div class="canvas" id="js-canvas"></div> 
       <div class="properties-panel-parent" id="js-properties-panel">
   </div>
</div>


<div class="modeler">
   <div id="canvas"></div>
 </div>
 <ul class="buttons">
   <li>
     <a id="js-download-diagram" href title="download BPMN diagram" class="active" (click)="saveDiagram($event)">
       BPMN diagram
     </a>
   </li>
   <li>
     <a id="js-download-svg" href title="download as SVG image" class="active" (click)="saveSVG($event)">
       SVG image
     </a>
   </li>
   <li *ngIf="saveHref">
     <a id="download" [href]="saveHref" [download]="saveName" class="active">下載</a>
   </li>
 </ul>

TS文件如下:
注意:在ts文件裏面有一句: const url = ‘…/…/…/assets/bpmn/newDiagram.bpmn’;
這個是存放的空白bpmn文件,根據自己存放書寫位置
注意:這個bpmn文件一定一定要放在assets下面

import propertiesPanelModule   from 'bpmn-js-properties-panel';
import propertiesProvider from 'bpmn-js-properties-panel/lib/provider/bpmn';
import BpmnModeler from 'bpmn-js/lib/Modeler.js';
import{HttpClient}from '@angular/common/http';
import { DomSanitizer } from '@angular/platform-browser';
constructor(
    private https: HttpClient,
     private sanitizer: DomSanitizer
) { }
ngOnInit() :void{
    this.initBpmn();
  }
  
  private modeler:any;
  saveHref;//下載是否出現
  saveName = '';

  initBpmn(){
    this.modeler = new BpmnModeler({
      container: '#js-canvas',
      width: '100%',
      height: '100%',
       propertiesPanel: {
        parent: '#js-properties-panel'
      },
      additionalModules: [
        propertiesProvider,
        propertiesPanelModule,
      ],
    });
    this.load();
  }
 
  load(): void {
    const url = '../../../assets/bpmn/newDiagram.bpmn';
    this.https.get(url, {
        headers: {observe: 'response'}, responseType: 'text'
    }).subscribe(
        (x: any) => {
            this.modeler.importXML(x, this.handleError);
        },
        this.handleError
    );
}
handleError(err: any) {
  if (err) {
      console.warn('Ups, error: ', err);
  }else {
    console.log('rendered:')
}
}
save(): void {
  this.modeler.saveXML((err: any, xml: any) => console.log('Result of saving XML: ', err, xml));
}
// 保存爲XML 
saveDiagram(e) {
  this.modeler.saveXML({format: true}, (err, xml) => {
      if (err) {
          console.error(err);
      } else {
          this.setEncoded(xml, 'bpmn.xml');
      }
  });
  e.preventDefault();
  e.stopPropagation();
}

// 保存爲svg
saveSVG(e) {
  this.modeler.saveSVG((err, svg) => {
      if (err) {
          console.error(err);
      } else {
          this.setEncoded(svg, 'bpmn.svg');
      }
  });
  e.preventDefault();
  e.stopPropagation();
}

setEncoded(data, name) {
  const encodedData = encodeURIComponent(data);
  if (data) {
      this.saveHref = this.sanitizer.bypassSecurityTrustResourceUrl('data:application/bpmn20-xml;charset=UTF-8,' + encodedData);
      this.saveName = name;
  }
}

bpmn文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  
<process id="LeaveProcess" name="BPMN業務流程建模與標註" isExecutable="true">
</process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_LeaveProcess">
    <bpmndi:BPMNPlane bpmnElement="LeaveProcess" id="BPMNPlane_LeaveProcess">
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

這個時候可能頁面無法顯示,原因是需要給bpmn一個寬和高:
樣式文件如下:

* {
    box-sizing: border-box;
  }
  
  body,
  html {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 12px;
    height: 100%;
    padding: 0;
    margin: 0;
  }
  
  a:link {
    text-decoration: none;
  }
  
  .content{
    display: flex;
  }
  .content>div {
    
    width: 100%;
    // width:200px;
    height: 100%;
  }
  
  .content>.message {
    text-align: center;
    display: table;
    font-size: 16px;
    color: #111;
  }
  
  .content>.message .note {
    vertical-align: middle;
    text-align: center;
    display: table-cell;
  }
  
  .content .error .details {
    max-width: 500px;
    font-size: 12px;
    margin: 20px auto;
    text-align: left;
  }
  
  .content .error pre {
    border: solid 1px #CCC;
    background: #EEE;
    padding: 10px;
  }
  
  .content:not(.with-error) .error,
  .content.with-error .intro,
  .content.with-diagram .intro {
    display: none;
    // height: 1000px;
  }
  
  .content .canvas,
  .content.with-error .canvas {
    visibility: hidden;
  }
  
  .content.with-diagram .canvas {
    visibility: visible;
    // height: 1000px;
  }
  
  .buttons {
    position: fixed;
    bottom: 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.0;
  }

我沒有按照上面這個css樣式寫,自己重新寫了一份,是下面這個樣式,我覺得比較好看也比較好操作。ts文件也做了小小的改動
在這裏插入圖片描述

修改後的HTML文件和樣式文件、ts文件如下:
HTML頁面

 <nz-select nzAllowClear nzPlaceHolder="下載類型" (ngModelChange)="saveUpload($event)" [(ngModel)]="selectedValue">
        <nz-option nzValue="xml" nzLabel="XML下載"></nz-option>
        <nz-option nzValue="svg" nzLabel="SVG下載"></nz-option>
    </nz-select>
    <a *ngIf="isdownload" id="download" [href]="saveHref" class="active" [download]="saveName">下載</a>

    <div nz-row class="content with-diagram" id="js-drop-zone" style="height:800px;">
        <div nz-col nzSpan="18" class="canvas" id="js-canvas"></div>
        <div nz-col nzSpan="6" class="properties-panel-parent" id="js-properties-panel"></div>
    </div>

樣式

* {
  box-sizing: border-box;
}

body,
html {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
  height: 100%;
  padding: 0;
  margin: 0;
}

a:link {
  text-decoration: none;
}

.content>.message {
  text-align: center;
  display: table;
  font-size: 16px;
  color: #111;
}

.content>.message .note {
  vertical-align: middle;
  text-align: center;
  display: table-cell;
}

.content .error .details {
  max-width: 500px;
  font-size: 12px;
  margin: 20px auto;
  text-align: left;
}

.content .error pre {
  border: solid 1px #CCC;
  background: #EEE;
  padding: 10px;
}

.content:not(.with-error) .error,
.content.with-error .intro,
.content.with-diagram .intro {
  display: flex; //控制屬性欄與右側有沒有間隙
  height: 1000px;
}

.content .canvas,
.content.with-error .canvas {
  visibility: hidden;
}

.content.with-diagram .canvas {
  visibility: inherit;
  height: 1000px;
}

// 控制左側工具欄的寬度
:host ::ng-deep .djs-palette.open {
  width: 100px !important;
}


// 下拉框的寬度
nz-select {
  margin: 8px;
  width: 120px;
}

import { Component, OnInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { HttpClient } from '@angular/common/http';
import propertiesPanelModule from 'bpmn-js-properties-panel';
import propertiesProvider from 'bpmn-js-properties-panel/lib/provider/bpmn';
import BpmnModeler from 'bpmn-js/lib/Modeler.js';
@Component({
  selector: 'app-system-bpmn',
  templateUrl: './bpmn.component.html',
  styleUrls: ['./bpmn.component.less']

})
export class SystemBpmnComponent implements OnInit {

  constructor(
    private https: HttpClient,
    private sanitizer: DomSanitizer) { }

  ngOnInit() {
    this.initBpmn();
  }
  private modeler: any;
  saveHref;//下載是否出現
  saveName = '';
  isdownload = false;
  selectedValue = null;
  saveXml;

  initBpmn() {
    this.modeler = new BpmnModeler({
      container: '#js-canvas',//js-canvas左側工具欄的id
      width: '100%',//畫板的大小
      height: '100%',
      propertiesPanel: {
        parent: '#js-properties-panel'
      },
      additionalModules: [
        propertiesProvider,//左側工具欄
        propertiesPanelModule,//右側屬性欄
      ],
    });
    this.load();
  }

  load(): void {
    const url = '../../../../assets/system-bpmn/blank/blank.bpmn';
    this.https.get(url, {
      headers: { observe: 'response' },
      responseType: 'text'
    }).subscribe(
      (x: any) => {
        this.modeler.importXML(x, this.handleError);
      },
      this.handleError
    );
  }
  handleError(err: any) {
    if (err) {
      console.warn('Ups, error: ', err);
    } else {
      console.log('rendered:')
    }
  }
  save(): void {
    this.modeler.saveXML((err: any, xml: any) =>
      this.saveXml = xml);
  }
  // 保存爲XML 
  saveDiagram(e) {
    this.modeler.saveXML({ format: true }, (err, xml) => {
      if (err) {
        console.error(err);
      } else {
        this.setEncoded(xml, 'bpmn.xml');
      }
    });
  }
  // e.preventDefault();//取消事件的默認動作
  // e.stopPropagation();//不再派發事件。

  // 保存爲svg
  saveSVG(e) {
    this.modeler.saveSVG((err, svg) => {
      if (err) {
        console.error(err);
      } else {
        this.setEncoded(svg, 'bpmn.svg');
      }
    });
    // e.preventDefault();//取消事件的默認動作
    // e.stopPropagation();//不再派發事件。
  }

  setEncoded(data, name) {
    // data是xml name是bpmn.xml
    const encodedData = encodeURIComponent(data);
    if (data) {
      this.saveHref = this.sanitizer.bypassSecurityTrustResourceUrl('data:application/bpmn20-xml;charset=UTF-8,' + encodedData);
      this.saveName = name;
    }
  }

  saveUpload(e) {
    console.log(e)
    if (e == 'xml') {
      this.isdownload = true;
      this.modeler.saveXML({ format: true }, (err, xml) => {
        if (err) {
          console.error(err);
        } else {
          this.setEncoded(xml, 'bpmn.xml');
        }
      });
      // e.preventDefault();//取消事件的默認動作
      // e.stopPropagation();//不再派發事件。
    }
    else if (e == 'svg') {
      this.isdownload = true;
      this.modeler.saveSVG((err, svg) => {
        if (err) {
          console.error(err);
        } else {
          this.setEncoded(svg, 'bpmn.svg');
        }
      });
      // e.preventDefault();//取消事件的默認動作
      // e.stopPropagation();//不再派發事件。
    }
    else {
      this.isdownload = false;
    }
  }
}

如果內容有什麼問題,歡迎大家指出,順便給我點個讚唄!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章