前面的文章中说到过项目中有用到 BPMN Modeler
, 现在有个新页面要显示流程图,支持缩放、拖拽,高亮显示节点等功能,并且不能对流程图进行编辑。通过研究文档,发现可以用 NavigatedViewer
来显示流程图,并支持缩放拖拽,高亮显示节点参考这个例子 实现。
下面看具体的代码
// bpmn-viewer.component.ts
import { Component, Input, OnInit, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';
import { from, Observable } from 'rxjs';
import Viewer from 'camunda-bpmn-js/lib/camunda-cloud/NavigatedViewer';
@Input() diagramXML;
// 已经走过的箭头
@Input() passedArrows = [];
// 流程中报错的节点id
@Input() errorNode = [];
// 当前节点
@Input() currentNode = [];
// 需要设置 overlay 的节点
@Input() overlayNode = [];
// 是否高亮设置 overlay 所在的节点
@Input() ifHighlightOverlayNode = false;
private viewer: Viewer;
private elementRegistry;
private graphicsFactory;
constructor() {
this.viewer = new Viewer();
}
ngOnChanges(changes: SimpleChanges) {
if (changes.diagramXML) {
if (changes.diagramXML.currentValue) {
this.diagramXML = changes.diagramXML.currentValue;
this.importDiagram(this.diagramXML).subscribe(res => {
this.viewer.get('canvas').zoom('fit-viewport', 'auto');
this.elementRegistry = this.viewer.get('elementRegistry');
this.graphicsFactory = this.viewer.get('graphicsFactory');
this.overlays = this.viewer.get('overlays');
this.setArrowColor();
this.setOverlay();
});
}
}
}
ngOnInit(): void {
this.viewer = new Viewer({
container: '#canvas',
width: '100%',
height: '100%',
bpmnRenderer: {
// 设置默认的线条样式
// defaultFillColor: 'green',
// defaultStrokeColor: 'green'
}
});
}
private setArrowColor() {
this.passedArrows.map(item => {
const element = this.elementRegistry.get(item);
this.setColor(element, 'green');
});
}
private setCurrentNodeColor() {
this.currentNode.map(item => {
const element = this.elementRegistry.get(item);
this.setColor(element, 'green');
});
}
// 几个关键的函数
private setColor(element, color) {
// 设置线条颜色
element.di.set('stroke', color);
// 设置填充的颜色
// element.di.set('fill', fill);
const gfx = this.elementRegistry.getGraphics(element);
const type = element.waypoints ? 'connection' : 'shape';
this.graphicsFactory.update(type, element, gfx);
}
// 导入 xml
private importDiagram(xml: string): Observable<{ warnings: Array<any> }> {
return from(this.viewer.importXML(xml) as Promise<{ warnings: Array<any> }>);
}
// bpmn-viewer.component.html
<div class="diagram-container">
<div id="canvas" #canvas class="canvas"></div>
</div>
最终效果图如下