//import ColorRenderer from '../colors/ColorRenderer';
|
import BpmnRenderer from 'bpmn-js/lib/draw/BpmnRenderer';
|
//import BaseRenderer from 'diagram-js/lib/draw/BaseRenderer';
|
//import { getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
|
|
import {
|
getFillColor,
|
getStrokeColor
|
} from 'bpmn-js/lib/draw/BpmnRenderUtil';
|
|
import {
|
append as svgAppend,
|
attr as svgAttr,
|
classes as svgClasses,
|
create as svgCreate,
|
remove as svgRemove
|
} from 'tiny-svg';
|
|
import {
|
isObject,
|
forEach,
|
assign
|
} from 'min-dash';
|
|
import {
|
//rotate,
|
transform,
|
//translate
|
} from 'diagram-js/lib/util/SvgTransformUtil';
|
|
import {
|
createLine
|
} from 'diagram-js/lib/util/RenderUtil';
|
|
import {
|
isExpanded,
|
isEventSubProcess
|
} from 'bpmn-js/lib/util/DiUtil';
|
|
const HIGH_PRIORITY = 2500,
|
TASK_BORDER_RADIUS = 2;
|
|
export default class MultilangRenderer extends BpmnRenderer {
|
|
constructor(config, eventBus, styles, pathMap,
|
canvas, textRenderer, injector) {
|
|
super(config, eventBus, styles, pathMap, canvas, textRenderer, HIGH_PRIORITY);
|
|
var DEFAULT_FILL_OPACITY = .95,
|
HIGH_FILL_OPACITY = .35;
|
|
var defaultFillColor = config && config.defaultFillColor,
|
defaultStrokeColor = config && config.defaultStrokeColor,
|
computeStyle = styles.computeStyle,
|
handlers = this.handlers,
|
me = this;
|
|
eventBus.on('diagram.clear', function() {
|
me.elCount = 0;
|
me.participantCount = 0;
|
});
|
|
function renderer(type) {
|
return handlers[type];
|
}
|
|
function getLangText(element) {
|
var semantic = getSemantic(element);
|
var lang = injector.get('bpmnjs').getLang();
|
return semantic.get(`text_${lang}`)
|
}
|
|
function getSemantic(element) {
|
return element.businessObject;
|
}
|
|
function renderEmbeddedLabel(parentGfx, element, align) {
|
return renderLabel(parentGfx, getLangText(element), {
|
box: element,
|
align: align,
|
padding: 5,
|
style: {
|
fill: getStrokeColor(element, defaultStrokeColor)
|
}
|
});
|
}
|
|
function renderLabel(parentGfx, label, options) {
|
|
options = assign({
|
size: {
|
width: 100
|
}
|
}, options);
|
|
var text = textRenderer.createText(label || '', options);
|
|
svgClasses(text).add('djs-label');
|
|
svgAppend(parentGfx, text);
|
|
return text;
|
}
|
|
function renderNumLabel(parentGfx, text, element) {
|
if (!text) {
|
return;
|
}
|
|
var textBox = renderLabel(parentGfx, text, {
|
box: {
|
height: 15,
|
width: element.height
|
},
|
align: 'left-top',
|
padding: 3,
|
style: {
|
fill: getStrokeColor(element, defaultStrokeColor)
|
}
|
});
|
}
|
|
function attachTaskMarkers(parentGfx, element, taskMarkers) {
|
var obj = getSemantic(element);
|
|
var subprocess = taskMarkers && taskMarkers.indexOf('SubProcessMarker') !== -1;
|
var position;
|
|
if (subprocess) {
|
position = {
|
seq: -21,
|
parallel: -22,
|
compensation: -42,
|
loop: -18,
|
adhoc: 10
|
};
|
} else {
|
position = {
|
seq: -3,
|
parallel: -6,
|
compensation: -27,
|
loop: 0,
|
adhoc: 10
|
};
|
}
|
|
forEach(taskMarkers, function (marker) {
|
renderer(marker)(parentGfx, element, position);
|
});
|
|
if (obj.isForCompensation) {
|
renderer('CompensationMarker')(parentGfx, element, position);
|
}
|
|
if (obj.$type === 'bpmn:AdHocSubProcess') {
|
renderer('AdhocMarker')(parentGfx, element, position);
|
}
|
|
var loopCharacteristics = obj.loopCharacteristics,
|
isSequential = loopCharacteristics && loopCharacteristics.isSequential;
|
|
if (loopCharacteristics) {
|
|
if (isSequential === undefined) {
|
renderer('LoopMarker')(parentGfx, element, position);
|
}
|
|
if (isSequential === false) {
|
renderer('ParallelMarker')(parentGfx, element, position);
|
}
|
|
if (isSequential === true) {
|
renderer('SequentialMarker')(parentGfx, element, position);
|
}
|
}
|
}
|
|
function renderLaneLabel(parentGfx, text, element) {
|
var textBox = renderLabel(parentGfx, text, {
|
box: {
|
height: 30,
|
width: element.height
|
},
|
align: 'center-middle',
|
style: {
|
fill: getStrokeColor(element, defaultStrokeColor)
|
}
|
});
|
|
var top = -1 * element.height;
|
|
transform(textBox, 0, -top, 270);
|
}
|
|
function drawRect(parentGfx, width, height, r, offset, attrs) {
|
|
if (isObject(offset)) {
|
attrs = offset;
|
offset = 0;
|
}
|
|
offset = offset || 0;
|
|
attrs = computeStyle(attrs, {
|
stroke: 'black',
|
strokeWidth: 2,
|
fill: 'white'
|
});
|
|
var rect = svgCreate('rect');
|
svgAttr(rect, {
|
x: offset,
|
y: offset,
|
width: width - offset * 2,
|
height: height - offset * 2,
|
rx: r,
|
ry: r
|
});
|
svgAttr(rect, attrs);
|
|
svgAppend(parentGfx, rect);
|
|
return rect;
|
}
|
|
function drawPath(parentGfx, d, attrs) {
|
|
attrs = computeStyle(attrs, ['no-fill'], {
|
strokeWidth: 2,
|
stroke: 'black'
|
});
|
|
var path = svgCreate('path');
|
svgAttr(path, { d: d });
|
svgAttr(path, attrs);
|
|
svgAppend(parentGfx, path);
|
|
return path;
|
}
|
|
function drawLine(parentGfx, waypoints, attrs) {
|
attrs = computeStyle(attrs, ['no-fill'], {
|
stroke: 'black',
|
strokeWidth: 2,
|
fill: 'none'
|
});
|
|
var line = createLine(waypoints, attrs);
|
|
svgAppend(parentGfx, line);
|
|
return line;
|
}
|
|
this.renderNumLabel = renderNumLabel;
|
|
this.handlers['bpmn:Task'] = function (parentGfx, element) {
|
|
var attrs = {
|
fill: getFillColor(element, defaultFillColor),
|
stroke: getStrokeColor(element, defaultStrokeColor)
|
};
|
|
var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
|
|
renderEmbeddedLabel(parentGfx, element, 'center-middle');
|
attachTaskMarkers(parentGfx, element);
|
|
return rect;
|
}
|
|
this.handlers['bpmn:Participant'] = function (parentGfx, element) {
|
|
var attrs = {
|
fillOpacity: DEFAULT_FILL_OPACITY,
|
fill: getFillColor(element, defaultFillColor),
|
stroke: getStrokeColor(element, defaultStrokeColor)
|
};
|
|
var lane = renderer('bpmn:Lane')(parentGfx, element, attrs);
|
|
var expandedPool = isExpanded(element);
|
|
if (expandedPool) {
|
drawLine(parentGfx, [
|
{ x: 30, y: 0 },
|
{ x: 30, y: element.height }
|
], {
|
stroke: getStrokeColor(element, defaultStrokeColor)
|
});
|
var text = getLangText(element);
|
renderLaneLabel(parentGfx, text, element);
|
} else {
|
|
// Collapsed pool draw text inline
|
var text2 = getLangText(element);
|
renderLabel(parentGfx, text2, {
|
box: element, align: 'center-middle',
|
style: {
|
fill: getStrokeColor(element, defaultStrokeColor)
|
}
|
});
|
}
|
|
var participantMultiplicity = !!(getSemantic(element).participantMultiplicity);
|
|
if (participantMultiplicity) {
|
renderer('ParticipantMultiplicityMarker')(parentGfx, element);
|
}
|
|
return lane;
|
}
|
|
this.handlers['bpmn:Lane'] = function (parentGfx, element, attrs) {
|
var rect = drawRect(parentGfx, element.width, element.height, 0, assign({
|
fill: getFillColor(element, defaultFillColor),
|
fillOpacity: HIGH_FILL_OPACITY,
|
stroke: getStrokeColor(element, defaultStrokeColor)
|
}, attrs));
|
var semantic = getSemantic(element);
|
if (semantic.$type === 'bpmn:Lane') {
|
renderLaneLabel(parentGfx, getLangText(element), element);
|
}
|
|
return rect;
|
}
|
|
this.handlers['bpmn:TextAnnotation'] = function (parentGfx, element) {
|
var style = {
|
'fill': 'none',
|
'stroke': 'none'
|
};
|
|
var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style);
|
|
var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', {
|
xScaleFactor: 1,
|
yScaleFactor: 1,
|
containerWidth: element.width,
|
containerHeight: element.height,
|
position: {
|
mx: 0.0,
|
my: 0.0
|
}
|
});
|
|
drawPath(parentGfx, textPathData, {
|
stroke: getStrokeColor(element, defaultStrokeColor)
|
});
|
|
var text = getLangText(element);
|
renderLabel(parentGfx, text, {
|
box: element,
|
align: 'left-top',
|
padding: 5,
|
style: {
|
fill: getStrokeColor(element, defaultStrokeColor)
|
}
|
});
|
|
return textElement;
|
}
|
|
this.handlers['bpmn:SubProcess'] = function (parentGfx, element, attrs) {
|
attrs = assign({
|
fill: getFillColor(element, defaultFillColor),
|
stroke: getStrokeColor(element, defaultStrokeColor)
|
}, attrs);
|
|
var rect = renderer('bpmn:Activity')(parentGfx, element, attrs);
|
|
var expanded = isExpanded(element);
|
|
if (isEventSubProcess(element)) {
|
svgAttr(rect, {
|
strokeDasharray: '1,2'
|
});
|
}
|
|
renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle');
|
|
if (expanded) {
|
attachTaskMarkers(parentGfx, element);
|
} else {
|
attachTaskMarkers(parentGfx, element, ['SubProcessMarker']);
|
}
|
|
return rect;
|
}
|
}
|
|
}
|
|
MultilangRenderer.$inject = [
|
'config.bpmnRenderer',
|
'eventBus',
|
'styles',
|
'pathMap',
|
'canvas',
|
'textRenderer',
|
'injector'
|
];
|
|
MultilangRenderer.prototype.drawShape = function (parentGfx, element) {
|
var type = element.type;
|
var h = this.handlers[type];
|
|
const shape = h(parentGfx, element);
|
|
this.participantCount = this.participantCount || 0;
|
this.elCount = this.elCount || 0;
|
|
if (element.type != 'label') {
|
svgAttr(shape, {
|
fill: getCustomColor(element) || '#ffffff'
|
});
|
if (!element.renderNum) {
|
if (element.type == 'bpmn:Participant') {
|
element.renderNum = ++this.participantCount + '';
|
this.elCount = 0;
|
} else {
|
if (element.type != 'bpmn:TextAnnotation') {
|
element.renderNum = this.participantCount + '.' + (++this.elCount);
|
}
|
}
|
}
|
this.renderNumLabel(parentGfx, element.renderNum, element);
|
} else {
|
svgAttr(shape, {
|
fill: getCustomColor(element) || '#000000'
|
});
|
}
|
|
return shape;
|
};
|
|
function getCustomColor(element) {
|
var bo = element.businessObject;
|
return bo.di.get('color:background-color');
|
}
|