bpmn-js系列之Palette

前边写了四篇文章介绍了bpmn.js的基本使用,最近陆续有小伙伴加我催更,感谢对我这个半吊子前端的信任,接着更新bpmn.js的一些高级用法,本篇介绍对左侧工具栏Palette的隐藏和自定义修改

隐藏shape

左侧工具栏Palette有些图标我用不到,那该如何隐藏呢?最简单的方法就是直接找到对应的class,通过css隐藏,例如我不需要创建数据存储,可以通过下边的代码隐藏

.bpmn-icon-data-store {
  display: none;
}

自定义shape

为了编辑方便,我想在palette上添加一个shape该如何操作呢?这里我们需要自定义Palette,自定义Palette有两种方式可以选择,第一种就是基于默认的Palette来修改,第二种就是完全写个新的Palette来替代默认的Palette,第一种只能在默认的Palette上添加shape,而不能修改或删除,比较鸡肋我们就直接放弃了,来看下完全自定义Palette该如何实现

以下代码基于我们之前搭建好的代码框架,具体可看文章『最好用的流程编辑器bpmn-js系列之基本使用』,

1.在components目录下新建customBpmn目录,在customBpmn目录下新建custom目录,每层目录下都新建index.js文件,最终目录结构如下

2.在custom目录下新建CustomPalette.js文件,内容如下

import { assign } from "min-dash";

export default function PaletteProvider(
  palette,
  create,
  elementFactory,
  handTool,
  lassoTool,
  spaceTool,
  globalConnect,
  translate
) {
  this.create = create;
  this.elementFactory = elementFactory;
  this.handTool = handTool;
  this.lassoTool = lassoTool;
  this.spaceTool = spaceTool;
  this.globalConnect = globalConnect;
  this.translate = translate;

  palette.registerProvider(this);
}

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

PaletteProvider.prototype.getPaletteEntries = function (element) {
  const {
    create,
    elementFactory,
    handTool,
    lassoTool,
    spaceTool,
    globalConnect,
    translate
  } = this;

  function createAction(type, group, className, title, options) {
    function createListener(event) {
      var shape = elementFactory.createShape(assign({ type: type }, options));

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

      create.start(event, shape);
    }

    var shortType = type.replace(/^bpmn:/, "");

    return {
      group: group,
      className: className,
      title: title || translate("Create {type}", { type: shortType }),
      action: {
        dragstart: createListener,
        click: createListener
      }
    };
  }

  return {
    "lasso-tool": {
      group: "tools",
      className: "bpmn-icon-lasso-tool",
      title: "Activate the lasso tool",
      action: {
        click: function (event) {
          lassoTool.activateSelection(event);
        }
      }
    },

    "tool-separator": {
      group: "tools",
      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",
      "创建结束节点"
    ),
    "create.user-task": createAction(
      "bpmn:UserTask",
      "activity",
      "bpmn-icon-user-task",
      "创建用户任务"
    ),
    "create.exclusive-gateway": createAction(
      "bpmn:ExclusiveGateway",
      "gateway",
      "bpmn-icon-gateway-xor",
      "创建排他网关"
    )
  };
};

这段代码的意思相信各位前端的大佬比我理解的要深刻,就不过多介绍了,Platte展示的shape就是最后return输出的那个字典数据定义的,一个shape对应的数据格式如下:

"lasso-tool": {
  group: "tools",
  className: "bpmn-icon-lasso-tool",
  title: "Activate the lasso tool",
  action: {
    click: function (event) {
      lassoTool.activateSelection(event);
    }
  }
}

其中key为这个shape的名称,value为这个shape定义的一些属性,主要有四个:

  • group: 定义这个shape属于哪个组,主要有tools、event、gateway和activity可以选择
  • className: 定义这个shape的chass名称,可以通过这个class给shape指定具体的样式
  • title: 定义这个shape的title,也就是鼠标移动到shape上的提示
  • action: 用户操作时触发的事件

通过这个数据我们就可以随意添加、删除或者修改Palette的shape了,改位置该样式轻松自如

3.在custom/index.js文件中添加如下内容将自定义的Palette导出

import CustomPalette from "./CustomPalette";

export default {
  __init__: ["paletteProvider"],
  paletteProvider: ["type", CustomPalette],
};

4.在customModeler/index.js文件中编写自定义的CustomModeler

import inherits from "inherits";

import Modeler from "bpmn-js/lib/Modeler";

import CustomModule from "./custom";

function CustomModeler(options) {
  Modeler.call(this, options);

  this._customElements = [];
}

inherits(CustomModeler, Modeler);

CustomModeler.prototype._modules = [].concat(CustomModeler.prototype._modules, [
  CustomModule
]);

export { CustomModeler };

5.在页面上引用自定义的CustomModeler以替代原本引用的BpmnModeler类,这样就能用到我们自定义的Palette啦

import { xmlStr } from "../mock/xmlStrPreview";
import { CustomModeler } from "../components/customBpmn";

export default {
  ...
  methods: {
    init() {
      const canvas = this.$refs.canvas;
      this.bpmnModeler = new CustomModeler({
        container: canvas
      });
      this.createNewDiagram();
    },
    async createNewDiagram() {
      try {
        const result = await this.bpmnModeler.importXML(xmlStr);
        const { warnings } = result;
        console.log(warnings);
      } catch (err) {
        console.log(err.message, err.warnings);
      }
    }
  }
};

最终效果如下:

Shape类型

关于Shape总共有哪些类型,以及各自对应的属性都是什么,这个官方没有具体的文档给列出,我在使用的时候通常直接查看源码bpmn-js/lib/features/palette/PaletteProvider.js和bpmn-js/lib/features/context-pad/ContextPadProvider.js文件获取,对于部分类型,需要添加options选项

例如中间时间事件IntermediateThrowEvent所对应的属性为:

return {
  "create.timer-intermediate-event": createAction(
    "bpmn:IntermediateThrowEvent",
    "event",
    "bpmn-icon-intermediate-event-catch-timer",
    "Create IntermediateThrowEvent",
    { eventDefinitionType: "bpmn:TimerEventDefinition" }
  )
};

写在最后

接触bpmn-js不久,边学边写,文章难免出错,各位多多包含。想要打造一个好用的适合自己的流程编辑器,需要了解的内容比较多,bpmn-js会分多篇文章来介绍,欢迎关注

源码地址:https://github.com/Mrs-Bean/bpmn-src.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/452963.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据挖掘】实验2:R入门2

实验2&#xff1a;R入门2 一&#xff1a;实验目的与要求 1&#xff1a;熟悉和掌握R数据类型。 2&#xff1a;熟悉和掌握R语言的数据读写。 二&#xff1a;实验内容 1&#xff1a;R数据类型 【基本赋值】 Eg.1代码&#xff1a; x <- 8 x Eg.2代码&#xff1a; a city …

碳实践 | 基于“界、源、算、质、查”五步法,实现企业组织碳核算

碳排放核算是夯实碳排放统计的基础&#xff0c;提高碳排放数据质量的关键&#xff0c;同时&#xff0c;将推动能耗“双控”向碳排放“双控”转变。总体来看&#xff0c;碳核算分为区域层面、组织层面和产品层面的碳核算&#xff0c;这三个层面的意义和计算方法完全不同。本文将…

【高通camera hal bug分析】高通自带相机镜像问题

首先打了两个log&#xff0c;一个是开启镜像的log&#xff0c;还有一个是没有开启镜像的log&#xff0c;如果我们开启镜像以后&#xff0c;观察开启镜像log发现 , 这段代码走的没有任何问题&#xff0c;因为Flip的值等于1了。 关闭镜像log如下&#xff1a; 如果我们不开启镜像…

<机器学习初识>——《机器学习》

目录 一、人工智能概述 1 人工智能应用场景 2 人工智能发展必备三要素 3 人工智能、机器学习和深度学习 二、人工智能发展历程 1 人工智能的起源 1.1 图灵测试 1.2 达特茅斯会议 2 发展历程 三、 人工智能主要分支 1 主要分支介绍 1.1 分支一&#xff1a;计算机视觉…

STM32点亮LED灯与蜂鸣器发声

STM32之GPIO GPIO在输出模式时可以控制端口输出高低电平&#xff0c;用以驱动Led蜂鸣器等外设&#xff0c;以及模拟通信协议输出时序等。 输入模式时可以读取端口的高低电平或电压&#xff0c;用于读取按键输入&#xff0c;外接模块电平信号输入&#xff0c;ADC电压采集灯 GP…

基于Springboot的驾校预约学习系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的驾校预约学习系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

ubuntu2004桌面系统英伟达显卡驱动安装方法

#如何查看显卡型号 lspci | grep -i vga#----output------ 01:00.0 VGA compatible controller: NVIDIA Corporation Device 1f06 (rev a1)根据 Device 后的 值 进入网站查询 pci-ids.ucw.cz/mods/PC/10de?actionhelp?helppci #根据显卡型号&#xff0c;下载对应系统的驱动…

C++ 作业 24/3/12

1、自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height),定义公有成员函数: 初始化函数:void init(int w, int h)更改宽度的函数:set_w(int w)更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() #include <iostream>using …

一劳永逸的方法解决:LNK1168无法打开 xxx.exe 进行写入 报错问题

这种错误的产生原因&#xff1a; 运行程序退出不是按正常流退出&#xff0c;是按窗口右上角的 “X” 来关闭程序&#xff0c;但是后台的xxx.exe控制台程序还在运行&#xff1b;修改程序的代码后再运行&#xff0c;就会报LNK1168的错误&#xff1b; 报错示例&#xff1a; 解决方…

【嵌入式学习】C++day03.12

一、思维导图 二、练习 #include <iostream>using namespace std;class Rect {int width;int height; public:void init(int w,int h){widthw;heighth;}void set_w(int w){widthw;}void set_h(int h){heighth;}void show(){int per2*(widthheight);int areawidth*height;…

通过el-select选择器和el-tree树形结构二次封装(vue2+elementUI),开发element-plus的TreeSelect树形选择器

需求&#xff1a; 领导看我在另一个vue3项目的el-tree-select挺好的&#xff0c;叫我移入vue2的项目中。 但是vue2版本的elementUI&#xff0c;并没有这个组件&#xff0c;所以只能自己找&#xff0c;找半天找不到和它差不多的&#xff0c;通过网友写的组件改写的 参考链接&…

手势学习

1. 点击手势 Composable fun ClickableSample() {val number remember {mutableStateOf(0)}Text(text number.value.toString(),textAlign TextAlign.Center,modifier Modifier.wrapContentSize().clickable {number.value}.background(Color.LightGray).padding(horizonta…

软件I2C读写MPU6050

文章目录 前言本次线路图封装I2C时序封装MPU6050,配置寄存器最后在主函数进行显示 前言 本片文章开始进行I2C在STM32的直接操作&#xff0c;理解时序的代码实现&#xff0c;理解对寄存器的配置&#xff0c;使用I2C读写MPU6050&#xff0c;读取MPU6050的各轴数据。 MPU6050详解…

vue 自定义组件绑定model+弹出选择支持上下按键选择

参考地址v-modelhttps://v2.cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-v-model 原文代码 Vue.component(base-checkbox, {model: {prop: checked,event: change},props: {checked: Boolean},template: `…

Java异常分类(二)

RuntimeException 运行时异常&#xff1a; 派生于 RuntimeException 的异常&#xff0c;如被 0 除、数组下标越界、空指针等&#xff0c;其产生比较频繁&#xff0c;处理麻烦&#xff0c;如果显式的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交…

Caffeine缓存

本地缓存基于本地环境的内存&#xff0c;访问速度非常快&#xff0c;对于一些变更频率低、实时性要求低的数据&#xff0c;可以放在本地缓存中&#xff0c;提升访问速度 使用本地缓存能够减少和Redis类的远程缓存间的数据交互&#xff0c;减少网络 I/O 开销&#xff0c;降低这…

使用EasyRec快速构建推荐模型

随着移动app的普及&#xff0c;个性化推荐和广告成为很多app不可或缺的一部分。他们在改善用户体验和提升app的收益方面带来了巨大的提升。深度学习在搜广推领域的应用也已经非常深入&#xff0c;并且给各种场景的效果带来了巨大的提升。针对推荐流程的各个阶段&#xff0c;业界…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的石头剪刀布手势识别系统详解(深度学习模型+UI界面代码+训练数据集)

摘要&#xff1a;本篇博客深入探讨了使用深度学习技术开发石头剪刀布手势识别系统的过程&#xff0c;并分享了完整代码。该系统利用先进的YOLOv8、YOLOv7、YOLOv6、YOLOv5算法&#xff0c;并对这几个版本进行性能对比&#xff0c;如mAP、F1 Score等关键指标。文章详细阐述了YOL…

【算法题解】Java算法题目解析

1. 数字三角形 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);int n scan.nextInt();int[][] dp new int[n 1][n 1];int max 0;for (int i 1; i < dp.length; i) {for (int j 1; j &l…

Android 生成SO - 基础工程创建

最近需要给小伙伴扫盲一下如何使用Android Studio 生成一个SO文件&#xff0c;网上找了很多都没有合适的样例&#xff0c;那只能自己来写一个了。 原先生成SO是一个很麻烦的事情&#xff0c;现在Android Studio帮忙做了很多的事情&#xff0c;基本只要管好自己的C代码即可。 …