vue里使用bpmn绘制流程图(一)

bpmn是比较方便的绘制流程图的插件,官方demo https://github.com/bpmn-io/bpmn-js-examples

安装

1.HTML中使用,通过script标签引入


2.npm安装bpmn-js

npm install bpmn-js
npm install bpmn-js-properties-panel //节点信息编辑面板


使用

1.HTML中使用

var bpmnModeler = new BpmnJS({
        container: '#canvas',
        keyboard: {
          bindTo: window
        }
      });

2.vue页面引入并使用bpmn

import BpmnModdle from 'bpmn-js'; //默认入口是Viewer.js文件,只有预览流程图的功能;

import BpmnModdle from 'bpmn-js/lib/Modeler'; //如果手动引入bpmn-js/lib/Modeler,则具备左侧工具栏,可以编辑流程图
<template>
	<div style="">
		<div id="js-canvas"></div>
		<div id="js-properties-panel"></div>
		<div>
			<a-button @click="download">保存到本地</a-button>
			<button @click="createNew">新建</button>
		</div>
		<!-- <a-modal></a-modal> -->
	</div>
</template>
<script>
import BpmnModdle from 'bpmn-js/lib/Modeler';
import diagramXml from '../../../assets/diagram.bpmn'; //xml文件
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';

export default {
	name: 'bpmn',
	data() {
		return {
			viewer: null,
			canvas: null,
			bpmnText: '',
		}
	},
	mounted() {
		this.$nextTick().then(() => {

			this.canvas = document.getElementById('js-canvas')

			this.viewer = new BpmnModdle({
				container: this.canvas,
				keyboard: {
					bindTo: window
				},
				propertiesPanel: {
					parent: '#js-properties-panel'
				},
				additionalModules: [
					propertiesProviderModule
				]
			})
			this.create()
		})
	},
	methods: {
		download() {
			this.viewer.saveXML({ format: true }, (err, xml) => {
				if (xml) {
					this.bpmnText = xml
					var a = document.createElement('a');
					a.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodeURIComponent(xml)
					a.download = 'diagram.bpmn';
					document.body.appendChild(a);
					a.click();
					document.body.removeChild(a);
					a = null;
				}

			})
		},
		create() {
			this.bpmnText = diagramXml
			this.viewer.importXML(diagramXml, err => {
				if (err) {
					throw (err)
				}
				this.viewer.get('canvas').zoom('fit-viewport')
				var eventBus = this.viewer.get('eventBus');

				var events = [
					'element.click',
					'element.dblclick'
				]
				events.forEach(event => {
					eventBus.on(event, (e) => {
					})
				})
			})

		},
		createNew() {
			this.viewer.createDiagram(err => {
				if (err) {
					throw (err)
				}
				this.viewer.get('canvas').zoom('fit-viewport')
				var eventBus = this.viewer.get('eventBus');

				var events = [
					'element.click',
					'element.dblclick'
				]
				events.forEach(event => {
					eventBus.on(event, (e) => {
						// console.log(event, 'on', e.element.id)
					})
				})
			})
		}
	}
}
</script>
<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';
</style>

vue里使用bpmn绘制流程图(一)_第1张图片
左侧是节点选择区域,点击图标后,鼠标移动到右侧画布区域,点击后绘制图形;

点击图形节点,右侧弹出节点详细信息,可以对节点信息进行编辑, 如下图:
vue里使用bpmn绘制流程图(一)_第2张图片

源码分析

以上功能主要通过Modeler来实现

1.新建Modeler实例

import BpmnModdle from 'bpmn-js/lib/Modeler';
var viewer = new 

2.创建空白新流程图

//Modeler继承自Viewer
//importXML定义在Viewer中
var initialDiagram =
  '' +
  ' +
                    '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" ' +
                    'targetNamespace="http://bpmn.io/schema/bpmn" ' +
                    'id="Definitions_1">' +
    '' +
      '' +
    '' +
    '' +
      '' +
        '' +
          '' +
        '' +
      '' +
    '' +
  '';
Modeler.prototype.createDiagram = function(done) {
  return this.importXML(initialDiagram, done);
};

3.创建指定流程图

//需要传入项xml: 流程图xml字符串  回调方法,创建完成后调用
Viewer.prototype.importXML = function(xml, bpmnDiagram, done) {
  if (isFunction(bpmnDiagram)) {
    done = bpmnDiagram;
    bpmnDiagram = null;
  }

  // done is optional
  done = done || function() {};

  ...//新建流程图操作

};

4.保存xml

//由源码可知,调用saveXML即可保存, 需要传入回调done,done里会传入参数保存后的xml内容。根据实际需要对xml进行处理
Viewer.prototype.saveXML = function(options, done) {

  if (!done) {
    done = options;
    options = {};
  }

  var self = this;

 ...

  this._moddle.toXML(definitions, options, function(err, xml) {

    try {
      xml = self._emit('saveXML.serialized', {
        error: err,
        xml: xml
      }) || xml;

      self._emit('saveXML.done', {
        error: err,
        xml: xml
      });
    } catch (e) {
      console.error('error in saveXML life-cycle listener', e);
    }

    done(err, xml); //生成的xml会传入回调方法
  });
};

5.保存为svg

//跟保存为xml操作一样,生成的svg信息会返回给回调,在回调里进行处理即可
Viewer.prototype.saveSVG = function(options, done) {

  if (!done) {
    done = options;
    options = {};
  }

  this._emit('saveSVG.start');

  var svg, err;

  try {
    var canvas = this.get('canvas');

    var contentNode = canvas.getDefaultLayer(),
        defsNode = domQuery('defs', canvas._svg);

    var contents = innerSVG(contentNode),
        defs = defsNode ? '' + innerSVG(defsNode) + '' : '';

    var bbox = contentNode.getBBox();

    svg =
      '\n' +
      '\n' +
      '\n' +
      ' +
           'width="' + bbox.width + '" height="' + bbox.height + '" ' +
           'viewBox="' + bbox.x + ' ' + bbox.y + ' ' + bbox.width + ' ' + bbox.height + '" version="1.1">' +
        defs + contents +
      '';
  } catch (e) {
    err = e;
  }

  this._emit('saveSVG.done', {
    error: err,
    svg: svg
  });

  done(err, svg);
};

详细见 https://github.com/haoyanyu/vue-with-bpmn

你可能感兴趣的:(日常总结,Vue)