首页 前端知识 bpmn-js自定义Palette、ContextPad、节点样式及属性

bpmn-js自定义Palette、ContextPad、节点样式及属性

2024-08-22 23:08:57 前端知识 前端哥 790 343 我要收藏

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
    • 项目中需要前端做一个流程设计器,后端拿到流程数据去执行相关任务。前端使用bpmn-js,后端使用flowable。
  • 一、自定义Palette
  • 二、重写Palette
  • 三、自定义节点样式
  • 四、bpmn的一些常用监听事件可以做自己的对应操作
  • 五、自定义ContextPad
  • 总结


前言

项目中需要前端做一个流程设计器,后端拿到流程数据去执行相关任务。前端使用bpmn-js,后端使用flowable。

效果图:
请添加图片描述

请添加图片描述

一、自定义Palette

1.使用 paletteProvider 同名参数 覆盖 默认 paletteProvider 构造函数

import rerenderPaletteProvider from "./rewritePaletteProvider";
const RerenderPalette = {
  __init__: ["paletteProvider"],
  paletteProvider: ["type", rerenderPaletteProvider]
};

export default RerenderPalette;

2.使用PaletteProvider配置自定义Palette

import PaletteProvider from "bpmn-js/lib/features/palette/PaletteProvider";
import { assign } from "min-dash";
import { createAction } from "../utils";

class RewritePaletteProvider extends PaletteProvider {
    constructor(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect) {
        super(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, 2000);
        this._create = create;
        this._elementFactory = elementFactory;
        this._lassoTool = lassoTool;
        this._handTool = handTool;
        this._globalConnect = globalConnect;
    }
    getPaletteEntries() {
        const actions = {},
            create = this._create,
            elementFactory = this._elementFactory,
            lassoTool = this._lassoTool,
            handTool = this._handTool,
            globalConnect = this._globalConnect;
            
        function createOutputLabelTask(event) {
            const acrossLinkTask = elementFactory.createShape({
                type: "miyue:OutputLabelTask",
            });
            create.start(event, acrossLinkTask);
        }
        assign(actions, {
            "create.service-task-scbq": {
                group: "任务",
                className: "miyue-output-label-task",
                title: "输出标签",
                action: {
                    click: createOutputLabelTask,
                    dragstart: createOutputLabelTask
                }
            },
        });

        return actions;
    }
}

RewritePaletteProvider.$inject = [
    "palette",
    "create",
    "elementFactory",
    "spaceTool",
    "lassoTool",
    "handTool",
    "globalConnect"
];

export default RewritePaletteProvider;

3.向additionalModules中添加自定义扩展

import Modeler from "bpmn-js/lib/Modeler";
import RewritePalette from "./RewritePalette";
new Modeler({
	container:'',
	additionalModules:[RewritePalette]
});

4.效果图
请添加图片描述

二、重写Palette

1.将原有的Palette隐藏掉

.djs-accordion-palette.open {
  display: none;
}

2.搭建操作栏样式

<el-collapse>
	<el-collapse-item title="事件">
		<div @mousedown="paletteChange($event, 'bpmn:StartEvent')" class="collapse-item">
			<div class="icon-before start-event-icon"></div>
			<span>开始事件</span>
		</div>
		<div @mousedown="paletteChange($event, 'bpmn:EndEvent')" class="collapse-item">
			<div class="icon-before end-event-icon"></div>
			<span>结束事件</span>
		</div>
	</el-collapse-item>
	<el-collapse-item title="数据读取">
		<div style="padding-left: 16px">
			<el-collapse>
				<el-collapse-item v-for="item in dataDbList" :title="item.dbNameCn" :key="item.id">
					<div v-for="val in item.dataTables" :key="val.id"
						@mousedown="paletteChange($event, 'bpmn:ServiceTask', val)" class="collapse-item">
						<div class="service-task-icon"></div>
						<span>{{ val.tabNameEn }}</span>
					</div>
				</el-collapse-item>
			</el-collapse>
		</div>
	</el-collapse-item>
	<el-collapse-item title="数据关联">
		<div @mousedown="paletteChange($event, 'miyue:AcrossLinkTask')" class="collapse-item">
			<div class="acrossLink-task-icon"></div>
			<span>横连接</span>
		</div>
	</el-collapse-item>
	<el-collapse-item title="数据输出">
		<div @mousedown="paletteChange($event, 'miyue:OutputLabelTask')" class="collapse-item">
			<div class="outputLabel-task-icon"></div>
			<span>输出标签</span>
		</div>
	</el-collapse-item>
</el-collapse>

3.点击操作栏调用节点创建事件

paletteChange(event, type, val) {
	//获取根节点
	const rootElement = this.getModeler.get("canvas").getRootElement();
	let elementFactory = this.getModeler.get("elementFactory");
	let create = this.getModeler.get("create");
	let branchShape = elementFactory.createShape({
		type: type,
	});
	create.start(event, branchShape);
}

4.效果图
请添加图片描述

三、自定义节点样式

"miyue:OutputLabelTask": function (parentGfx, element, attr) {
  // 渲染外层边框
  const attrs = {
    fill: '#FFFFFF',
    fillOpacity: 1,
    stroke: getStrokeColor(element, defaultTaskColor),
    strokeWidth:'1px'
  };
  //修改外层边框样式
  element.width = 64;
  element.height = 56;
  renderer("bpmn:Activity")(parentGfx, element, attrs);
  // 自定义节点
  const customIcon = svgCreate("image");
  svgAttr(customIcon, {
    ...(attr || {}),
    width: element.width - 22,
    height: element.height - 22,
    x:11,
    y:11,
    href: labelIcon
  });
  svgAppend(parentGfx, customIcon);
  //渲染lable
  renderEmbeddedLabel(parentGfx, element, "center-bottom");
  return customIcon;
}

四、bpmn的一些常用监听事件可以做自己的对应操作

//节点创建时触发
 modeler.on("commandStack.shape.create.postExecuted", (event) => {});
//双击节点时触发
 modeler.on("element.dblclick", (event) => {});
//单击节点时出发
modeler.on("element.click", (event) => {});
//选中当前节点时触发
modeler.on("selection.changed", () => {});

在双击节点时拿到节点信息弹出表单框,填写信息后将数据插入节点属性中。
在这里插入图片描述
将数据保存在节点属性中

//attribute 你要插入的数据
const attribute;
 modeler.get("modeling").updateProperties(
    modeler.get("elementRegistry").get(event.context.shape.id),
    attribute
);

五、自定义ContextPad

因为默认的ContextPad有很多功能,我只需要移除和连接。
修改前:
在这里插入图片描述
修改后:
在这里插入图片描述
1.使用contextPadProvider参数覆盖同名构造函数

import rewriteContextPadProvider from "./rewriteContextPadProvider";

const rewriteContextPad = {
  __init__: ["contextPadProvider"],
  contextPadProvider: ["type", rewriteContextPadProvider]
};

export default rewriteContextPad;

2.引入ContextPadProvider进行重写

import ContextPadProvider from "bpmn-js/lib/features/context-pad/ContextPadProvider";
class RewriteContextPadProvider extends ContextPadProvider {
  constructor(
    config,
    injector,
    eventBus,
    contextPad,
    modeling,
    elementFactory,
    connect,
    create,
    popupMenu,
    canvas,
    rules,
    translate,
    globalConnect
  ) {
    super(
      config,
      injector,
      eventBus,
      contextPad,
      modeling,
      elementFactory,
      connect,
      create,
      popupMenu,
      canvas,
      rules,
      translate,
      globalConnect,
      2000
    );

    this._contextPad = contextPad;
    this._modeling = modeling;
    this._elementFactory = elementFactory;
    this._connect = connect;
    this._create = create;
    this._popupMenu = popupMenu;
    this._canvas = canvas;
    this._rules = rules;
    this._translate = translate;

    this._autoPlace = injector.get("autoPlace", false);
    this._globalConnect = globalConnect;
  }

  getContextPadEntries(element) {
    const actions = {};
    const modeling = this._modeling;
    const globalConnect = this._globalConnect;
    const connect = this._connect;
    actions["enhancement-op"] = {
      group: "操作栏",
      className: "bpmn-icon-trash",
      title: "移除",
      action: {
        click: function (event, delElement) {
          modeling.removeElements([...(delElement.incoming || []), ...(delElement.outgoing || []), delElement]);
        }
      }
    };
    actions["enhancement-op-1"] = {
      group: "操作栏",
      className: "bpmn-icon-connection-multi",
      title: "连接",
      action: {
        click: function (event, element) {
          connect.start(event, element);
        }
      }
    };
    return actions;
  }
}
export default RewriteContextPadProvider;

总结

工作准则:多做多错,少错少错、不做不错。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16505.html
标签
流程图
评论
发布的文章

HTML5入门基础

2024-06-16 09:06:50

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!