【bpmn.js 使用总结】十、答疑

11 篇文章 37 订阅
5 篇文章 0 订阅

答疑 (持续更新)

1 如何自定义 id

如何将 id,例如 Task_1hcentk 改成自己想要的格式 ?

先看看源码怎么写
bpmn-js/lib/features/modeling/BpmnFactory.js

BpmnFactory.prototype._ensureId = function(element) {
  // generate semantic ids for elements
  // bpmn:SequenceFlow -> SequenceFlow_ID
  var prefix

  if (is(element, 'bpmn:Activity')) {
    prefix = 'Activity'
  } else if (is(element, 'bpmn:Event')) {
    prefix = 'Event'
  } else if (is(element, 'bpmn:Gateway')) {
    prefix = 'Gateway'
  } else if (isAny(element, ['bpmn:SequenceFlow', 'bpmn:MessageFlow'])) {
    prefix = 'Flow'
  } else {
    prefix = (element.$type || '').replace(/^[^:]*:/g, '')
  }

  prefix += '_'

  if (!element.id && this._needsId(element)) {
    // 关键在这里,我们也可以拿它的id生成器结合我们的一起使用
    element.id = this._model.ids.nextPrefixed(prefix, element)
  }
}

可知,他的默认格式是 ${type}_${id}, 其中 id 部分是由 _model.ids.nextPrefixed 生成

然后需要知道 id 是什么时候生成的? id 是点击拖动 palette 工具栏元素的时候生成的。
那么我们只要修改工具栏代码即可。

CustomPalette.js


// 1
Palette.$inject = [
  'eventBus',
  'canvas',
  'elementFactory',
  'bpmnFactory', // 新增
  'moddle', // 新增
  'create',
  'config.paletteContainer',
  'config.paletteEntries'
]
// 顺序一一对齐
// 2
function Palette(
  eventBus,
  canvas,
  elementFactory,
  bpmnFactory, // 新增
  moddle, // 新增
  create,
  paletteContainer,
  paletteEntries
) {
  // ....
  this._bpmnFactory = bpmnFactory
  this._model = moddle
}
// 3
Palette.prototype.trigger = function () {
   var bpmnFactory = this._bpmnFactory
   var model = this._model

  // simple action (via callback function)
  //  传入 action 的 dragstart方法 click 方法
  // 传入 bpmnFactory
  if (isFunction(handler)) {
    if (action === 'click') {
      handler(originalEvent, autoActivate, elementFactory, bpmnFactory, model, create)
    }
  } else {
    if (handler[action]) {
      handler[action](originalEvent, autoActivate, elementFactory, bpmnFactory, model, create)
    }
}

// 4
// 最后就调用
// https://github.com/PL-FE/bpmn-doc/blob/dev/src/views/bpmn/config/paletteEntries.js#L60
function createListener(
    event,
    autoActivate,
    elementFactory,
    bpmnFactory, // 新增 bpmnFactory 入参,为了创建业务对象
    model, // 生成随机码
    create
  ) {
    const prefix = type + +new Date() + '_'
    const id = model.ids.nextPrefixed(prefix, { type })
    // 我们的id格式为 ${type}${new Date()}_${id}
    const taskBusinessObject = bpmnFactory.create(type, { id, name: id })

    var shape = elementFactory.createShape(
      assign({ type: type }, options, { businessObject: taskBusinessObject })
    )
  // ...
  }

完整代码可以看 git 提交记录

最后,contextPad 面板的元素生成也需要处理,代码与 palette 类似,不重复说明。
在线预览:http://bpmn-doc.pl-fe.cn/
如果我写的不是很清楚,那么这里有一些极简例子选择业务对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cOZRGn1t-1624161294774)(./img/业务对象.jpg)]

相关


2 保持居中

如有副作用,欢迎交流

期望效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wIvYGrhj-1626190260529)(./img/居中.gif)]

实际上,画布在快速改变的第一时间拿到的是缓存的尺寸。导致居中计算不正确。如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O2A7qAlg-1626190260531)(./img/偶尔居中.gif)]

解决方法,每次拿最新的画布尺寸。即重写一些居中的方法。
关键代码: https://github.com/bpmn-io/diagram-js/blob/develop/lib/core/Canvas.js#L976

Canvas.prototype._fitViewport = function(center) {
  // var vbox = this.viewbox() 修改成如下
  var vbox = this.viewbox(false)
  // ...
}
Canvas.prototype.viewbox = function(box) {
  // 由此可看到,当 box 不传值时,默认拿到的是缓存
  if (box === undefined && this._cachedViewbox) {
    return this._cachedViewbox
  }
  // ...
  // 入参为 false 将走进这个判断,获取最新的画布尺寸。
  if (!box) {
  }
}

完整代码:

import {
  addResizeListener,
  removeResizeListener
} from 'element-ui/src/utils/resize-event'

export default {
  mounted() {
    addResizeListener(this.$refs.canvas, this.resizeListener)
  },
  beforeDestroy() {
    removeResizeListener(this.$refs.canvas, this.resizeListener)
  },
  resizeListener() {
    const canvas = this.bpmnModeler.get('canvas')
    _fitViewport.call(canvas, true)
  }
}

function _fitViewport(center) {
  var vbox = this.viewbox(false)
  var outer = vbox.outer
  var inner = vbox.inner
  var newScale
  var newViewbox

  if (
    inner.x >= 0 &&
    inner.y >= 0 &&
    inner.x + inner.width <= outer.width &&
    inner.y + inner.height <= outer.height &&
    !center
  ) {
    newViewbox = {
      x: 0,
      y: 0,
      width: Math.max(inner.width + inner.x, outer.width),
      height: Math.max(inner.height + inner.y, outer.height)
    }
  } else {
    newScale = Math.min(
      1,
      outer.width / inner.width,
      outer.height / inner.height
    )
    newViewbox = {
      x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0),
      y:
        inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0),
      width: outer.width / newScale,
      height: outer.height / newScale
    }
  }

  this.viewbox(newViewbox)

  return this.viewbox(false).scale
}

提交记录
https://github.com/PL-FE/bpmn-doc/commit/b1b30513ada0682ac1bb26e2d1dad05518f00fb4

3 元素如何放大缩小

效果

在这里插入图片描述

https://github.com/philippfromme/camunda-modeler-plugin-resize-tasks
https://github.com/ElCondor1969/bpmn-js-task-resize

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_pengliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值