@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,186 lines • 73.3 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Property, Complex, Collection, ChildProperty, ComplexFactory, CollectionFactory, compile as baseTemplateCompiler } from '@syncfusion/ej2-base';
import { ShapeStyle, StrokeStyle } from '../core/appearance';
import { Point } from '../primitives/point';
import { TextElement } from '../core/elements/text-element';
import { Transform, ConnectorConstraints, ControlPointsVisibility, PortVisibility, ElementAction } from '../enum/enum';
import { PortConstraints, BezierSmoothness } from '../enum/enum';
import { Rect } from '../primitives/rect';
import { Size } from '../primitives/size';
import { findAngle, findConnectorPoints, getOuterBounds } from '../utility/connector';
import { getAnnotationPosition, alignLabelOnSegments, updateConnector, checkPortRestriction, updatePortEdges, getPortsPosition, getPathOffset } from '../utility/diagram-util';
import { setUMLActivityDefaults, initFixedUserHandlesSymbol } from '../utility/diagram-util';
import { findDistance, findPath, updatePathElement, setConnectorDefaults } from '../utility/diagram-util';
import { randomId, getFunction } from './../utility/base-util';
import { flipConnector } from './../utility/diagram-util';
import { PathElement } from '../core/elements/path-element';
import { PathAnnotation } from './annotation';
import { Canvas } from '../core/containers/canvas';
import { getDecoratorShape, getPortShape } from './dictionary/common';
import { DiagramAction } from '../enum/enum';
import { NodeBase } from './node-base';
import { DiagramTooltip } from './tooltip';
import { identityMatrix, rotateMatrix, scaleMatrix, transformPointsByMatrix, transformPointByMatrix } from '../primitives/matrix';
import { DiagramHtmlElement } from '../core/elements/html-element';
import { getTemplateContent, getContent } from '../utility/dom-util';
import { SymbolSize } from './preview';
import { ConnectorFixedUserHandle } from './fixed-user-handle';
import { ResizeTool } from '../interaction/tool';
import { PathPort } from './port';
var getConnectorType = function (obj) {
//Removed isBlazor code
if (obj) {
switch (obj.type) {
case 'Bpmn':
return BpmnFlow;
case 'UmlActivity':
return ActivityFlow;
case 'UmlClassifier':
return RelationShip;
default:
return ConnectorShape;
}
}
return ConnectorShape;
};
var getSegmentType = function (obj) {
if (obj) {
//Removed isBlazor code
switch (obj.type) {
case 'Straight':
return StraightSegment;
case 'Bezier':
return BezierSegment;
case 'Orthogonal':
return OrthogonalSegment;
default:
return StraightSegment;
}
}
return undefined;
};
/**
* Decorators are used to decorate the end points of the connector with some predefined path geometry
*/
var Decorator = /** @class */ (function (_super) {
__extends(Decorator, _super);
function Decorator() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property(10)
], Decorator.prototype, "width", void 0);
__decorate([
Property(10)
], Decorator.prototype, "height", void 0);
__decorate([
Property('Arrow')
], Decorator.prototype, "shape", void 0);
__decorate([
Complex({ fill: 'black', strokeColor: 'black', strokeWidth: 1 }, ShapeStyle)
], Decorator.prototype, "style", void 0);
__decorate([
Complex({ x: 0, y: 0.5 }, Point)
], Decorator.prototype, "pivot", void 0);
__decorate([
Property('')
], Decorator.prototype, "pathData", void 0);
return Decorator;
}(ChildProperty));
export { Decorator };
/**
* Describes the length and angle between the control point and the start point of bezier segment
*/
var Vector = /** @class */ (function (_super) {
__extends(Vector, _super);
function Vector() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property(0)
], Vector.prototype, "angle", void 0);
__decorate([
Property(0)
], Vector.prototype, "distance", void 0);
return Vector;
}(ChildProperty));
export { Vector };
/**
* Describes the length and angle between the control point and the start point of bezier segment
*/
var BezierSettings = /** @class */ (function (_super) {
__extends(BezierSettings, _super);
function BezierSettings() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property(ControlPointsVisibility.All)
], BezierSettings.prototype, "controlPointsVisibility", void 0);
__decorate([
Property('FreeForm')
], BezierSettings.prototype, "segmentEditOrientation", void 0);
__decorate([
Property(BezierSmoothness.Default)
], BezierSettings.prototype, "smoothness", void 0);
__decorate([
Property(true)
], BezierSettings.prototype, "allowSegmentsReset", void 0);
return BezierSettings;
}(ChildProperty));
export { BezierSettings };
/**
* Sets the type of the connector
*/
var ConnectorShape = /** @class */ (function (_super) {
__extends(ConnectorShape, _super);
function ConnectorShape() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property('None')
], ConnectorShape.prototype, "type", void 0);
return ConnectorShape;
}(ChildProperty));
export { ConnectorShape };
/**
* Sets the type of the flow in a BPMN Process
*/
var ActivityFlow = /** @class */ (function (_super) {
__extends(ActivityFlow, _super);
function ActivityFlow() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property('Object')
], ActivityFlow.prototype, "flow", void 0);
__decorate([
Property(30)
], ActivityFlow.prototype, "exceptionFlowHeight", void 0);
return ActivityFlow;
}(ConnectorShape));
export { ActivityFlow };
/**
* Sets the type of the flow in a BPMN Process
*/
var BpmnFlow = /** @class */ (function (_super) {
__extends(BpmnFlow, _super);
function BpmnFlow() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property('Sequence')
], BpmnFlow.prototype, "flow", void 0);
__decorate([
Property('Normal')
], BpmnFlow.prototype, "sequence", void 0);
__decorate([
Property('Default')
], BpmnFlow.prototype, "message", void 0);
__decorate([
Property('Default')
], BpmnFlow.prototype, "association", void 0);
return BpmnFlow;
}(ConnectorShape));
export { BpmnFlow };
/**
* Defines the behavior of connector segments
*/
var ConnectorSegment = /** @class */ (function (_super) {
__extends(ConnectorSegment, _super);
// tslint:disable-next-line:no-any
function ConnectorSegment(parent, propName, defaultValue, isArray) {
var _this = _super.call(this, parent, propName, defaultValue, isArray) || this;
_this.points = [];
return _this;
}
__decorate([
Property('Straight')
], ConnectorSegment.prototype, "type", void 0);
__decorate([
Property(true)
], ConnectorSegment.prototype, "allowDrag", void 0);
return ConnectorSegment;
}(ChildProperty));
export { ConnectorSegment };
/**
* Defines the behavior of straight segments
*/
var StraightSegment = /** @class */ (function (_super) {
__extends(StraightSegment, _super);
function StraightSegment() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Returns the name of class StraightSegment
*
* @private
*/
StraightSegment.prototype.getClassName = function () {
return 'StraightSegment';
};
__decorate([
Complex({ x: 0, y: 0 }, Point)
], StraightSegment.prototype, "point", void 0);
return StraightSegment;
}(ConnectorSegment));
export { StraightSegment };
/**
* Defines the behavior of bezier segments
*/
var BezierSegment = /** @class */ (function (_super) {
__extends(BezierSegment, _super);
function BezierSegment() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* @private
* Returns the name of class BezierSegment
*/
BezierSegment.prototype.getClassName = function () {
return 'BezierSegment';
};
/**
* @private
* Returns the total points of the bezier curve
*/
BezierSegment.prototype.getPoints = function (segments, start) {
var points = [];
if (points.length > 0 || start != null) {
var st = points.length > 0 ? points[points.length - 1] : start;
var bezier = this.bezireToPoly(st, segments);
// 878719: Resolve ESLint errors
// eslint-disable-next-line prefer-spread
points.push.apply(points, bezier);
}
return points;
};
/**
* @private
* Returns the total points of the bezier curve
*/
BezierSegment.prototype.bezireToPoly = function (start, segment) {
var points = [];
if (segment) {
var bezSeg = segment;
var pt0 = start;
var pt1 = bezSeg.bezierPoint1;
var pt2 = bezSeg.bezierPoint2;
var pt3 = { x: bezSeg.points[1].x, y: bezSeg.points[1].y };
this.flattenCubicBezier(points, pt0, pt1, pt2, pt3, 10);
}
return points;
};
/**
* @private
* Returns the total points of the bezier curve
*/
BezierSegment.prototype.flattenCubicBezier = function (points, ptStart, ptCtrl1, ptCtrl2, ptEnd, tolerance) {
var max = ((Point.findLength(ptStart, ptCtrl1) + Point.findLength(ptCtrl1, ptCtrl2)
+ Point.findLength(ptCtrl2, ptEnd)) / tolerance);
var i;
for (i = 0; i <= max; i++) {
var t = i / max;
var x = (1 - t) * (1 - t) * (1 - t) * ptStart.x +
3 * t * (1 - t) * (1 - t) * ptCtrl1.x +
3 * t * t * (1 - t) * ptCtrl2.x +
t * t * t * ptEnd.x;
var y = (1 - t) * (1 - t) * (1 - t) * ptStart.y +
3 * t * (1 - t) * (1 - t) * ptCtrl1.y +
3 * t * t * (1 - t) * ptCtrl2.y +
t * t * t * ptEnd.y;
points.push({ x: x, y: y });
}
};
__decorate([
Property('Horizontal')
], BezierSegment.prototype, "orientation", void 0);
__decorate([
Complex({ x: 0, y: 0 }, Point)
], BezierSegment.prototype, "point1", void 0);
__decorate([
Complex({ x: 0, y: 0 }, Point)
], BezierSegment.prototype, "point2", void 0);
__decorate([
Complex({ angle: 0, distance: 0 }, Vector)
], BezierSegment.prototype, "vector1", void 0);
__decorate([
Complex({ angle: 0, distance: 0 }, Vector)
], BezierSegment.prototype, "vector2", void 0);
return BezierSegment;
}(StraightSegment));
export { BezierSegment };
/**
* Defines the behavior of orthogonal segments
*/
var OrthogonalSegment = /** @class */ (function (_super) {
__extends(OrthogonalSegment, _super);
function OrthogonalSegment() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Returns the module of class OrthogonalSegment
*
* @private
*/
OrthogonalSegment.prototype.getClassName = function () {
return 'OrthogonalSegment';
};
__decorate([
Property(null)
], OrthogonalSegment.prototype, "length", void 0);
__decorate([
Property(null)
], OrthogonalSegment.prototype, "direction", void 0);
return OrthogonalSegment;
}(ConnectorSegment));
export { OrthogonalSegment };
/**
* Defines the behavior of orthogonal segments
*/
var DiagramConnectorSegment = /** @class */ (function (_super) {
__extends(DiagramConnectorSegment, _super);
function DiagramConnectorSegment() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* @private
* Returns the module of class OrthogonalSegment
*/
DiagramConnectorSegment.prototype.getClassName = function () {
return 'DiagramConnectorSegment';
};
__decorate([
Property('Straight')
], DiagramConnectorSegment.prototype, "type", void 0);
__decorate([
Property(true)
], DiagramConnectorSegment.prototype, "allowDrag", void 0);
__decorate([
Complex({ x: 0, y: 0 }, Point)
], DiagramConnectorSegment.prototype, "point", void 0);
__decorate([
Complex({ x: 0, y: 0 }, Point)
], DiagramConnectorSegment.prototype, "point1", void 0);
__decorate([
Complex({ x: 0, y: 0 }, Point)
], DiagramConnectorSegment.prototype, "point2", void 0);
__decorate([
Complex({ angle: 0, distance: 0 }, Vector)
], DiagramConnectorSegment.prototype, "vector1", void 0);
__decorate([
Complex({ angle: 0, distance: 0 }, Vector)
], DiagramConnectorSegment.prototype, "vector2", void 0);
__decorate([
Property(null)
], DiagramConnectorSegment.prototype, "length", void 0);
__decorate([
Property(null)
], DiagramConnectorSegment.prototype, "direction", void 0);
return DiagramConnectorSegment;
}(ChildProperty));
export { DiagramConnectorSegment };
/**
* Get the direction of the control points while the bezier is connected to the node
*/
export function getDirection(bounds, points, excludeBounds) {
var center = bounds.center;
var direction;
var part = excludeBounds ? 45 : (180 / (2 + 2 / (bounds.height / bounds.width)));
var fourty5 = part;
var one35 = (180 - part);
var two25 = one35 + (2 * part);
var three15 = 360 - part;
var angle = findAngle(points, center);
if (angle > fourty5 && angle < one35) {
return direction = 'top';
}
else if (angle > one35 && angle < two25) {
return direction = 'right';
}
else if (angle > two25 && angle < three15) {
return direction = 'bottom';
}
else {
return direction = 'left';
}
}
export function isEmptyVector(element) {
if (!element.distance && !element.angle) {
return true;
}
return false;
}
/**
* Get the bezier points if control points are not given.
*/
export function getBezierPoints(sourcePoint, targetPoint, direction) {
var distance = 60;
var value = { x: 0, y: 0 };
if (!direction) {
if (Math.abs(targetPoint.x - sourcePoint.x) > Math.abs(targetPoint.y - sourcePoint.y)) {
direction = sourcePoint.x < targetPoint.x ? 'right' : 'left';
}
else {
direction = sourcePoint.y < targetPoint.y ? 'bottom' : 'top';
}
}
switch (direction) {
case 'bottom':
case 'top':
distance = Math.min(Math.abs(sourcePoint.y - targetPoint.y) * 0.45, distance);
value = { x: sourcePoint.x, y: sourcePoint.y + (direction === 'bottom' ? distance : -distance) };
break;
case 'right':
case 'left':
distance = Math.min(Math.abs(sourcePoint.x - targetPoint.x) * 0.45, distance);
value = { x: sourcePoint.x + (direction === 'right' ? distance : -distance), y: sourcePoint.y };
break;
}
return value;
}
/**
* Get the bezier curve bounds.
*/
export function getBezierBounds(startPoint, controlPoint1, controlPoint2, endPoint, connector) {
var minx = 0;
var miny = 0;
var maxx = 0;
var maxy = 0;
var tolerancevalue = 3;
var max = Number((connector.distance(controlPoint1, startPoint) +
connector.distance(controlPoint2, controlPoint1) +
connector.distance(endPoint, controlPoint2)) / tolerancevalue);
if (max !== 0) {
for (var i = 0; i <= max; i++) {
var t = i / max;
var x = (1 - t) * (1 - t) * (1 - t) * startPoint.x +
3 * t * (1 - t) * (1 - t) * controlPoint1.x +
3 * t * t * (1 - t) * controlPoint2.x +
t * t * t * endPoint.x;
var y = (1 - t) * (1 - t) * (1 - t) * startPoint.y +
3 * t * (1 - t) * (1 - t) * controlPoint1.y +
3 * t * t * (1 - t) * controlPoint2.y +
t * t * t * endPoint.y;
if (i === 0) {
minx = maxx = x;
miny = maxy = y;
}
else {
minx = Math.min(x, minx);
miny = Math.min(y, miny);
maxx = Math.max(x, maxx);
maxy = Math.max(y, maxy);
}
}
}
return {
x: minx, y: miny, width: maxx - minx, height: maxy - miny,
left: minx, top: miny, right: (minx + (maxx - minx)), bottom: (miny + (maxy - miny)),
center: { x: (minx + (maxx - minx)) / 2, y: (miny + (maxy - miny)) / 2 }
};
}
/**
* Get the intermediate bezier curve for point over connector
*/
export function bezierPoints(connector, startPoint, point1, point2, endPoint, i, max) {
var pt = { x: 0, y: 0 };
var t = i / max;
var x = (1 - t) * (1 - t) * (1 - t) * startPoint.x +
3 * t * (1 - t) * (1 - t) * point1.x +
3 * t * t * (1 - t) * point2.x +
t * t * t * endPoint.x;
pt.x = x;
var y = (1 - t) * (1 - t) * (1 - t) * startPoint.y +
3 * t * (1 - t) * (1 - t) * point1.y +
3 * t * t * (1 - t) * point2.y +
t * t * t * endPoint.y;
pt.y = y;
return pt;
}
/**
* Defines the behavior of the UMLActivity Classifier multiplicity connection defaults
*/
var MultiplicityLabel = /** @class */ (function (_super) {
__extends(MultiplicityLabel, _super);
function MultiplicityLabel() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property(true)
], MultiplicityLabel.prototype, "optional", void 0);
__decorate([
Property(undefined)
], MultiplicityLabel.prototype, "lowerBounds", void 0);
__decorate([
Property(undefined)
], MultiplicityLabel.prototype, "upperBounds", void 0);
return MultiplicityLabel;
}(ChildProperty));
export { MultiplicityLabel };
/**
* Defines the behavior of the UMLActivity Classifier multiplicity connection defaults
*/
var ClassifierMultiplicity = /** @class */ (function (_super) {
__extends(ClassifierMultiplicity, _super);
function ClassifierMultiplicity() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property('OneToOne')
], ClassifierMultiplicity.prototype, "type", void 0);
__decorate([
Complex({}, MultiplicityLabel)
], ClassifierMultiplicity.prototype, "target", void 0);
__decorate([
Complex({}, MultiplicityLabel)
], ClassifierMultiplicity.prototype, "source", void 0);
return ClassifierMultiplicity;
}(ChildProperty));
export { ClassifierMultiplicity };
/**
* Defines the behavior of the UMLActivity shape
*/
var RelationShip = /** @class */ (function (_super) {
__extends(RelationShip, _super);
function RelationShip() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property('UmlClassifier')
], RelationShip.prototype, "type", void 0);
__decorate([
Property('Aggregation')
], RelationShip.prototype, "relationship", void 0);
__decorate([
Property('Directional')
], RelationShip.prototype, "associationType", void 0);
__decorate([
Complex({}, ClassifierMultiplicity)
], RelationShip.prototype, "multiplicity", void 0);
return RelationShip;
}(ConnectorShape));
export { RelationShip };
/**
* Connector shape for blazor
*/
var DiagramConnectorShape = /** @class */ (function (_super) {
__extends(DiagramConnectorShape, _super);
function DiagramConnectorShape() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property('None')
], DiagramConnectorShape.prototype, "type", void 0);
__decorate([
Property('Directional')
], DiagramConnectorShape.prototype, "associationType", void 0);
__decorate([
Property('Aggregation')
], DiagramConnectorShape.prototype, "relationship", void 0);
__decorate([
Complex({}, ClassifierMultiplicity)
], DiagramConnectorShape.prototype, "multiplicity", void 0);
__decorate([
Property('Sequence')
], DiagramConnectorShape.prototype, "bpmnFlow", void 0);
__decorate([
Property('Default')
], DiagramConnectorShape.prototype, "message", void 0);
__decorate([
Property('Normal')
], DiagramConnectorShape.prototype, "sequence", void 0);
__decorate([
Property('Default')
], DiagramConnectorShape.prototype, "association", void 0);
__decorate([
Property('Object')
], DiagramConnectorShape.prototype, "umlActivityFlow", void 0);
__decorate([
Property(30)
], DiagramConnectorShape.prototype, "exceptionFlowHeight", void 0);
return DiagramConnectorShape;
}(ChildProperty));
export { DiagramConnectorShape };
/**
* Connectors are used to create links between nodes
*/
var Connector = /** @class */ (function (_super) {
__extends(Connector, _super);
// tslint:disable-next-line:no-any
function Connector(parent, propName, defaultValue, isArray) {
var _this = _super.call(this, parent, propName, defaultValue, isArray) || this;
/** @private */
_this.parentId = '';
/** @private */
_this.bridges = [];
/** @private */
_this.status = 'None';
/** @private */
_this.outEdges = [];
/** @private */
_this.inEdges = [];
if (_this.shape && _this.shape.type === 'UmlActivity') {
setUMLActivityDefaults(defaultValue, _this);
}
if (defaultValue && defaultValue.shape && defaultValue.shape.type !== 'None') {
setConnectorDefaults(defaultValue, _this);
}
return _this;
}
/* tslint:disable */
Connector.prototype.setPortID = function (diagram, isTarget) {
if (this.targetID && this.sourceID) {
var targetNode = diagram.nameTable[this.targetID];
var sourceNode = diagram.nameTable[this.sourceID];
var ports = isTarget ? (targetNode && targetNode.ports) : (sourceNode && sourceNode.ports);
var port = void 0;
for (var i = 0; ports && i < ports.length; i++) {
port = ports[parseInt(i.toString(), 10)];
if (this.targetPortID === port.id && isTarget) {
if ((port.constraints & PortConstraints.None) || !(port.constraints & PortConstraints.InConnect)) {
this.targetPortID = '';
}
}
else if (this.sourcePortID === port.id && !isTarget) {
if ((port.constraints & PortConstraints.None) || !(port.constraints & PortConstraints.OutConnect)) {
this.sourcePortID = '';
}
}
}
}
};
/* tslint:enable */
/** @private */
// tslint:disable-next-line:no-any
Connector.prototype.init = function (diagram) {
if (!this.id) {
this.id = randomId();
}
if (this.sourcePortID) {
this.setPortID(diagram);
}
if (this.targetPortID) {
this.setPortID(diagram, true);
}
var bpmnElement;
var container = new Canvas();
var segment = new PathElement();
segment.id = this.id + '_path';
var srcDecorator = new PathElement();
var targetDecorator = new PathElement();
segment = this.getSegmentElement(this, segment);
//let bounds: Rect;
var points = [];
points = this.type === 'Bezier' ? this.intermediatePoints : this.getConnectorPoints(this.type);
points = this.clipDecorators(this, points);
var bounds = Rect.toBounds(points);
container.width = bounds.width;
container.height = bounds.height;
container.offsetX = bounds.x + container.pivot.x * bounds.width;
container.offsetY = bounds.y + container.pivot.y * bounds.height;
switch (this.shape.type) {
case 'Bpmn':
// eslint-disable-next-line no-case-declarations
var flow = this.shape.flow;
switch (flow) {
case 'Sequence':
bpmnElement = this.getBpmnSequenceFlow();
break;
case 'Association':
bpmnElement = new PathElement();
bpmnElement.visible = false;
this.getBpmnAssociationFlow();
break;
case 'Message':
bpmnElement = this.getBpmnMessageFlow();
segment = this.getSegmentElement(this, segment);
this.updateShapePosition(this, bpmnElement);
break;
}
break;
case 'UmlActivity':
// eslint-disable-next-line no-case-declarations
var activityFlow = this.shape.flow;
switch (activityFlow) {
case 'Object':
this.getUMLObjectFlow();
break;
case 'Exception':
this.getUMLExceptionFlow(segment);
break;
}
break;
case 'UmlClassifier':
this.getConnectorRelation();
break;
}
var anglePoints = this.intermediatePoints;
if (this.type === 'Bezier') {
var firstSegment = this.segments[0];
var lastSegment = this.segments[this.segments.length - 1];
anglePoints = [!Point.isEmptyPoint(lastSegment.point2) ? lastSegment.point2 : lastSegment.bezierPoint2,
!Point.isEmptyPoint(firstSegment.point1) ? firstSegment.point1 : firstSegment.bezierPoint1];
}
var accessContent = 'getDescription';
var getDescription = diagram["" + accessContent];
//const strokeWidth: number = this.sourceWrapper ? this.sourceWrapper.style.strokeWidth / 2 / 2 : 0;
srcDecorator = this.getDecoratorElement(points[0], anglePoints[1], this.sourceDecorator, true, getDescription);
targetDecorator = this.getDecoratorElement(points[points.length - 1], anglePoints[anglePoints.length - 2], this.targetDecorator, false, getDescription);
srcDecorator.id = this.id + '_srcDec';
targetDecorator.id = this.id + '_tarDec';
segment.style = this.style;
/* tslint:disable:no-string-literal */
segment.style['fill'] = 'transparent';
if (getDescription !== undefined) {
// tslint:disable-next-line:no-any
var wrapperContent = getDescription(this, diagram);
segment.description = wrapperContent ? wrapperContent : this.id;
}
container.style.strokeColor = 'transparent';
container.style.fill = 'transparent';
container.style.strokeWidth = 0;
container.children = [segment, srcDecorator, targetDecorator];
container.id = this.id;
if (bpmnElement !== undefined) {
container.children.push(bpmnElement);
}
container.offsetX = segment.offsetX;
container.offsetY = segment.offsetY;
container.width = segment.width;
container.height = segment.height;
for (var i = 0; this.annotations !== undefined, i < this.annotations.length; i++) {
container.children.push(this.getAnnotationElement(this.annotations[parseInt(i.toString(), 10)], this.intermediatePoints, bounds, getDescription, diagram.element.id, diagram.annotationTemplate));
}
for (var i = 0; this.fixedUserHandles !== undefined, i < this.fixedUserHandles.length; i++) {
container.children.push(this.getFixedUserHandle(this.fixedUserHandles[parseInt(i.toString(), 10)], this.intermediatePoints, bounds, diagram.fixedUserHandleTemplate, diagram.element.id));
}
// Feature 826644: Support to add ports to the connector.
this.initPorts(getDescription, container, bounds);
this.wrapper = container;
return container;
};
/** @private */
Connector.prototype.initPorts = function (accessibilityContent, container, bounds) {
for (var i = 0; this.ports !== undefined, i < this.ports.length; i++) {
container.children.push(this.initPort(this.ports[parseInt(i.toString(), 10)], this.intermediatePoints, bounds, accessibilityContent));
}
};
// Feature 826644: Support to add ports to the connector. Added below method to init the connector port.
/** @private */
Connector.prototype.initPort = function (ports, points, bounds, accessibilityContent) {
var portWrapper = new PathElement();
portWrapper.height = ports.height;
portWrapper.width = ports.width;
portWrapper.margin = ports.margin;
ports.shape = ports.shape || 'Square';
var pathdata = (ports.shape === 'Custom') ? ports.pathData : getPortShape(ports.shape);
portWrapper.data = pathdata;
portWrapper.horizontalAlignment = ports.horizontalAlignment;
portWrapper.verticalAlignment = ports.verticalAlignment;
// eslint-disable-next-line prefer-const
portWrapper = this.initPortWrapper(ports, points, bounds, portWrapper, this);
// tslint:disable-next-line:no-any
var wrapperContent;
var contentAccessibility = getFunction(accessibilityContent);
if (contentAccessibility) {
wrapperContent = contentAccessibility(portWrapper, this);
}
portWrapper.description = wrapperContent ? wrapperContent : portWrapper.id;
portWrapper.elementActions = portWrapper.elementActions | ElementAction.ElementIsPort;
portWrapper.isPathPort = true;
return portWrapper;
};
// Feature 826644: Support to add ports to the connector. Added below method to init the connector portwrapper.
/** @private */
Connector.prototype.initPortWrapper = function (ports, points, bounds, portContent, Connector) {
ports.id = ports.id || randomId();
// Creates port element
var pivotPoint = { x: 0, y: 0 };
var getPointloop = getPortsPosition(points, ports, bounds);
var newPoint = getPointloop.point;
portContent.id = this.id + '_' + (ports.id);
var style = ports.style;
portContent.style = {
fill: style.fill, strokeColor: style.strokeColor, gradient: null,
opacity: style.opacity, strokeDashArray: style.strokeDashArray, strokeWidth: style.strokeWidth
};
if (bounds.width === 0) {
bounds.width = this.style.strokeWidth;
}
if (bounds.height === 0) {
bounds.height = this.style.strokeWidth;
}
var offsetPoint = { x: ((newPoint.x - bounds.x) / bounds.width), y: ((newPoint.y - bounds.y) / bounds.height) };
pivotPoint.x = bounds.width * offsetPoint.x;
pivotPoint.y = bounds.height * offsetPoint.y;
var align = alignLabelOnSegments(ports, getPointloop.angle, points);
var hAlign = align.hAlign;
var vAlign = align.vAlign;
var horizor;
var verzor;
if (hAlign === 'left') {
horizor = 'Left';
pivotPoint.x += ports.displacement.x;
}
else if (hAlign === 'right') {
horizor = 'Right';
pivotPoint.x -= ports.displacement.x;
}
else if (hAlign === 'center') {
horizor = 'Center';
}
if (vAlign === 'top') {
verzor = 'Top';
pivotPoint.y += ports.displacement.y;
}
else if (vAlign === 'bottom') {
verzor = 'Bottom';
pivotPoint.y -= ports.displacement.y;
}
else if (vAlign === 'center') {
verzor = 'Center';
}
portContent.horizontalAlignment = horizor;
portContent.verticalAlignment = verzor;
if (Connector && Connector.flipMode !== 'Label' && Connector.flipMode !== 'None') {
portContent = updatePortEdges(portContent, this.flip, ports);
}
else {
portContent = updatePortEdges(portContent, 'None', ports);
}
portContent.float = true;
portContent.connectionDirection = ports.connectionDirection;
portContent.setOffsetWithRespectToBounds(pivotPoint.x, pivotPoint.y, 'Absolute');
portContent.relativeMode = 'Point';
portContent.visible = checkPortRestriction(ports, PortVisibility.Visible) &&
!checkPortRestriction(ports, PortVisibility.Hover) && !checkPortRestriction(ports, PortVisibility.Connect) ? true : false;
portContent.elementActions = portContent.elementActions | ElementAction.ElementIsPort;
return portContent;
};
Connector.prototype.getConnectorRelation = function () {
var shape = this.shape;
if (shape.relationship === 'Association') {
this.sourceDecorator.shape = 'None';
this.targetDecorator.shape = 'Arrow';
}
else if (shape.relationship === 'Inheritance') {
this.sourceDecorator.shape = 'None';
this.targetDecorator.shape = 'Arrow';
}
else if (shape.relationship === 'Composition') {
this.sourceDecorator.shape = 'Diamond';
this.targetDecorator.shape = 'None';
}
else if (shape.relationship === 'Aggregation') {
this.sourceDecorator.shape = 'Diamond';
this.targetDecorator.shape = 'None';
}
else if (shape.relationship === 'Dependency') {
this.sourceDecorator.shape = 'None';
this.targetDecorator.shape = 'OpenArrow';
}
else if (shape.relationship === 'Realization') {
this.sourceDecorator.shape = 'None';
this.targetDecorator.shape = 'Arrow';
}
if (shape.associationType === 'BiDirectional') {
this.sourceDecorator.shape = 'None';
this.targetDecorator.shape = 'None';
}
var text1 = '';
//let lower: MultiplicityLabelModel;
//let upper: MultiplicityLabelModel;
var sourceText = '';
var targetText = '';
var text = '';
if (shape.multiplicity.source) {
shape.multiplicity.source.lowerBounds = shape.multiplicity.source.lowerBounds;
shape.multiplicity.source.upperBounds = shape.multiplicity.source.upperBounds;
}
if (shape.multiplicity.target) {
shape.multiplicity.target.lowerBounds = shape.multiplicity.target.lowerBounds;
shape.multiplicity.target.upperBounds = shape.multiplicity.target.upperBounds;
}
var lower = shape.multiplicity.source;
var upper = shape.multiplicity.target;
text = lower.upperBounds ? lower.lowerBounds + '...' + lower.upperBounds : lower.lowerBounds;
text1 = upper.upperBounds ? upper.lowerBounds + '...' + upper.upperBounds : upper.lowerBounds;
if (shape.multiplicity.type === 'ManyToOne') {
shape.multiplicity.target.optional = false;
sourceText = text ? text : '*';
targetText = '1';
}
if (shape.multiplicity.type === 'OneToMany') {
shape.multiplicity.source.optional = false;
targetText = text1 ? text1 : '*';
sourceText = '1';
}
//831806 -Added ManyToMany relationship for UML class connector annotation label
if (shape.multiplicity.type === 'ManyToMany') {
sourceText = text ? text : '*';
targetText = text1 ? text1 : '*';
}
if (shape.multiplicity.type === 'OneToOne') {
shape.multiplicity.target.optional = false;
shape.multiplicity.source.optional = false;
sourceText = '1';
targetText = '1';
}
this.annotations = [
{
id: this.id + 'sourcelabel', content: sourceText, offset: 0, alignment: 'Before',
margin: { right: 5, bottom: 5 }
},
{
id: this.id + 'targetlabel', content: targetText, offset: 1, alignment: 'Before',
margin: { right: 5, bottom: 5 }
}
];
};
Connector.prototype.getBpmnSequenceFlow = function () {
var segment = new PathElement();
var pathseq = new PathElement();
var pathseqData;
if ((this.shape.sequence) === 'Normal' && this.type !== 'Bezier') {
this.targetDecorator.shape = 'Arrow';
}
if ((this.shape.sequence) === 'Default') {
segment = this.getSegmentElement(this, segment);
var anglePoints = this.intermediatePoints;
pathseq = updatePathElement(anglePoints, this);
this.targetDecorator.shape = 'Arrow';
}
if ((this.shape.sequence) === 'Conditional') {
this.targetDecorator.shape = 'Arrow';
this.sourceDecorator.shape = 'Diamond';
pathseq.id = this.id + this.shape.type;
}
return pathseq;
};
/** @private */
Connector.prototype.getUMLObjectFlow = function () {
if (this.annotations) {
for (var i = 0; i < this.annotations.length; i++) {
this.annotations[parseInt(i.toString(), 10)].content = '[' + this.annotations[parseInt(i.toString(), 10)].content + ']';
}
}
};
/** @private */
Connector.prototype.getUMLExceptionFlow = function (segment) {
this.type = 'Straight';
var height = (this.shape.exceptionFlowHeight) / 2;
var midPt = { x: (this.targetPoint.x + this.sourcePoint.x) / 2, y: (this.targetPoint.y + this.sourcePoint.y) / 2 };
var xDist = midPt.x - this.sourcePoint.x;
var yDist = midPt.y - this.sourcePoint.y;
var dist = Math.sqrt(xDist * xDist + yDist * yDist);
var fractionOfTotal = (height) / dist;
var midPt2 = { x: midPt.x - xDist * fractionOfTotal, y: midPt.y - yDist * fractionOfTotal };
var midPt1 = { x: midPt.x + xDist * fractionOfTotal, y: midPt.y + yDist * fractionOfTotal };
var matrix = identityMatrix();
rotateMatrix(matrix, 315, midPt.x, midPt.y);
this.segments = [];
var segments = new StraightSegment(this, 'segments', { type: 'Straight', point: transformPointByMatrix(matrix, midPt1) }, true);
(this.segments).push(segments);
segments = new StraightSegment(this, 'segments', { type: 'Straight', point: transformPointByMatrix(matrix, midPt2) }, true);
(this.segments).push(segments);
segment = this.getSegmentElement(this, segment);
};
Connector.prototype.getBpmnAssociationFlow = function () {
if ((this.shape.association) === 'Default') {
this.targetDecorator.shape = 'None';
this.style.strokeDashArray = '2 2';
}
if ((this.shape.association) === 'Directional') {
this.targetDecorator.shape = 'OpenArrow';
this.style.strokeDashArray = '2 2';
}
if ((this.shape.association) === 'BiDirectional') {
this.targetDecorator.shape = 'OpenArrow';
this.sourceDecorator.shape = 'OpenArrow';
this.style.strokeDashArray = '2 2';
}
};
// 882378 - Added below code to provide template support for fixedUserHandles in connectors
/** @private */
Connector.prototype.getFixedUserHandle = function (fixedUserHandle, points, bounds, fixedUserHandleTemplate, diagramId) {
var fixedUserHandleContainer;
if (fixedUserHandle.pathData === '' && fixedUserHandleTemplate) {
fixedUserHandleContainer = new DiagramHtmlElement(this.id, diagramId, undefined, fixedUserHandleTemplate);
fixedUserHandleContainer.isTemplate = true;
fixedUserHandleContainer.template = getContent(fixedUserHandleContainer, true, fixedUserHandle);
fixedUserHandle.id = fixedUserHandle.id || randomId();
fixedUserHandleContainer.id = this.id + '_' + fixedUserHandle.id;
}
else {
fixedUserHandleContainer = new Canvas();
var children = [];
fixedUserHandleContainer.children = children;
fixedUserHandle.id = fixedUserHandle.id || randomId();
fixedUserHandleContainer.id = this.id + '_' + fixedUserHandle.id;
var symbolIcon = initFixedUserHandlesSymbol(fixedUserHandle, fixedUserHandleContainer);
fixedUserHandleContainer.children.push(symbolIcon);
}
fixedUserHandleContainer.float = true;
fixedUserHandleContainer.visible = fixedUserHandle.visibility;
fixedUserHandleContainer.width = fixedUserHandle.width;
fixedUserHandleContainer.height = fixedUserHandle.height;
fixedUserHandleContainer.style.strokeWidth = fixedUserHandle.handleStrokeWidth;
fixedUserHandleContainer.style.fill = fixedUserHandle.fill;
fixedUserHandleContainer.style.strokeColor = fixedUserHandle.handleStrokeColor;
fixedUserHandleContainer.cornerRadius = fixedUserHandle.cornerRadius;
this.updateAnnotation(fixedUserHandle, points, bounds, fixedUserHandleContainer);
fixedUserHandleContainer.description = fixedUserHandleContainer.id;
return fixedUserHandleContainer;
};
Connector.prototype.getBpmnMessageFlow = function () {
var segmentMessage = new PathElement();
this.targetDecorator.shape = 'Arrow';
this.targetDecorator.width = 10;
this.targetDecorator.height = 10;
this.sourceDecorator.shape = 'Circle';
this.sourceDecorator.style.fill = 'white';
this.targetDecorator.style.fill = 'white';
if (((this.shape.message) === 'InitiatingMessage') ||
((this.shape.message) === 'NonInitiatingMessage')) {
segmentMessage.id = this.id + '_' + (this.shape.message);
segmentMessage.width = 25;
segmentMessage.height = 15;
segmentMessage.data = 'M0,0 L19.8,12.8 L40,0 L0, 0 L0, 25.5 L40, 25.5 L 40, 0';
segmentMessage.horizontalAlignment = 'Center';
segmentMessage.verticalAlignment = 'Center';
segmentMessage.transform = Transform.Self;
segmentMessage.style.fill = (this.shape.message) === 'NonInitiatingMessage' ? 'lightgrey' : 'white';
}
return segmentMessage;
};
/** @private */
Connector.prototype.distance = function (pt1, pt2) {
return findDistance(pt1, pt2);
};
/** @private */
Connector.prototype.findPath = function (sourcePt, targetPt) {
return findPath(sourcePt, targetPt);
};
/** @private */
Connector.prototype.getAnnotationElement = function (annotation, points, bounds, getDescription, diagramId, annotationTemplate) {
annotation.content = annotation.content || '';
annotation.id = annotation.id || randomId();
var textele;
//Removed isBlazor code
if (diagramId && (annotation.template || annotation.annotationType === 'Template'
|| (annotationTemplate && annotation.content === ''))) {
// Task 834121: Content-Security-Policy support for diagram
var diagramElement = document.getElementById(diagramId);
var instance = 'ej2_instances';
var diagram = diagramElement["" + instance][0];
textele = new DiagramHtmlElement(this.id, diagramId, annotation.id, annotationTemplate);
if (annotation.template && typeof annotation.template === 'function' && diagram.isReact) {
textele.templateFn = baseTemplateCompiler(annotation.template);
textele.isTemplate = true;
}
//908155-Annotation template update wrongly while do interaction for connector
if (annotation.height === undefined && annotation.annotationType === 'String' && (annotation.template || annotation.content === '')) {
annotation.height = bounds.height;
}
textele = getTemplateContent(textele, annotation, annotationTemplate, diagram);
}
else {
textele = new TextElement();
//876030 - Adding hyperlink for connectors
var link = annotation.hyperlink.link ? annotation.hyperlink : undefined;
textele.style = annotation.style;
textele.style.color = link ? link.color || textele.hyperlink.color : annotation.style.color;
textele.hyperlink.link = annotation.hyperlink.link || undefined;
textele.hyperlink.hyperlinkOpenState = annotation.hyperlink.hyperlinkOpenState || undefined;
textele.hyperlink.textDecoration = annotation.hyperlink.textDecoration || undefined;
textele.content = link ? link.content ||
textele.hyperlink.link : annotation.content;
}
textele.constraints = annotation.constraints;
textele.visible = annotation.visibility;
textele.annotationVisibility = textele.visible ? 'Visible' : 'Collapsed';
textele.rotateAngle = annotation.rotateAngle;
textele.horizontalAlignment = annotation.horizontalAlignment;
textele.verticalAlignment = annotation.verticalAlignment;
textele.width = annotation.width;
textele.height = annotation.height;
if (bounds.width !== undefined && !annotation.template) {
textele.width = (annotation.width || bounds.width) - annotation.margin.left - annotation.margin.right;
}
textele.margin = annotation.margin;
textele.id = this.id + '_' + annotation.id;
if (bounds.width === 0) {
bounds.width = this.style.strokeWidth;
}
if (bounds.height === 0) {
bounds.height = this.style.strokeWidth;
}
// tslint:disable-next-line:no-any
var wrapperContent;
var description = getFunction(getDescription);
if (description) {
wrapperContent = description(annotation, this);
}
textele.description = wrapperContent ? wrapperContent : textele.id;
this.updateAnnotation(annotation, points, bounds, textele);
return textele;
};
/** @private */
Connector.prototype.updateAnnotation = function (annotation, points, bounds, textElement, canRefresh) {
//let getPointloop: SegmentInfo;
//let align: Alignment; let hAlign: string;
var pivotPoint = { x: 0, y: 0 };
//Bug 881512: Wrapping of the connector annotation at run time not working properly.
//To refresh the annotation at run time while moving connector end points or while moving nodes connected with connector.
if ((textElement instanceof TextElement) && (!canRefresh)) {
textElement.refreshTextElement();
}
textElement.width = (annotation.width || bounds.width);
var getPointloop = getAnnotationPosition(points, annotation, bounds);
var newPoint = getPointloop.point;
if (annotation instanceof PathAnnotation && annotation.segmentAngle) {
textElement.rotateAngle = annotation.rotateAngle + getPointloop.angle;
textElement.rotateAngle = (textElement.rotateAngle + 360) % 360;
}
if (bounds.width === 0) {
bounds.width = this.style.strokeWidth;
}
if (bounds.height === 0) {
bounds.height = this.style.strokeWidth;
}
var offsetPoint = { x: ((newPoint.x - bounds.x) / bounds.width), y: ((newPoint.y - bounds.y) / bounds.height) };
pivotPoint.x = bounds.width * offsetPoint.x;
pivotPoint.y = bounds.height * offsetPoint.y;
var align = alignLabelOnSegments(annotation, getPointloop.angle, points);
var hAlign = align.hAlign;
var vAlign = align.vAlign;
var horizor;
var verzor;
if (hAlign === 'left') {
horizor = 'Left';
pivotPoint.x += annotation.displacement.x;
}
else if (hAlign === 'right') {
horizor = 'Right';
pivotPoint.x -= annotation.displacement.x;
}
else if (hAlign === 'center') {
horizor