当前位置: 移动技术网 > IT编程>开发语言>JavaScript > vue项目中使用bpmn-基础篇

vue项目中使用bpmn-基础篇

2020年05月12日  | 移动技术网IT编程  | 我要评论

内容概述

本系列“vue项目中使用bpmn-xxxx”分为七篇,均为自己使用过程中用到的实例,手工原创,目前陆续更新中。主要包括vue项目中bpmn使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。如果转载或通过爬虫直接爬的,格式特别丑,请来原创看:

前情提要

经过前四篇的学习,我们能够实现bpmn基本绘图、预览、为节点加事件加颜色等效果,这一篇我们来说,如何自定义左侧工具栏(platter),首先看一下自定义前后效果图对比:

我们本次要实现的目标:基于左侧platter原有元素类型,创建出一个新的自定义节点。暂且叫它“草莓蛋糕”节点,类型是 bpmn:task, 样式我们自己找一个好看的小草莓蛋糕图案。所以,开动吧~首先新建一个“custompalette”文件夹,里面放我们今天所有自定义的文件。

步骤1:建立platter类函数,命名为custompalette.js

export default class custompalette {
  constructor(create, elementfactory, palette) {
    this.create = create;
    this.elementfactory = elementfactory;
    palette.registerprovider(this);
  }
 
 
  // 这个是绘制palette的核心,函数名不要变
  getpaletteentries() {
    const elementfactory = this.elementfactory;
    const create = this.create;
 
    function drageventfactory(type) {
      return function (event) {
        const taskshape = elementfactory.create('shape', {
          type: type
        });
        create.start(event, taskshape);
      };
    }
 
    return {
      'create.cake': {
        title: '我是自定义节点-草莓蛋糕',    // 鼠标悬浮到节点上显示的文字
        classname: 'icon-custom bpmn-icon-cake',   // 样式名
        action: {      // 操作该节点时会触发的事件,此时只注册一个拖动事件即可,否则拖动时没有效果
          dragstart: drageventfactory('bpmn:task')
        }
      }
    };
  }
}
custompalette.$inject = [
  'create',
  'elementfactory',
  'palette'
];

此时,我们已经注册好了一个名称为“create.cake”的节点,拖动它时,画布中会出现一个"bpmn:task"类型的节点,此时需要将该文件导出并在页面中引入,否则没有效果。

步骤2:在custompalette.js同级,建立一个index.js文件将其导出

import custompalette from './custompalette';
export default {
  __init__: ['custompalette']
  custompalette: ['type', custompalette],
};

步骤3:页面中(index.vue)引入index.js

import custommodule from './custompalette';
export default {
  mounted() {
    this.containerel = document.getelementbyid('container');
    this.bpmnmodeler = new bpmnmodeler({
       additionalmodules: [ custommodule ]
    });
}

步骤4:为节点定义样式

新建一个custompalette.scss文件,在该文件同级放一张“cake.png”的图片,作为节点的背景图写入。背景图引入的话,貌似只支持.png格式,亲测:jpg报错

.bpmn-icon-cake {
  background-image: url('./cake.png');
}
 
.icon-custom {
  background-size: 65%;
  background-repeat: no-repeat;
  background-position: center center;
}

并且在main.js中引入,注意,一定要在main.js中全局引入,否则不生效。

import 'custompalette/custompalette.scss';

此时,我们便可以在左侧工具栏中看到自定义的“草莓蛋糕”节点了,但是此时拖动该节点,右侧只会产生一个“bpmn:task”的节点,只有一个框框。

我们希望的是,拖动后画布中也显示自定义图标,所以我们进行下一步:自定义渲染

步骤5:画布渲染自定义节点

此时需要我们新建一个 customrenderer.js文件,作用:自定义 renderer。因为我们是在bpmn原有的元素“bpmn:task”基础上进行修改,所以我们需要对将baserenderer进行继承。

import baserenderer from 'diagram-js/lib/draw/baserenderer'; // 引入默认的renderer
 
const high_priority = 1500; // 最高优先级
 
export default class customrenderer extends baserenderer {
  // 继承baserenderer
  constructor(eventbus, bpmnrenderer) {
    super(eventbus, high_priority);
    this.bpmnrenderer = bpmnrenderer;
  }
 
  canrender(element) {
    return !element.labeltarget;
  }
 
  drawshape(parentnode, element) {
    const shape = this.bpmnrenderer.drawshape(parentnode, element);
    return shape;
  }
 
  getshapepath(shape) {
    return this.bpmnrenderer.getshapepath(shape);
  }
}
 
customrenderer.$inject = ['eventbus', 'bpmnrenderer'];

此时, customrenderer.js文件大概结构完成了,注意:high_priority变量和canrender不可以删掉,否则会有问题。重头戏是里面的drawshape函数。

步骤6:书写drawshape函数

我们在customrenderer.js同级建立一个util文件,记录自定义类型节点的一些属性。

import cake from './cake.png';

// 自定义元素的类型,此时我们只需要自定义一种节点,所以数组只有一个元素
const customelements = ['bpmn:task']; 
const customconfig = {
  // 自定义元素的配置
  cake: {
    url: cake,
    attr: {x: 0, y: 0, width: 50, height: 50}
  }
};
 
export {customelements, customconfig};

现在我们来书写drawshape函数

import { customelements, customconfig } from './util';
import { append as svgappend, create as svgcreate } from 'tiny-svg';
...
drawshape(parentnode, element) {
  const type = element.type; // 获取到类型
  // 所有节点都会走这个函数,所以此时只限制,需要自定义的才去自定义,否则仍显示bpmn默认图标
  if (customelements.includes(type)) {  
    const {url, attr} = customconfig['cake'];
    const customicon = svgcreate('image', {...attr, href: url});
    element['width'] = attr.width;
    element['height'] = attr.height;
    svgappend(parentnode, customicon);
    return customicon;
  }
  const shape = this.bpmnrenderer.drawshape(parentnode, element);
  return shape;
}

步骤7: 导出并使用customrenderer

修改之前导出custompalette的 index.js文件

import custompalette from './custompalette';
import customrenderer from './customrenderer';
 
export default {
  __init__: ['custompalette', 'customrenderer'],
  custompalette: ['type', custompalette],
  customrenderer: ['type', customrenderer]
};

注意:此时__init__内的属性名都不可以改,不要问为什么,因为改了报错。

步骤3中已经将该index.js引入到了页面中,此时无需再次引入,此时我们来看看效果。

 后续

项目目录:index.vue是画布主页面,同级custompalette文件夹下共有6个文件,结构如下:

 

各个文件的代码片段在文中已经展示过了,文件夹不知道怎么上传到博客。如想获取完整源码或有问题,公众号联系我,扫下面二维码或公众号搜“lemoncool”,即可获取~

 可爱的你可能还需要

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网