天天看點

【bpmn.js 使用總結】十、答疑

答疑 (持續更新)

文章目錄

    • 答疑 (持續更新)
    • 1 如何自定義 id
      • 相關
    • 2 保持居中
    • 3 元素如何放大縮小

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/

如果我寫的不是很清楚,那麼這裡有一些極簡例子選擇業務對象

【bpmn.js 使用總結】十、答疑

相關

  • Modeler
  • bpmn-doc 文檔

2 保持居中

如有副作用,歡迎交流

期望效果:

【bpmn.js 使用總結】十、答疑

實際上,畫布在快速改變的第一時間拿到的是緩存的尺寸。導緻居中計算不正确。如下

【bpmn.js 使用總結】十、答疑

解決方法,每次拿最新的畫布尺寸。即重寫一些居中的方法。

關鍵代碼: 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 元素如何放大縮小

效果

【bpmn.js 使用總結】十、答疑

https://github.com/philippfromme/camunda-modeler-plugin-resize-tasks

https://github.com/ElCondor1969/bpmn-js-task-resize

繼續閱讀