import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer' import { append as svgAppend, create as svgCreate } from 'tiny-svg' import notify from '@/assets/notify.png' import userTask from '@/assets/userIcon.png' import serviceTask from '@/assets/serviceTask.png' const HIGH_PRIORITY = 1500 const customConfig = { notify: { url: notify, attr: { x: 0, y: 0, width: 100, height: 80 } }, userTask: { url: userTask, attr: { x: 6, y: 6, width: 18, height: 18 } }, serviceTask: { url: serviceTask, attr: { x: 15, y: 5, width: 70, height: 70 } } } const customElements = ['bpmn:ServiceTask'] export default class CustomRenderer extends BaseRenderer { constructor(eventBus, bpmnRenderer) { super(eventBus, HIGH_PRIORITY) this.bpmnRenderer = bpmnRenderer } canRender(element) { return !element.labelTarget } drawShape(parentNode, element) { const type = element.type // 获取到类型 // 所有节点都会走这个函数,所以此时只限制,需要自定义的才去自定义,否则仍显示bpmn默认图标 // 更换用户任务图标 if (element.type === 'bpmn:UserTask') { const { url, attr } = customConfig['userTask'] const customIcon = svgCreate('rect', { fill: '#fff', x: 0, y: 0, rx: 12, ry: 12, width: 100, height: 80, stroke: 'black', strokeWidth: '2' }) svgAppend(parentNode, customIcon) const icon = svgCreate('image', attr) attr.href = url svgAppend(parentNode, icon) // 下方为更改节点名称位置(防止图片遮盖节点的文字) if (element.businessObject.name) { const text = svgCreate('text', { class: 'djs-label-custom', 'font-size': '15px', 'font-family': 'Arial, sans-serif', 'font-weight': 'normal', fill: 'black', x: 0, y: 0 // 位置可以随意调,我理解此时的attr.y 是此时元素的左上角纵坐标 }) const nameStr = element.businessObject.name let str = '' for (let i = 0; i < nameStr.length / 6; i++) { const temp = nameStr.substr(i * 6, 6) const x = (100 - temp.length * 16) / 2 const y = 40 + i * 20 str += `<tspan x=${x} y=${y}>${temp}</tspan>` } text.innerHTML = str svgAppend(parentNode, text) } // 结束 return customIcon } // let custom = null // if (element.type === 'bpmn:ServiceTask') { // const extensionElements = element.businessObject.extensionElements // if (extensionElements) { // const property = extensionElements.values // if (property && property.length) { // property.forEach(el => { // if (el.$children && el.$children.length) { // custom = el.$children.find((item) => { // return item.name === 'custom' // }) // } // }) // } // } // } if (customElements.includes(type)) { const { url, attr } = customConfig['serviceTask'] attr.href = url const customIcon = svgCreate('image', attr) element['width'] = attr.width element['height'] = attr.height svgAppend(parentNode, customIcon) // 结束 return customIcon } const shape = this.bpmnRenderer.drawShape(parentNode, element) return shape } getShapePath(shape) { return this.bpmnRenderer.getShapePath(shape) } } CustomRenderer.$inject = ['eventBus', 'bpmnRenderer']