bpmn.js自定义各项,palette contextPad elementFactory modeling renderer rules

从bpmn仓库给出的example看
https://github.com/bpmn-io/bpmn-js-examples
我们要实现自定义可以有两种方式,

  1. 【继承】 bpmn-js,并修改原型上的方法,达到兼容自定义的相关
  2. 【重新实现】也就是把bpmn做的事情,在本地再做一遍,当然你可以各种“借鉴”里面的function,并达到你的要求

比如
customModeler/index.js

import CustomContextPadProvider from './CustomContextPadProvider';
import CustomElementFactory from './CustomElementFactory';
import CustomOrderingProvider from './CustomOrderingProvider';
import CustomPalette from './CustomPalette';
import CustomRenderer from './CustomRenderer';
import CustomRules from './CustomRules';
import CustomUpdater from './CustomUpdater';
import CustomModeling from './CustomModeling';

export default {
  __init__: [
    'contextPadProvider',
    'customOrderingProvider',
    'customRenderer',
    'customRules',
    'customUpdater',
    'customUpdater',
    'paletteProvider',
    'modeling'
  ],
  contextPadProvider: ['type', CustomContextPadProvider],
  customOrderingProvider: ['type', CustomOrderingProvider],
  customRenderer: ['type', CustomRenderer],
  customRules: ['type', CustomRules],
  customUpdater: ['type', CustomUpdater],
  elementFactory: ['type', CustomElementFactory],
  paletteProvider: ['type', CustomPalette],
  modeling: ['type', CustomModeling]
};

里面elementFactory、paletteProvider、modeling都是对原有的进行覆盖,当你在使用$inject的时候,使用的其实是你自定义的部分;
其余则是新增(追加),不会改变原有,也可以在 $inject的时候引进你的名字进行使用

原有的

import BpmnModeler from 'bpmn-js/lib/Modeler';
import CustomModeler from '../customModeler';

this.bpmnModeler = new BpmnModeler({
// ...
})
改为上面的
this.bpmnModeler = new CustomModeler({
// ...
})

当你要新增一个并列与bpmn:Task,bpmn:StartEvent的类型,你可以建CustomElementFactory
继承bpmn

import BpmnElementFactory from 'bpmn-js/lib/features/modeling/ElementFactory';
import inherits from 'inherits';

export default function CustomElementFactory(bpmnFactory, moddle, translate) {
  BpmnElementFactory.call(this, bpmnFactory, moddle, translate);

  var self = this;
  this.create = function(elementType, attrs) {
    var type = attrs.type;
    // ...
    // 排除自定义类型,exaple中自定义的图标类型是custom:triangle / custom:circle
    if (/^custom:/.test(type)) {
      // ...
    }
    // 真实创建在这里✨✨✨
    return self.createBpmnElement(elementType, attrs);
  }
}
inherits(CustomElementFactory, BpmnElementFactory);

CustomElementFactory.$inject = [
  'bpmnFactory',
  'moddle',
  'translate'
];
// 重写bpmn中BpmnElementFactory的一些方法
CustomElementFactory.prototype._getCustomElementSize = function(type) {
  var shapes = {
    __default: { width: 100, height: 80 },
    'custom:triangle': { width: 40, height: 40 },
    'custom:circle': { width: 140, height: 140 }
  };

  return shapes[type] || shapes.__default;
}

看这句self.createBpmnElement
追溯到’bpmn-js/lib/features/modeling/ElementFactory’文件下可以看到,其实调用的还是diagram-js/lib/core/ElementFactory

import BaseElementFactory from 'diagram-js/lib/core/ElementFactory';
// ...
ElementFactory.prototype.baseCreate = BaseElementFactory.prototype.create;

分割线

左侧菜单

import {
  assign
} from 'min-dash';
import PaletteProvider from 'bpmn-js/lib/features/palette/PaletteProvider';

export default function PaletteProvider(injector, palette, create, elementFactory, spaceTool, lassoTool) {

  this._create = create;
  this._elementFactory = elementFactory;
  this._spaceTool = spaceTool;
  this._lassoTool = lassoTool;
  // 如果你希望在原有上追加,使用cached这一种
  // injector.invoke(PaletteProvider, this);
  // this._cached = bind(this.getPaletteEntries, this);

  palette.registerProvider(this);
}
PaletteProvider.$inject = [
  'injector',
  'palette',
  'create',
  'elementFactory',
  'spaceTool',
  'lassoTool'
];
// getPaletteEntries  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PaletteProvider.prototype.getPaletteEntries = function(element) {
  // 如果你希望在原有上追加,使用cached这一种
  // let actions = this._cached(element);
  let actions = {}, // 清空原有的所有项目
    create = this._create,
    elementFactory = this._elementFactory;
    
  function createAction(type, group, className, title, options) {
    // 'custom:triangle', 'custom', 'icon-custom-triangle'

    function createListener(event) {
      let shape = elementFactory.createShape(assign({ type: type }, options));

      if (options) {
        shape.businessObject.di.isExpanded = options.isExpanded;
      }

      create.start(event, shape);
    }

    let shortType = type.replace(/^bpmn:/, '');

    return {
      group: group,
      className: className,
      title: title || 'Create ' + shortType,
      action: {
        dragstart: createListener,
        click: createListener
      }
    };
  }
  
  assign(actions, {
    // 自定义类型1
    'custom-triangle': createAction(
      'custom:triangle', 'custom', 'icon-custom-triangle'
    ),
    // 自定义类型2
    'custom-circle': createAction(
      'custom:circle', 'custom', 'icon-custom-circle'
    ),
    'custom-separator': {
      group: 'custom',
      separator: true
    },
    'create.start-event': createAction(
      'bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none'
    ),
    'create.end-event': createAction(
      'bpmn:EndEvent', 'event', 'bpmn-icon-end-event-none'
    ),
  }
  return actions;
}

任务清单:

  1. 追加左侧palette类型:结构可以自行控制
  2. 追加节点(随意控制包括自定义节点的任意节点)选中时身边的contextPadProvider:可以链接到其他自定义类型
  3. 内置的connect是有rule限制的,所以要自定义rule修改规则,允许连线到自定义节点
  4. 单个节点的结构要允许能够自行定义(网络做法是自定义moddleExtensions,动作时
{
  "name": "QualityAssurance",
  "uri": "http://some-company/schema/bpmn/qa",
  "prefix": "qa",
  "xml": {
    "tagAlias": "lowerCase"
  },
  "types": [
    {
      "name": "XssProperties",
      "superClass": ["Element"],
      "meta": {
        "allowedIn": ["*"]
      },
	  "properties": [
        {
          "name": "values",
          "type": "XssProperty",
          "isMany": true
        }
	  ]
	},
	{
	    "name": "XssPropertyStruct",
	    "properties": [
	      {
	        "name": "value",
	        "type": "String",
	        "isAttr": true
	      }
	    ]
	  },
	  {
	    "name": "XssProperty",
	    "superClass": ["InputOutputParameterDefinition"],
	    "properties": [
	      {
	        "name": "type",
	        "isAttr": true,
	        "type": "XssPropertyStruct"
	      },
	      {
	        "name": "value",
	        "isAttr": true,
	        "type": "XssPropertyStruct"
	      }
    ]
  }],
  "emumerations": [],
  "associations": []
}
let dd = moddle.create('qa:XssProperties', { values: [] });
let typeObj = moddle.create('qa:XssPropertyStruct', { value: 'type1' });
let valueObj = moddle.create('qa:XssPropertyStruct', { value: '0' });
let dd2 = moddle.create('qa:XssProperty', { type: {}, value: {} });
const extensions = moddle.create('bpmn:ExtensionElements', { values: [] });
dd2.type = typeObj;
dd2.value = valueObj;
dd.values.push(dd2);
extensions.values.push(dd);

this.bpmnModeler.get('modeling').updateProperties(this.bpmnElement, {
  extensionElements: extensions
})

还有问题的可以一起留言讨论

你可能感兴趣的:(源码,vue,javascript,bpmn.js,源码,前端)