全网最详bpmn.js教材-Color篇

前言

Q: bpmn.js是什么? 🤔️

bpmn.js是一个BPMN2.0渲染工具包和web建模器, 使得画流程图的功能在前端来完成.

Q: 我为什么要写该系列的教材? 🤔️

因为公司业务的需要因而要在项目中使用到bpmn.js,但是由于bpmn.js的开发者是国外友人, 因此国内对这方面的教材很少, 也没有详细的文档. 所以很多使用方式很多坑都得自己去找.在将其琢磨完之后, 决定写一系列关于它的教材来帮助更多bpmn.js的使用者或者是期于找到一种好的绘制流程图的开发者. 同时也是自己对其的一种巩固.

首先先说明一点吧,bpmn.js主要是为画工作流做规则引擎用的,所以如果您的工作中并不涉及到这一块的话可以不用浪费时间阅读本篇文章。当然如果您为此感兴趣的话可以移步bpmn-chinese-document看看它的介绍,如果你对它不感兴趣对我感兴趣的话可以移步我的个人博客niubility-coding-js (好惨没一个Star)😄。

由于是系列的文章, 所以更新的可能会比较频繁, 您要是无意间刷到了且不是您所需要的还请谅解😊.

求赞👍求心❤️. 更希望能对你有一点小小的帮助.

完整目录及GitHub地址:bpmn-chinese-document

Color篇

很久没写bpmn.js系列的教材了...😄,写起来还是感觉挺亲切的。

这篇文章主要是介绍一下在bpmn.js中修改节点颜色的各种场景和方式,算是bpmn.js交流群群里的一个热门问点吧。另外文章中我会以几个常用类型的节点作为案例来进行讲解,比如StartEvent、Task、EndEvent这几种类型,其它类型的修改和案例中的大同小异,还请自行扩展。

因为我一直相信授人予鱼不如授人予渔,这才是一篇教程真正能带给你的东西。我们在实际开发中肯定会遇到各种各样不同的需求,不可能每篇教程都能刚好符合你的业务要求,所以我能做的只是保证你能有一定的bpmn.js使用基础并在此基础上有自己的思考。

好了话不多说咯,来看看,通过阅读你可以学习到:

  • 修改palette左侧工具栏中的节点颜色
  • 修改renderer渲染在页面上的节点颜色
  • 修改contextPad上的节点颜色
  • 在渲染完成之后用户手动触发修改节点颜色

来几张张效果图看看:

bpmn-colors.gif

(这狗血的画质...)

1.png
2.png

因为内容不多,所以就没有另起一个案例项目。

以下所有案例都整理在bpmn-properties-panel里面。Color篇的展示主要是在custom-color这个页面下,代码是放在components/custom-color.vue中。

修改palette左侧工具栏中的节点颜色

左侧工具栏修改节点颜色很简单,只需要找到对应节点的类名在css中修改就可以了。

例如我修改了案例中的开始节点。

  1. 找到开始节点的类名
3.png
  1. 在一个全局样式中修改它

如果你和我一样不想要所有的palette都被修改颜色,可以指定某一个页面下进行修改,方式是给你生成bpmn图的容器添加一个类名:

custom-color.vue

<div class="containers bpmn-color" ref="content">
  <div class="canvas" ref="canvas"></div>
</div>

例如我这里只修改custom-color页面中的palette

![5.png](https://upload-images.jianshu.io/upload_images/7190596-b24bc3eb5f80bb0e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

给它加上bpmn-color这个类名。

然后在全局的/styles/bpmn-custom-color.css中修改类的样式:

.bpmn-color .bpmn-icon-start-event-none:before {
  color: #12c2e9;
}
.bpmn-color .bpmn-icon-task:before {
  color: #c471ed;
}
.bpmn-color .bpmn-icon-end-event-none:before {
  color: #f64f59;
}
  1. 将自定义的样式引入到main.js

最后一步就是要把我们自定义的样式引入到main.js里,这里有一个要注意的就是自定义的样式要放在bpmn.js自带的样式下面:

main.js

import Vue from 'vue'

import 'bpmn-js/dist/assets/diagram-js.css' // 左边工具栏以及编辑节点的样式
import './styles/bpmn-custom-color.css' // 自定义样式

现在保存打开页面就可以看到效果了。

不过这个只能修改图像边框的颜色,因为这个图像本质就是一个icon字体,所以可以用color这个属性来控制字体的颜色。而字体颜色的范围是由这个icon图像本身决定的,也就是说如果这个字体它本身就是个圆环,那color也就只能修改它的圆边框;如果这个字体本身就是个完整的圆,那color肯定也就能修改整个圆了。

修改renderer渲染在页面上的节点颜色

光有左侧工具栏的修改还不够,最主要的是要渲染的时候能修改为自己想要的颜色。

例如你的需求可能是在进行初始化的时候,就需要根据节点的类型来将节点修改为不同的颜色。

比如StartEvent修改为红色,Task修改为蓝色等等。

这时候我们需要用到之前在自定义renderer篇中提到过的「在默认的Renderer基础上修改」。对renderer不懂的小伙伴一定要先阅读自定义renderer篇才行。

在此我假设你已经完全了解了renderer

那么我们知道一个元素能否成功在页面上渲染,关键的代码就是在CustomRenderer中重写drawShape这个方法。

而这个方法其实依赖的是这段代码:

//CustomRenderer.js

drawShape(parentNode, element) {
    let shape = this.bpmnRenderer.drawShape(parentNode, element)
    return shape
}

也就是说是靠this.bpmnRenderer.drawShape这个方法将element对象转换为一个svg形式的节点。

最开始我的想法是在转换之前使用modeling.setColor方法来修改element的相应样式:

//CustomRenderer.js

drawShape(parentNode, element) {
        modeling.setColor(element, {
        fill: null,
        stroke: color
    })
    let shape = this.bpmnRenderer.drawShape(parentNode, element)
    return shape
}

但这种方式失败了,打开控制台报了一堆的红色错误,大致就是进入了死循环,浏览器爆栈了。

想了一下其实也好理解,renderer的作用本就是将element进行渲染,但是在这个阶段你又用setColor去修改element的这个属性,那这样肯定就会造成递归循环渲染,所以这种做法被我否定了。

之后我想了一下,使用drawShape方法产生的东西会是什么呢?带着好奇我把生成的shape打印出来看了一下,发现他就是一个DOM元素:

// StartEvent
<circle cx="18" cy="18" r="18" style="stroke: black; stroke-width: 2px; fill: rgb(18, 194, 233); fill-opacity: 0.95;"></circle>

// TaskEvent
<rect x="0" y="0" width="100" height="80" rx="10" ry="10" style="stroke: rgb(196, 113, 237); stroke-width: 2px; fill: white; fill-opacity: 0.95;"></rect>

既然是DOM元素那可就简单了,只需要用修改DOM元素样式的方法来处理就可以了。

所以其实你可以这样做:

//CustomRenderer.js

drawShape(parentNode, element) {
    let shape = this.bpmnRenderer.drawShape(parentNode, element)
    shape.style.setProperty('fill', 'red')
    return shape
}

在生成shape之后使用style.setProperty方法修改想要修改的属性就可以了。

在一个shape中,主要是有这么几种属性可以供我们修改:

  • fill:元素的填充色
  • stroke:元素的边框颜色
  • strokenWidth:元素边框的宽度

为了方便管理和配置我在CustomRenderer.js中定义了一个配置想,另外封装了一个setShapeProperties方法专门用来处理节点颜色的问题,核心代码就这么些:

const propertiesConfig = {
  'bpmn:StartEvent': {
    fill: '#12c2e9'
  },
  'bpmn:Task': {
    stroke: '#c471ed',
    strokeWidth: 2,
  },
  'bpmn:EndEvent': {
    stroke: '#f64f59',
    fill: '#f64f59'
  }
}

export default class CustomRenderer extends BaseRenderer {
  drawShape(parentNode, element) {
      let shape = this.bpmnRenderer.drawShape(parentNode, element)
      setShapeProperties(shape, element)
      return shape
  }
}

function setShapeProperties (shape, element) {
  const type = element.type // 获取到的类型
  if (propertiesConfig[type]) {
    const properties = propertiesConfig[type]
    Object.keys(properties).forEach(prop => {
      shape.style.setProperty(prop, properties[prop])
    })
  }
}

通过PropertiesConfig[type]判断有没有要自定义的元素,有的话就走if判断里。

Object.keys() 方法其实就是获取某个对象下的所有属性名称,比如:

var obj = { a: 1, b: 2 }
console.log(Object.keys(obj)) // ['a', 'b']

这个写前端的可能都知道,主要是怕后台人员不了解所以提一嘴。

现在保存刷新页面后就可以看到效果了 😊:

1.png

修改contextPad上的节点颜色

contextPad上的节点颜色,事实上和修改palette是一样的。因为它们共用了一个className。因此如果你改了palette上的样式,contextPad上的也会被修改。

在渲染完成之后用户手动触发修改节点颜色

这个功能的主要作用是说,在渲染成功之后,可能需要用户手动去修改某个节点的颜色。

额...这其实在全网最详bpmn.js教材-poperties-panel篇(下)中也说到过了吧,核心方法就是用使用modeling.setColor()方法去修改。

const modeling = this.modeler.get('modeling')
modeling.setColor(element, {
  fill: 'blue',
  stroke: 'red'
})

在此不再重复说了 😁。

另外我在官网也发现了有关于colors的案例,它主要是能配合xml标签上的属性来进行相应颜色的修改,有兴趣的小伙伴可以看一下:

bpmn-js colors

bpmn-js-task-priorities

后语

2019年12月10日最开始写此教材到现在已经四个月了,bpmn.js交流群也从最开始的3,4个人扩展到了现在的200人,还是挺欣慰的。

也很感谢群里的一些小伙伴能热心的为新来的小伙伴解答问题提供帮助,我在此代接受过帮助的小伙伴谢谢大家!

不过也希望能有更多的小伙伴能积极的参与到bpmn-chinese-document的项目中来,也算是为国内bpmn.js的社区贡献一份力吧💪。

最后还请能给bpmn-chinese-document一个Star🌟,编写整理都不易,感谢🙏。

喜欢霖呆呆的小伙还希望可以关注霖呆呆的公众号 LinDaiDai 或者扫一扫下面的二维码👇👇👇.

LinDaiDai公众号gif图.gif

我会不定时的更新一些前端方面的知识内容以及自己的原创文章🎉

你的鼓励就是我持续创作的主要动力 😊.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容