@syncfusion/ej2-diagrams
Version:
Feature-rich diagram control to create diagrams like flow charts, organizational charts, mind maps, and BPMN diagrams. Its rich feature set includes built-in shapes, editing, serializing, exporting, printing, overview, data binding, and automatic layouts.
1,054 lines (1,053 loc) • 143 kB
JavaScript
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable jsdoc/require-returns */
/* eslint-disable jsdoc/require-param */
/* eslint-disable valid-jsdoc */
/* eslint-disable @typescript-eslint/ban-types */
import { Lane } from './../objects/node';
import { DiagramElement } from './../core/elements/diagram-element';
import { Canvas } from './../core/containers/canvas';
import { GroupableView } from './../core/containers/container';
import { PathElement } from './../core/elements/path-element';
import { TextElement } from './../core/elements/text-element';
import { updateStyle } from './../../diagram/utility/diagram-util';
import { randomId, cloneObject } from './../utility/base-util';
import { Diagram } from './../../diagram/diagram';
import { Transform, DiagramAction } from '../enum/enum';
import { findAngle, getPortDirection } from '../utility/connector';
import { Point } from '../primitives/point';
import { NodeConstraints } from '../enum/enum';
import { PointPort } from './../objects/port';
import { Rect } from '../primitives/rect';
import { Size } from '../primitives/size';
import { getDiagramElement } from '../utility/dom-util';
import { isBlazor } from '@syncfusion/ej2-base';
import { removeElement } from '../utility/dom-util';
/**
* BPMN Diagrams contains the BPMN functionalities
*/
var BpmnDiagrams = /** @class */ (function () {
//End size region
/**
* Constructor for the BpmnDiagrams module
*
* @private
*/
function BpmnDiagrams() {
//Code conversion for Bpmn Shapes
//Start Region
/** @private */
this.bpmnTextAnnotationConnector = [];
//constructs the BpmnDiagrams module
}
/** @private */
BpmnDiagrams.prototype.getSize = function (node, content) {
var size = new Size(node.width, node.height);
if (!(content instanceof PathElement)) {
size.width = size.width || 50;
size.height = size.height || 50;
}
if (content.actualSize.width && content.actualSize.height) {
return content.actualSize;
}
else {
content.measure(new Size());
size.width = size.width || content.desiredSize.width;
size.height = size.height || content.desiredSize.height;
}
if (node.maxWidth !== undefined) {
size.width = Math.min(size.width, node.maxWidth);
}
if (node.maxHeight !== undefined) {
size.height = Math.min(size.height, node.maxHeight);
}
if (node.minWidth !== undefined) {
size.width = Math.max(size.width, node.minWidth);
}
if (node.minHeight !== undefined) {
size.height = Math.max(size.height, node.minHeight);
}
return size;
};
/** @private */
BpmnDiagrams.prototype.initBPMNContent = function (content, node, diagram) {
var shape = node.shape;
var bpmnShape = node.shape.shape;
if (bpmnShape === 'Event') {
content = this.getBPMNEventShape(node, shape.event);
}
if (bpmnShape === 'Gateway') {
content = this.getBPMNGatewayShape(node);
}
if (bpmnShape === 'DataObject') {
content = this.getBPMNDataObjectShape(node);
}
if (bpmnShape === 'Message' || bpmnShape === 'DataSource') {
content = this.getBPMNShapes(node);
}
//848061-BPMN Group shape to be function Like Subprocess Node
if (bpmnShape === 'Group') {
//854195 - bpmn group serialization issue
content = this.getBPMNGroup(node, diagram);
content.style.strokeDashArray = node.style.strokeDashArray !== '' ? node.style.strokeDashArray : '2 2 6 2';
content.cornerRadius = 10;
}
if (bpmnShape === 'Activity') {
content = this.getBPMNActivityShape(node);
}
//Task 866412: Should revamp BPMN text annotation node.
if (bpmnShape === 'TextAnnotation') {
if (node.parentObj instanceof Diagram || node.parentObj instanceof Lane) {
content = this.getBpmnTextAnnotationShape(node, node.shape, diagram);
}
else {
content = this.getBpmnTextAnnotationSymbol(node, node.shape, diagram);
}
}
return content;
};
BpmnDiagrams.prototype.getBpmnTextAnnotationShape = function (textAnnotation, bpmnTextAnnotation, diagram) {
var annotationsContainer = new Canvas();
annotationsContainer.measureChildren = false;
annotationsContainer.offsetX = textAnnotation.offsetX;
annotationsContainer.offsetY = textAnnotation.offsetY;
annotationsContainer.float = true;
annotationsContainer.id = textAnnotation.id + "_textannotation";
annotationsContainer.style.strokeColor = 'transparent';
annotationsContainer.style.fill = 'transparent';
annotationsContainer.relativeMode = 'Object';
annotationsContainer.rotateAngle = 0;
var width = textAnnotation.width;
var height = textAnnotation.height;
var bounds = new Rect(0, 0, 0, 0);
if (width !== 0 && height !== 0) {
bounds = new Rect(textAnnotation.offsetX - width / 2, textAnnotation.offsetY - height / 2, width, height);
}
var oldIsProtectedOnChange = diagram.isProtectedOnChange;
diagram.isProtectedOnChange = false;
this.setAnnotationPath(bounds, annotationsContainer, textAnnotation, bpmnTextAnnotation, bpmnTextAnnotation.textAnnotation.textAnnotationDirection, diagram);
diagram.isProtectedOnChange = oldIsProtectedOnChange;
return annotationsContainer;
};
//Task 866412: Should revamp BPMN text annotation node. To render text annotation in symbol palette.
BpmnDiagrams.prototype.getBpmnTextAnnotationSymbol = function (annotation, bpmnTextAnnotation, diagram) {
var data = 'M33.33,15 L0,43 M39.33,0 L33.33,0 L33.33,30 L39.33,30 M60,0';
if (bpmnTextAnnotation.textAnnotation.textAnnotationDirection === 'Top') {
data = 'M15,33.33 L43,0 M0,39.33 L0,33.33 L30,33.33 L30,39.33 M0,60';
}
else if (bpmnTextAnnotation.textAnnotation.textAnnotationDirection === 'Right') {
data = 'M6,15 L39.33,43 M0,0 L6,0 L6,30 L0,30 M-20,0';
}
else if (bpmnTextAnnotation.textAnnotation.textAnnotationDirection === 'Bottom') {
data = 'M15,6 L43,39.33 M0,0 L0,6 L30,6 L30,0 M0,-20';
}
var path = new PathElement();
path.data = data;
path.style.fill = ((annotation.style.fill === 'white') ? 'transparent' : annotation.style.fill);
path.style.strokeDashArray = (annotation.style.strokeDashArray ? annotation.style.strokeDashArray : '');
path.style.strokeWidth = annotation.style.strokeWidth;
path.style.strokeColor = ((annotation.style.strokeColor === 'transparent') ? 'black' : annotation.style.strokeColor);
path.style.opacity = annotation.style.opacity;
return path;
};
/** @private */
BpmnDiagrams.prototype.getBPMNShapes = function (node) {
var bpmnShape = new PathElement();
//set style
this.setStyle(bpmnShape, node);
//941052: Issue with visible property doesn't hide shadows
if ((node.constraints & NodeConstraints.Shadow) !== 0 && node.visible) {
bpmnShape.shadow = node.shadow;
}
var bpmnShapeData = getBpmnShapePathData(node.shape.shape);
bpmnShape.data = bpmnShapeData;
bpmnShape.id = node.id + '_' + node.shape.shape;
if (node.width !== undefined && node.height !== undefined) {
bpmnShape.width = node.width;
bpmnShape.height = node.height;
}
return bpmnShape;
};
//854195 - Method to add the children as canvas in the Bpmn group node container
/** @private */
BpmnDiagrams.prototype.getBPMNGroup = function (node, diagram) {
var group = new Canvas();
//set style
this.setStyle(group, node);
group.id = node.id + '_group';
if (!group.children) {
group.children = [];
}
var groupShapeObj = (node.shape.group);
if (node.shape.group) {
for (var i = 0; i < groupShapeObj.children.length; i++) {
var child = diagram.nameTable[groupShapeObj.children[parseInt(i.toString(), 10)]];
group.children.push(child.wrapper);
}
}
group.width = node.width;
group.height = node.height;
return group;
};
/** @private */
BpmnDiagrams.prototype.getBPMNGatewayShape = function (node) {
var gatewayshape = new Canvas();
//childNode0
var gatewayNode = new PathElement();
gatewayNode.id = node.id + '_0_gateway';
gatewayNode.offsetX = node.offsetX;
gatewayNode.offsetY = node.offsetY;
gatewayNode.data = 'M 40 20 L 20 40 L 0 20 L 20 0 L 40 20 Z';
this.setStyle(gatewayNode, node);
//childNode1
var gatewayTypeNode = new PathElement();
gatewayTypeNode.id = node.id + '_1_gatewayType';
//set style - opacity
gatewayTypeNode.style.opacity = node.style.opacity;
gatewayTypeNode.style.strokeColor = node.style.strokeColor;
gatewayTypeNode.horizontalAlignment = 'Center';
gatewayTypeNode.verticalAlignment = 'Center';
gatewayTypeNode.relativeMode = 'Object';
var shapeType = node.shape.gateway;
//let gatewayTypeNodeShapeData: string;
var gatewayTypeNodeShapeData = getBpmnGatewayShapePathData(shapeType.type);
if (shapeType.type === 'EventBased' || shapeType.type === 'ExclusiveEventBased' || shapeType.type === 'ParallelEventBased') {
gatewayTypeNode.style.fill = 'white';
}
else {
gatewayTypeNode.style.fill = 'black';
}
gatewayTypeNode.data = gatewayTypeNodeShapeData;
// append child and set style
gatewayshape.style.fill = 'transparent';
gatewayshape.style.strokeColor = 'transparent';
gatewayshape.style.strokeWidth = 0;
gatewayshape.children = [gatewayNode, gatewayTypeNode];
var size = this.getSize(node, gatewayNode);
this.setSizeForBPMNGateway(node.shape.gateway, gatewayshape, size.width, size.height);
return gatewayshape;
};
/** @private */
BpmnDiagrams.prototype.getBPMNDataObjectShape = function (node) {
var dataObjectshape = new Canvas();
var shape = node.shape.dataObject;
//childNode0
var dataobjNode = new PathElement();
dataobjNode.id = node.id + '_0_dataobj';
dataobjNode.data = 'M29.904,5 L7.853,5 L7.853,45 L42.147,45 L42.147,17.242,L29.932,5,L29.932,17.242,L42.147,17.242';
var size = this.getSize(node, dataobjNode);
dataobjNode.width = size.width;
dataobjNode.height = size.height;
this.setStyle(dataobjNode, node);
//childNode1
var dataobjTypeNode = new PathElement();
dataobjTypeNode.id = node.id + '_1_type';
dataobjTypeNode.width = 25;
dataobjTypeNode.height = 20;
dataobjTypeNode.margin.left = 5;
dataobjTypeNode.margin.top = 5;
dataobjTypeNode.data = 'M 3 9.4 l 6 0 v 2.4 l 3.6 -4 L 9 4 v 2.5 H 3 V 9.4 Z';
//set style - opacity
dataobjTypeNode.style.opacity = node.style.opacity;
//childNode2
var dataobjCollectionNode = new PathElement();
dataobjCollectionNode.id = node.id + '_2_collection';
dataobjCollectionNode.width = 7.5;
dataobjCollectionNode.height = 15;
dataobjCollectionNode.style.fill = 'black';
dataobjCollectionNode.visible = true;
dataobjCollectionNode.horizontalAlignment = 'Center';
dataobjCollectionNode.verticalAlignment = 'Bottom';
dataobjCollectionNode.relativeMode = 'Object';
//set style - opacity
dataobjCollectionNode.style.opacity = node.style.opacity;
dataobjCollectionNode.data = 'M 0 0 L 0.1 0 L 0.1 2 L 0 2 Z M 0.4 0 L 0.6 0 L 0.6 2 L0.4 2 Z M 0.9 0 L 1 0 L 1 2 L 0.9 2 Z';
switch (shape.type) {
case 'None':
dataobjTypeNode.visible = false;
break;
case 'Input':
dataobjTypeNode.style.fill = 'white';
break;
case 'Output':
dataobjTypeNode.style.fill = 'black';
break;
}
if (shape.collection === false) {
dataobjCollectionNode.visible = false;
}
//append child and set style
dataObjectshape.style.fill = 'transparent';
dataObjectshape.style.strokeColor = 'transparent';
dataObjectshape.style.strokeWidth = 0;
dataObjectshape.children = [dataobjNode, dataobjTypeNode, dataobjCollectionNode];
return dataObjectshape;
};
/** @private */
BpmnDiagrams.prototype.getBPMNTaskShape = function (node) {
var shape = node.shape.activity;
var task = shape.task;
var taskShapes = new Canvas();
//childNode0
var taskNode = new DiagramElement();
taskNode.cornerRadius = 10;
var size = this.getSize(node, taskNode);
taskNode.id = node.id + '_0_task';
taskNode.width = size.width;
taskNode.height = size.height;
this.setStyle(taskNode, node);
// if task as call
if ((task.call !== undefined) && task.call === true) {
taskNode.style.strokeWidth = 4;
}
taskShapes.width = size.width;
taskShapes.height = size.height;
var childCount = this.getTaskChildCount(node);
var x;
var childSpace = childCount * 12;
var area = size.width / 2 - childSpace;
if (childCount === 1) {
x = area + 8;
}
else {
x = area + (childCount - 1) * 8;
}
//childNode1
var taskTypeNode = new PathElement();
if (task.type === 'Receive' || task.type === 'Send') {
taskTypeNode.width = 18;
taskTypeNode.height = 16;
}
else if (task.type === 'Manual') {
taskTypeNode.width = 16;
taskTypeNode.height = 11;
}
else {
taskTypeNode.width = 20;
taskTypeNode.height = 20;
}
taskTypeNode.id = node.id + '_1_tasktType';
taskTypeNode.margin.left = 5;
taskTypeNode.margin.top = 5;
task.type = task.type || 'None';
var taskTypeNodeData = getBpmnTaskShapePathData(task.type);
taskTypeNode.data = taskTypeNodeData;
taskTypeNode.style.fill = 'transparent';
taskTypeNode.style.opacity = node.style.opacity;
if (task.type === 'Send') {
taskTypeNode.style.fill = 'black';
}
// append child and set style
taskShapes.style.fill = 'transparent';
taskShapes.style.strokeColor = 'transparent';
taskShapes.style.strokeWidth = 0;
taskShapes.children = [taskNode, taskTypeNode];
//childnode for service
if (task.type === 'Service') {
var taskTypeNodeService = new PathElement();
taskTypeNodeService.id = node.id + '_1_taskTypeService';
taskTypeNodeService.data = taskTypeNodeData;
taskTypeNodeService.margin.left = taskTypeNode.margin.left + 9;
taskTypeNodeService.margin.top = taskTypeNode.margin.top + 9;
taskTypeNodeService.style.fill = 'white';
taskTypeNodeService.style.opacity = node.style.opacity;
taskShapes.children.push(taskTypeNodeService);
}
// if task as loop
var loopType = task.loop;
var taskLoopNode = new PathElement(); //let childNode2data: string;
var childNode2data = getBpmnLoopShapePathData(loopType);
taskLoopNode.data = childNode2data;
taskLoopNode.style.fill = 'black';
if (loopType !== 'None') {
taskLoopNode.visible = true;
}
else {
taskLoopNode.visible = false;
}
if (childCount === 1) {
x = area + 9;
}
//891296: Position of BPMN activity loop node is not proper while save and load
taskLoopNode.margin.left = x - 3;
if (taskLoopNode.visible === true) {
x += 12 + 8;
}
taskLoopNode.width = 12;
taskLoopNode.height = 12;
taskLoopNode.margin.bottom = 5;
taskLoopNode.id = node.id + '_2_loop';
taskLoopNode.horizontalAlignment = 'Left';
taskLoopNode.verticalAlignment = 'Bottom';
taskLoopNode.setOffsetWithRespectToBounds(0, 1, 'Fraction');
taskLoopNode.relativeMode = 'Point';
taskLoopNode.style.fill = 'transparent';
taskTypeNode.style.opacity = node.style.opacity;
taskShapes.children.push(taskLoopNode);
//if task as compensation
var taskCompNode = new PathElement();
taskCompNode = this.getBPMNCompensationShape(node, taskCompNode);
if (task.compensation === true) {
taskCompNode.visible = true;
}
else {
taskCompNode.visible = false;
}
if (childCount === 1) {
x = area + 9;
}
taskCompNode.margin.left = x - 3;
x += 12 + 6;
taskShapes.children.push(taskCompNode);
return taskShapes;
};
/** @private */
BpmnDiagrams.prototype.getBPMNEventShape = function (node, subEvent, sub, id) {
var eventshape = new Canvas();
var event;
var trigger;
var width;
var height;
id = id || node.id;
var pathdata = 'M164.1884,84.6909000000001C156.2414,84.6909000000001,149.7764,78.2259000000001,149.7764,70.2769000000001' +
'C149.7764,62.3279000000001,156.2414,55.8629000000001,164.1884,55.8629000000001C172.1354,55.8629000000001,178.6024,' +
'62.3279000000001,178.6024,70.2769000000001C178.6024,78.2259000000001,172.1354,84.6909000000001,164.1884,84.6909000000001';
var shapeEvent = node.shape.event;
if ((!isBlazor() && node.shape.shape === 'Event')) {
event = shapeEvent.event;
trigger = shapeEvent.trigger;
}
width = subEvent.width;
height = subEvent.height;
if (sub) {
width = width || 20;
height = height || 20;
}
else if (subEvent.width === undefined || subEvent.height === undefined) {
var pathElement = new PathElement();
pathElement.data = pathdata;
var size = this.getSize(node, pathElement);
width = size.width;
height = size.height;
}
var shapeActivity = node.shape.activity;
if ((!isBlazor() && node.shape.shape === 'Activity')) {
var subProcess = shapeActivity.subProcess;
event = subEvent.event;
trigger = subEvent.trigger;
}
//childNode0
var innerEvtNode = new PathElement();
innerEvtNode.data = pathdata;
innerEvtNode.id = id + '_0_event';
innerEvtNode.width = width;
innerEvtNode.height = height;
innerEvtNode.horizontalAlignment = 'Center';
innerEvtNode.verticalAlignment = 'Center';
innerEvtNode.relativeMode = 'Object';
this.setStyle(innerEvtNode, node);
//childNode1
var outerEvtNode = new PathElement();
outerEvtNode.data = pathdata;
outerEvtNode.id = id + '_1_event';
outerEvtNode.style.gradient = node.style.gradient;
outerEvtNode.horizontalAlignment = 'Center';
outerEvtNode.verticalAlignment = 'Center';
outerEvtNode.relativeMode = 'Object';
// set style opacity & strokeColor
outerEvtNode.style.strokeColor = node.style.strokeColor;
outerEvtNode.style.opacity = node.style.opacity;
//childNode2
var triggerNode = new PathElement();
var triggerNodeData = getBpmnTriggerShapePathData(trigger);
triggerNode.data = triggerNodeData;
triggerNode.id = id + '_2_trigger';
triggerNode.horizontalAlignment = 'Center';
triggerNode.verticalAlignment = 'Center';
triggerNode.relativeMode = 'Object';
// set style opacity & strokeColor
triggerNode.style.strokeColor = node.style.strokeColor;
triggerNode.style.opacity = node.style.opacity;
switch (event) {
case 'Start':
outerEvtNode.visible = false;
break;
case 'NonInterruptingStart':
innerEvtNode.style.strokeDashArray = '2 3';
outerEvtNode.visible = false;
break;
case 'Intermediate':
innerEvtNode.style.fill = node.style.fill;
innerEvtNode.style.gradient = null;
break;
case 'NonInterruptingIntermediate':
innerEvtNode.style.fill = node.style.fill;
innerEvtNode.style.gradient = null;
innerEvtNode.style.strokeDashArray = '2 3';
outerEvtNode.style.strokeDashArray = '2 3';
break;
case 'ThrowingIntermediate':
case 'End':
innerEvtNode.style.fill = event !== 'End' ? node.style.fill : node.style.fill !== 'white' ? node.style.fill : 'black';
innerEvtNode.style.gradient = null;
triggerNode.style.fill = 'black';
triggerNode.style.strokeColor = 'white';
break;
}
//append child and set style
eventshape.style.fill = 'transparent';
eventshape.style.strokeColor = 'transparent';
eventshape.style.strokeWidth = 0;
eventshape.children = [innerEvtNode, outerEvtNode, triggerNode];
this.setSizeForBPMNEvents(shapeEvent, eventshape, width, height);
return eventshape;
};
BpmnDiagrams.prototype.setEventVisibility = function (node, canvas) {
var event = node.shape.event.event;
var innerEvtNode = canvas[0];
var outerEvtNode = canvas[1];
var triggerNode = canvas[2];
switch (event) {
case 'Start':
outerEvtNode.visible = false;
break;
case 'NonInterruptingStart':
innerEvtNode.style.strokeDashArray = '2 3';
outerEvtNode.visible = false;
break;
}
};
BpmnDiagrams.prototype.setSubProcessVisibility = function (node) {
var subProcess = node.shape.activity.subProcess;
var eventLength = subProcess.events.length;
var index = (node.shape.activity.subProcess.type === 'Transaction') ? 2 : 0;
var elementWrapper = node.wrapper.children[0].children[0];
if (subProcess.adhoc === false) {
elementWrapper.children[3 + index + eventLength].visible = false;
}
if (subProcess.compensation === false) {
elementWrapper.children[4 + index + eventLength].visible = false;
}
if (eventLength > 0) {
for (var i = 0; i < eventLength; i++) {
this.setEventVisibility(node, elementWrapper.children[2 + i].children);
}
}
};
/** @private */
BpmnDiagrams.prototype.getBPMNSubProcessShape = function (node) {
var subProcessShapes = new Canvas();
var loopType;
var events;
var event;
var subprocessAdhoc = new PathElement();
var subProcessEventsShapes = new Canvas();
var subProcessLoopShapes = new PathElement();
var shape = node.shape.activity;
var subProcess = shape.subProcess;
var subChildCount = this.getSubprocessChildCount(node);
var x;
var subprocessNode = new DiagramElement();
subprocessNode.id = node.id + '_0_Subprocess';
subprocessNode.style.fill = 'transparent';
subprocessNode.cornerRadius = 10;
var size = this.getSize(node, subprocessNode);
subprocessNode.width = size.width;
subprocessNode.height = size.height;
subProcessShapes.children = [subprocessNode];
if (shape.subProcess.type === 'Transaction') {
this.getBPMNSubProcessTransaction(node, node.shape, subProcessShapes);
}
var iconSpace = 4;
var subChildSpace = 12;
var childSpace = subChildCount * subChildSpace;
var area = size.width / 2;
if (subChildCount === 1) {
x = area - (subChildSpace * 0.5);
}
else {
x = area - (childSpace / 2) - ((subChildCount - 1) * iconSpace) / 2;
}
//set style
this.setStyle(subprocessNode, node);
//941052: Issue with visible property doesn't hide shadows
if ((node.constraints & NodeConstraints.Shadow) !== 0 && node.visible) {
subProcessShapes.shadow = node.shadow;
}
var collapsedShape = new PathElement();
collapsedShape.id = node.id + '_0_collapsed';
collapsedShape.width = 12;
collapsedShape.height = 12;
collapsedShape.style.fill = 'black';
collapsedShape.style.strokeColor = node.style.strokeColor;
collapsedShape.margin.bottom = 5;
collapsedShape.style.opacity = node.style.opacity;
collapsedShape.horizontalAlignment = 'Left';
collapsedShape.verticalAlignment = 'Bottom';
collapsedShape.setOffsetWithRespectToBounds(0, 1, 'Fraction');
collapsedShape.relativeMode = 'Point';
collapsedShape.data = getBpmnShapePathData('collapsedShape');
collapsedShape.margin.left = x;
if (subProcess.collapsed === true && !subProcess.processes) {
collapsedShape.visible = true;
}
else {
collapsedShape.visible = false;
}
if (collapsedShape.visible === true) {
x += subChildSpace + iconSpace;
}
subProcessShapes.children.push(collapsedShape);
if (subProcess.type === 'Event') {
subprocessNode.style.strokeWidth = 1;
subprocessNode.style.strokeDashArray = '2 2';
events = subProcess.events;
for (var i = 0; i < events.length; i++) {
event = events[parseInt(i.toString(), 10)];
this.getBPMNSubEvent(event, node, subProcessShapes);
}
}
// set loop for subprocess
subProcessLoopShapes = this.getBPMNSubProcessLoopShape(node);
if (subChildCount === 1) {
x = area - 6;
}
subProcessLoopShapes.margin.left = x;
if (subProcessLoopShapes.visible === true) {
x += subChildSpace + iconSpace;
}
subProcessLoopShapes.style.opacity = node.style.opacity;
subProcessShapes.children.push(subProcessLoopShapes);
// set boundary for subprocess
subprocessNode.id = node.id + '_boundary';
if (subProcess.boundary === 'Default') {
//937170: Stroke width not applied after save and load
subprocessNode.style.strokeWidth = node.style.strokeWidth ? node.style.strokeWidth : 1;
subprocessNode.style.strokeDashArray = '1 0';
}
if (subProcess.boundary === 'Call') {
subprocessNode.style.strokeWidth = 4;
subprocessNode.style.strokeDashArray = '1 0';
}
if (subProcess.boundary === 'Event') {
subprocessNode.style.strokeWidth = node.style.strokeWidth ? node.style.strokeWidth : 1;
subprocessNode.style.strokeDashArray = '2 2';
}
//set adhoc for subprocess
subprocessAdhoc = this.getBPMNAdhocShape(node, subprocessAdhoc, subProcess);
if (subChildCount === 1) {
x = area - 6;
}
subprocessAdhoc.margin.left = x;
if (subprocessAdhoc.visible === true) {
x += subChildSpace + iconSpace;
}
subprocessAdhoc.style.opacity = node.style.opacity;
subProcessShapes.children.push(subprocessAdhoc);
//set compensation for subprocess
var subprocessComp = new PathElement();
if (subProcess.compensation === true) {
subprocessComp.visible = true;
}
else {
subprocessComp.visible = false;
}
subprocessComp = this.getBPMNCompensationShape(node, subprocessComp);
if (subChildCount === 1) {
x = area - 6;
}
subprocessComp.margin.left = x;
if (subprocessComp.visible === true) {
x += subChildSpace + iconSpace;
}
subprocessComp.style.opacity = node.style.opacity;
subProcessShapes.children.push(subprocessComp);
//set style for subprocess
subProcessShapes.style.strokeColor = 'transparent';
subProcessShapes.style.strokeWidth = 0;
subProcessShapes.style.fill = 'transparent';
return subProcessShapes;
};
BpmnDiagrams.prototype.getBPMNSubEvent = function (event, node, container, id) {
container.children = container.children || [];
//let eventContainer: Canvas;
var eventContainer = this.getBPMNEventShape(node, event, true, id);
this.getBPMNSubprocessEvent(node, eventContainer, event);
eventContainer.id = id || (node.id + '_subprocessEvents');
eventContainer.width = event.width || 20;
eventContainer.height = event.height || 20;
// set offset for subevents
eventContainer.setOffsetWithRespectToBounds(event.offset.x, event.offset.y, 'Fraction');
eventContainer.relativeMode = 'Point';
//set margin for subevents
eventContainer.margin = event.margin;
//set alignment for subevents
eventContainer.horizontalAlignment = event.horizontalAlignment;
eventContainer.verticalAlignment = event.verticalAlignment;
// set style for subevent
eventContainer.style.fill = 'transparent';
eventContainer.style.strokeColor = 'transparent';
eventContainer.style.strokeWidth = 0;
container.children.push(eventContainer);
};
BpmnDiagrams.prototype.getBPMNSubProcessTransaction = function (node, shape, container) {
var shapeWidth = container.children[0].width;
var shapeHeight = container.children[0].height;
var innerRect = new DiagramElement();
innerRect.margin = { left: 3, right: 0, top: 3, bottom: 0 };
innerRect.id = node.id + '_0_Subprocess_innnerRect';
innerRect.cornerRadius = 10;
innerRect.width = shapeWidth - 6;
//EJ2-824711 - Fill color is not applied properly for BPMN transaction subProcess.
innerRect.style.fill = 'transparent';
innerRect.height = shapeHeight - 6;
container.children.push(innerRect);
var transactionEvents = new Canvas();
transactionEvents.id = node.id + '_transaction_events';
transactionEvents.style.gradient = node.style.gradient;
var transaction = shape.activity.subProcess.transaction;
this.getBPMNSubEvent(transaction.success, node, transactionEvents, node.id + '_success');
this.getBPMNSubEvent(transaction.cancel, node, transactionEvents, node.id + '_cancel');
this.getBPMNSubEvent(transaction.failure, node, transactionEvents, node.id + '_failure');
this.updateDiagramContainerVisibility(transactionEvents.children[0], transaction.success.visible);
this.updateDiagramContainerVisibility(transactionEvents.children[1], transaction.cancel.visible);
this.updateDiagramContainerVisibility(transactionEvents.children[2], transaction.failure.visible);
transactionEvents.float = true;
transactionEvents.width = shapeWidth;
transactionEvents.height = shapeHeight;
transactionEvents.style.fill = transactionEvents.style.strokeColor = 'transparent';
container.children.push(transactionEvents);
};
/** @private */
BpmnDiagrams.prototype.getBPMNSubProcessLoopShape = function (node) {
var shape = node.shape.activity;
var loopType;
var subprocessLoop = new PathElement();
var subprocessLoopData;
var subProcess = shape.subProcess;
// eslint-disable-next-line prefer-const
loopType = subProcess.loop;
// eslint-disable-next-line prefer-const
subprocessLoopData = getBpmnLoopShapePathData(loopType);
if (loopType !== 'None') {
subprocessLoop.visible = true;
}
else {
subprocessLoop.visible = false;
}
subprocessLoop.id = node.id + '_loop';
subprocessLoop.data = subprocessLoopData;
subprocessLoop.style.fill = 'black';
subprocessLoop.width = 12;
subprocessLoop.height = 12;
subprocessLoop.horizontalAlignment = 'Left';
subprocessLoop.verticalAlignment = 'Bottom';
subprocessLoop.setOffsetWithRespectToBounds(0, 1, 'Fraction');
subprocessLoop.relativeMode = 'Point';
subprocessLoop.margin.bottom = 5;
subprocessLoop.style.fill = 'transparent';
subprocessLoop.style.strokeColor = node.style.strokeColor;
return subprocessLoop;
};
/** @private */
BpmnDiagrams.prototype.drag = function (obj, tx, ty, diagram) {
var node = diagram.nameTable[(obj).processId];
var oldLeft = obj.margin.left;
var oldTop = obj.margin.top;
//905286: Dragging bpmn node in subprocess using public method is not proper
var newMargin = {
top: obj.margin.top + ty >= 0 ? obj.margin.top + ty : obj.margin.top,
left: obj.margin.left + tx >= 0 ? obj.margin.left + tx : obj.margin.left
};
if (newMargin.top !== obj.margin.top || newMargin.left !== obj.margin.left) {
diagram.nodePropertyChange(obj, {}, { margin: newMargin });
}
if (diagram.eventHandler.currentAction !== 'Drag' &&
!diagram.eventHandler.isNudgeKey &&
!obj.hasTextAnnotation &&
(oldTop !== obj.margin.top || oldLeft !== obj.margin.left)) {
var newOffset = {
offsetX: obj.offsetX + tx >= 0 ? obj.offsetX + tx : obj.offsetX,
offsetY: obj.offsetY + ty >= 0 ? obj.offsetY + ty : obj.offsetY
};
diagram.nodePropertyChange(obj, {}, { offsetX: newOffset.offsetX, offsetY: newOffset.offsetY });
}
var bound = this.getChildrenBound(node, obj.id, diagram);
this.updateSubProcessess(bound, obj, diagram);
//For Subproceess connected with Text Annotation Drag and drop issue
var diffX = obj.margin.left - oldLeft;
var diffY = obj.margin.top - oldTop;
if (obj.outEdges.length !== 0) {
for (var i = 0; i < obj.outEdges.length; i++) {
var connector = diagram.nameTable[obj.outEdges[parseInt(i.toString(), 10)]];
if (connector && connector.shape.type === 'Bpmn' && connector.isBpmnAnnotationConnector) {
var targetNode = diagram.nameTable[connector.targetID];
var oldValue = { offsetX: targetNode.offsetX, offsetY: targetNode.offsetY };
targetNode.offsetX += diffX;
targetNode.offsetY += diffY;
var newValue = { offsetX: targetNode.offsetX, offsetY: targetNode.offsetY };
diagram.nodePropertyChange(targetNode, oldValue, newValue);
}
}
}
node.wrapper.measure(new Size(undefined, undefined));
node.wrapper.arrange(node.wrapper.desiredSize);
diagram.refreshCanvasLayers();
diagram.updateSelector();
//909205: The selector updates properly, but the node does not update correctly, so call the updateDiagramObject method.
diagram.updateDiagramObject(node);
//941048: The connectors not updates properly on redo, so call the updateConnectorEdges method.
diagram.updateConnectorEdges(obj);
this.updateDocks(obj, diagram);
};
/** @private */
BpmnDiagrams.prototype.dropBPMNchild = function (target, source, diagram) {
if (source && source.shape.type === 'Bpmn' && target.shape.type === 'Bpmn'
&& !isBlazor()) {
var subProcess = diagram.nameTable[target.id].shape.activity.subProcess;
if (diagram.currentSymbol && target.shape.type === 'Bpmn' && !subProcess.collapsed) {
source.processId = target.id;
return;
}
subProcess.processes = subProcess.processes || [];
if (subProcess.processes && subProcess.processes.indexOf(source.id) === -1 && !subProcess.collapsed) {
subProcess.processes.push(source.id);
// To arrange the process based on zIndex, which cause issue in save and load.
if (subProcess.processes.length > 1) {
this.sortProcessOrder(subProcess.processes, diagram);
}
var redoElement = cloneObject(source);
var sources = diagram.nameTable[source.id].wrapper;
var targetWrapper = diagram.nameTable[target.id].wrapper;
sources.margin.top = (sources.offsetY - (sources.actualSize.height / 2))
- (target.offsetY - (target.actualSize.height / 2));
sources.margin.left = (sources.offsetX - (sources.actualSize.width / 2))
- (target.offsetX - (target.actualSize.width / 2));
sources.margin.top = (sources.margin.top < 0) ? 0 : sources.margin.top;
sources.margin.left = (sources.margin.left < 0) ? 0 : sources.margin.left;
diagram.nameTable[source.id].processId = target.id;
targetWrapper.children.push(diagram.nameTable[source.id].wrapper);
//To identify the processess added at runtime.
//diagram.nameTable[source.id].wrapper.isDroppedProcess = true;
var bound = this.getChildrenBound(target, source.id, diagram);
this.updateSubProcessess(bound, source, diagram);
targetWrapper.measure(new Size(undefined, undefined));
targetWrapper.arrange(targetWrapper.desiredSize);
diagram.refreshCanvasLayers();
diagram.updateSelector();
// 908136: Node goes behind the subprocess and the connector connected to it is destroyed Issue Fix by commenting these lines
// let edges: string[] = [];
// edges = edges.concat((source as Node).outEdges, (source as Node).inEdges);
// for (let i: number = edges.length - 1; i >= 0; i--) {
// if (diagram.bpmnModule.bpmnTextAnnotationConnector.indexOf(diagram.nameTable[edges[parseInt(i.toString(), 10)]])
// === -1) {
// diagram.remove(diagram.nameTable[edges[parseInt(i.toString(), 10)]]);
// }
// }
var obj = cloneObject(source);
var entry = {
type: 'PositionChanged', undoObject: { nodes: [redoElement] },
redoObject: { nodes: [obj] }, category: 'Internal'
};
diagram.addHistoryEntry(entry);
if (diagram.mode === 'SVG') {
if (source.zIndex < target.zIndex) {
diagram.updateProcesses(source);
this.updateSubprocessNodeIndex(source, diagram, target);
} //909204-The node inside the subprocess disappears while grouping
var parent_1 = getDiagramElement(target.id + '_groupElement');
parent_1.appendChild(getDiagramElement(source.id + '_groupElement'));
}
this.updateDocks(source, diagram);
}
}
};
BpmnDiagrams.prototype.sortProcessOrder = function (processes, diagram) {
// Sort the process array based on node zIndex
processes.sort(function (a, b) { return diagram.nameTable["" + a].zIndex - diagram.nameTable["" + b].zIndex; });
};
BpmnDiagrams.prototype.updateIndex = function (diagram, source) {
//let processNode: Node;
var processNode = source;
var nodeindex = diagram.getIndex(processNode, processNode.id);
diagram.nodes.splice(Number(nodeindex), 1);
processNode.zIndex = ++diagram.activeLayer.objectZIndex;
diagram.nodes.push(processNode);
};
BpmnDiagrams.prototype.updateSubprocessNodeIndex = function (source, diagram, target) {
if (source.shape.activity.subProcess.processes
&& source.shape.activity.subProcess.processes.length > 0) {
for (var i = 0; i < source.shape.activity.subProcess.processes.length; i++) {
this.updateIndex(diagram, source);
var processes = source.shape.activity.subProcess.processes[parseInt(i.toString(), 10)];
if (diagram.nameTable["" + processes].shape.activity.subProcess.processes.length > 0) {
this.updateSubprocessNodeIndex(diagram.nameTable["" + processes], diagram, target);
}
else {
var node = diagram.nameTable[source.shape.activity.subProcess.processes[parseInt(i.toString(), 10)]];
this.updateIndex(diagram, node);
}
}
}
else {
this.updateIndex(diagram, source);
}
};
/** @private */
BpmnDiagrams.prototype.updateDocks = function (obj, diagram) {
if (obj.shape.type === 'Bpmn' && obj.shape.activity.subProcess.processes &&
!obj.shape.activity.subProcess.collapsed) {
var processTable = obj.shape.activity.subProcess.processes;
for (var _i = 0, processTable_1 = processTable; _i < processTable_1.length; _i++) {
var i = processTable_1[_i];
var actualObject = diagram.nameTable["" + i];
if (actualObject) {
diagram.updateConnectorEdges(actualObject);
actualObject.wrapper.measure(new Size(actualObject.wrapper.width, actualObject.wrapper.height));
actualObject.wrapper.arrange(actualObject.wrapper.desiredSize);
if (actualObject.shape.activity.subProcess.processes
&& actualObject.shape.activity.subProcess.processes.length) {
this.updateDocks(actualObject, diagram);
}
}
}
}
};
/** @private */
BpmnDiagrams.prototype.removeBpmnProcesses = function (currentObj, diagram) {
var element = diagram.nameTable[currentObj.processId];
if (currentObj.shape.type === 'Bpmn' && currentObj.shape.activity.subProcess.processes &&
currentObj.shape.activity.subProcess.processes.length > 0) {
var processes = currentObj.shape.activity.subProcess.processes;
for (var j = processes.length - 1; j >= 0; j--) {
diagram.remove(diagram.nameTable[processes[parseInt(j.toString(), 10)]]);
}
}
if (element) {
diagram.removeDependentConnector(currentObj);
var processes = element.shape.activity.subProcess.processes;
this.removeChildFromBPMN(element.wrapper, currentObj.id, diagram, true);
var processIndex = processes.indexOf(currentObj.id);
processes.splice(processIndex, 1);
}
};
/** @private */
BpmnDiagrams.prototype.removeChildFromBPMN = function (wrapper, name, diagram, isDelete) {
for (var _i = 0, _a = wrapper.children; _i < _a.length; _i++) {
var i = _a[_i];
if (i.id === name) {
wrapper.children.splice(wrapper.children.indexOf(i), 1);
if (!isDelete) {
// To remove the child node from subprocess to diagram in DOM.
this.removeGElement(i.id, diagram);
}
}
else if (i.children) {
this.removeChildFromBPMN(i, name, diagram, isDelete);
}
}
};
//Bug 858761: Default Tooltip of sub-process node is not positioned properly after drag and drop the child of subprocess in diagram.
// To remove the child node from subprocess to diagram in DOM.
BpmnDiagrams.prototype.removeGElement = function (id, diagram) {
var element = document.getElementById(id + '_groupElement');
var diagramLayer = document.getElementById(diagram.element.id + '_diagramLayer');
var parent = element.parentElement;
parent.removeChild(element);
diagramLayer.appendChild(element);
var node = diagram.nameTable["" + id];
var subProcess = diagram.nameTable["" + node.processId];
var beforeIndex = node.zIndex + 1;
var getNode = this.getNode(beforeIndex, diagram);
if (getNode.length > 0) {
var neighborElement_1 = document.getElementById(getNode[0].id + '_groupElement');
var index = Array.from(diagramLayer.children).findIndex(function (child) { return child === neighborElement_1; });
var domIndex = index !== -1 ? index : 1;
// 889550: issue with dragging process nodes of the sub process
// Remove the adjacent element of the node which z index is lessthan subprocess z index
if (node.zIndex < subProcess.zIndex) {
diagramLayer.children[parseInt(domIndex.toString(), 10)].insertAdjacentElement('beforebegin', element);
}
}
};
BpmnDiagrams.prototype.getNode = function (index, diagram) {
var getNode = diagram.nodes.filter(function (x) { return x.zIndex === index; });
if (getNode.length === 0 && index > 0) {
return this.getNode(index - 1, diagram);
}
return getNode;
};
/** @private */
BpmnDiagrams.prototype.removeProcess = function (id, diagram) {
var node = diagram.nameTable["" + id];
if (node) {
var parent_2 = diagram.nameTable[node.processId];
var undoElement = cloneObject(node);
if (parent_2 && parent_2.shape.type === 'Bpmn') {
var processes = parent_2.shape.activity.subProcess.processes;
this.removeChildFromBPMN(parent_2.wrapper, id, diagram, true);
var processIndex = processes.indexOf(id);
processes.splice(processIndex, 1);
node.processId = '';
//934140-Removing of process node to expanded subprocess at runtime won't be undoed
if (!(diagram.diagramActions & DiagramAction.UndoRedo)) {
var obj = cloneObject(node);
var entry = {
type: 'PositionChanged', undoObject: { nodes: [undoElement] },
redoObject: { nodes: [obj] }, category: 'Internal'
};
diagram.addHistoryEntry(entry);
}
diagram.refreshDiagramLayer();
diagram.updateSelector();
}
}
};
/** @private */
BpmnDiagrams.prototype.addProcess = function (process, parentId, diagram) {
//let id: string;
process.id = process.id || randomId();
var id = process.id;
var node = diagram.nameTable["" + id];
//913821-Adding of process node to expanded subprocess at runtime won't be undoed.
var undoElement = cloneObject(node);
if (!node) {
diagram.add(process);
}
process.processId = parentId;
var parentNode = diagram.nameTable["" + parentId];
var subProcess = parentNode.shape.activity.subProcess;
var isUndoRedo = diagram.diagramActions & DiagramAction.UndoRedo;
if (!isUndoRedo) {
diagram.protectPropertyChange(true);
}
//EJ2-942115-The function addProcess is not working when empty processes are not defined in the subprocess object.
if (!subProcess.processes) {
subProcess.processes = [];
}
if (!isUndoRedo) {
diagram.protectPropertyChange(false);
}
if (node && parentNode && parentNode.shape.type === 'Bpmn' && node.shape.type === 'Bpmn') {
node.processId = parentId;
//934140: Save and Load Functionality Not Working Properly in Subprocess
if (!isUndoRedo) {
diagram.protectPropertyChange(true);
if (node.zIndex < parentNode.zIndex) {
this.updateIndex(diagram, node);
}
//937210: Add processes to subprocess at runtime and remove by button click, save and load not working
var nodeOffsetX = (parentNode.offsetX - parentNode.width * parentNode.pivot.x) +
(node.margin.left + node.width * node.pivot.x);
var nodeOffsetY = (parentNode.offsetY - parentNode.height * parentNode.pivot.y) +
(node.margin.top + node.height * node.pivot.y);
if (node.offsetX !== nodeOffsetX || node.offsetY !== nodeOffsetY) {
node.offsetX = nodeOffsetX;
node.offsetY = nodeOffsetY;
}
diagram.protectPropertyChange(false);
}
var processes = parentNode.shape.activity.subProcess.processes;
if (processes.indexOf(id) < 0) {
processes.push(id);
}
parentNode.wrapper.children.push(node.wrapper);