orcasvn-react-diagrams 0.1.36 → 0.1.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -486,6 +486,7 @@ function generateUniqueId() {
486
486
  var Element$2 = /** @class */ (function () {
487
487
  function Element(x, y, width, height, cssClass, renderShape, texts, ports, portMovealeAreas, portSlideRailSVGClassName, portDirection, parentElement, textsPlaceHolderClassName, textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition) {
488
488
  if (portMovealeAreas === void 0) { portMovealeAreas = []; }
489
+ this.positionAnchor = exports.PositioningAnchor.TopLeft;
489
490
  this._childrenElements = [];
490
491
  this.resizability = {
491
492
  enabled: true,
@@ -7284,6 +7285,99 @@ var checkPositionOnLine = function (position, line) {
7284
7285
  return _line.contains(point);
7285
7286
  };
7286
7287
 
7288
+ // Calculate the position of the 4 vertices of a rectangle relative to its parent svg
7289
+ var getRectangleCorners = function (rectSVG) {
7290
+ var ownerSVG = rectSVG.ownerSVGElement;
7291
+ var rectStrokeWidth = Number(rectSVG.getAttribute('stroke-width')) || 0;
7292
+ var strokeWidthOffset = rectStrokeWidth / 2;
7293
+ if (!ownerSVG) {
7294
+ throw new Error('Rectangle does not wrapper by svg.');
7295
+ }
7296
+ var ownerX = ownerSVG.x.baseVal.value;
7297
+ var ownerY = ownerSVG.y.baseVal.value;
7298
+ var ownerWidth = ownerSVG.width.baseVal.value;
7299
+ var ownerHeight = ownerSVG.height.baseVal.value;
7300
+ var a = { x: ownerX + strokeWidthOffset, y: ownerY + strokeWidthOffset };
7301
+ var b = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + strokeWidthOffset };
7302
+ var c = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7303
+ var d = { x: ownerX + strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
7304
+ return [a, b, c, d];
7305
+ };
7306
+ //find rotation angle of svg element on g element
7307
+ var getElementRotationInfo = function (element) {
7308
+ var gElement = element;
7309
+ var rotationAngle = 0;
7310
+ while (!(gElement instanceof SVGGElement)) {
7311
+ gElement = gElement.parentElement;
7312
+ }
7313
+ var transform = gElement.getAttribute('transform');
7314
+ if (transform) {
7315
+ // Match the rotation value using a regular expression
7316
+ var rotateMatch = transform.match(/rotate\(([-\d.]+)(?:\s+[-\d.]+\s+[-\d.]+)?\)/);
7317
+ if (rotateMatch) {
7318
+ // The first capture group is the rotation angle
7319
+ rotationAngle = parseFloat(rotateMatch[1]);
7320
+ }
7321
+ }
7322
+ return rotationAngle;
7323
+ };
7324
+
7325
+ // const topLeftOffsetOfSquareHoldingRect = (x: number, y: number, rectWidth: number, rectHeight: number, rotation?: number): IPosition => {
7326
+ // rotation = rotation || 0;
7327
+ // const rotationInRadians = rotation * Math.PI / 180;
7328
+ // //calculate the bouding edge of the square that holds the rectangle with the given width and height and rotation, knowing that the square is always parallel to the x and y axis
7329
+ // //calculate a1 equal sin of rotation * height
7330
+ // const a1 = Math.abs(Math.sin(rotationInRadians) * rectHeight);
7331
+ // //calculate a2 equal cos of rotation * width
7332
+ // const a2 = Math.abs(Math.cos(rotationInRadians) * rectWidth);
7333
+ // const a = a1 + a2;
7334
+ // console.info(`a1: ${a1}, a2: ${a2}, a: ${a}`);
7335
+ // //calculate b1 equal cos of rotation * height
7336
+ // const b1 = Math.abs(Math.cos(rotationInRadians) * rectHeight);
7337
+ // //calculate b2 equal sin of rotation * width
7338
+ // const b2 = Math.abs(Math.sin(rotationInRadians) * rectWidth);
7339
+ // const b = b1 + b2;
7340
+ // console.info(`b1: ${b1}, b2: ${b2}, b: ${b}`);
7341
+ // //const squareEdge = Math.max(rectWidth, rectHeight);
7342
+ // return {x, y};
7343
+ // return { x: x - (b - rectWidth) / 2, y: y - (a - rectHeight) / 2 };
7344
+ // }
7345
+ var diamondEdgeInsideSquare = function (squareEdgeSize) {
7346
+ return (squareEdgeSize / 2) * Math.sqrt(2);
7347
+ };
7348
+ function degreeToRadian(degree) {
7349
+ return degree * (Math.PI / 180);
7350
+ }
7351
+ //rotate the four vertices of the rectangle
7352
+ function getRotatedRectangleCoordinates(actualPoints, centerX, centerY, angle) {
7353
+ var coordinatesAfterRotation = [];
7354
+ for (var i = 0; i < 4; i++) {
7355
+ var point = actualPoints[i];
7356
+ var tempX = point.x - centerX;
7357
+ var tempY = point.y - centerY;
7358
+ var rotatedX = tempX * Math.cos(degreeToRadian(angle)) - tempY * Math.sin(degreeToRadian(angle));
7359
+ var rotatedY = tempX * Math.sin(degreeToRadian(angle)) + tempY * Math.cos(degreeToRadian(angle));
7360
+ point.x = rotatedX + centerX;
7361
+ point.y = rotatedY + centerY;
7362
+ coordinatesAfterRotation.push({ x: point.x, y: point.y });
7363
+ }
7364
+ return coordinatesAfterRotation;
7365
+ }
7366
+ //Calculate the angle between 2 points relative to the OX axis
7367
+ function calculateAngleWithOx(pStart, pEnd) {
7368
+ var deltaX = pEnd.x - pStart.x;
7369
+ var deltaY = pEnd.y - pStart.y;
7370
+ // Calculate the angle in radians
7371
+ var angleInRadians = Math.atan2(deltaY, deltaX);
7372
+ // Convert to degrees (optional)
7373
+ var angleInDegrees = angleInRadians * (180 / Math.PI);
7374
+ // Ensure the angle is positive (optional, depending on use case)
7375
+ if (angleInDegrees < 0) {
7376
+ angleInDegrees += 360;
7377
+ }
7378
+ return angleInDegrees;
7379
+ }
7380
+
7287
7381
  /**
7288
7382
  * Check if position 1 is within the radius r of position 2
7289
7383
  * @returns boolean
@@ -7575,6 +7669,14 @@ var getAbsolutePosition = function (element) {
7575
7669
  y: y,
7576
7670
  };
7577
7671
  };
7672
+ //get absolute position of element
7673
+ var getPortAbsolutePosition = function (port, element) {
7674
+ var elementAbsolutePosition = getAbsolutePosition(element);
7675
+ return {
7676
+ x: elementAbsolutePosition.x + port.position.x,
7677
+ y: elementAbsolutePosition.y + port.position.y,
7678
+ };
7679
+ };
7578
7680
  var transformAbsPositionToElementRelativePosition = function (position, element) {
7579
7681
  var parentElement = element.parentElement;
7580
7682
  if (!parentElement) {
@@ -7593,6 +7695,91 @@ var transformAbsPositionToRelativePositionInsideElement = function (absolutePosi
7593
7695
  y: absolutePosition.y - ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0),
7594
7696
  };
7595
7697
  return position;
7698
+ };
7699
+ var correctPortPositionInElement = function (elementRelativePosition, elementWidth, elementHeight, portMoveableAreas, portSlideRailSVGClassName, element) {
7700
+ //Normalize a point so that it can lie exactly on an area
7701
+ var normalizePortPositionOnMoveableAreas = function (moveableAreas, position) {
7702
+ var lines = moveableAreas.filter(function (area) { return area.length === 2; });
7703
+ var polygons = moveableAreas.filter(function (area) { return area.length >= 3; });
7704
+ var normalizedPosition;
7705
+ //If moveableAreas is lines
7706
+ if (lines.length > 0) {
7707
+ var newPosition_1 = findNearestProjectedPoint({ x: position.x, y: position.y }, lines);
7708
+ if (newPosition_1) {
7709
+ normalizedPosition = newPosition_1;
7710
+ }
7711
+ }
7712
+ //If moveableAreas is polygons
7713
+ else if (polygons.length > 0) {
7714
+ var newPosition_2 = { x: position.x, y: position.y };
7715
+ var isContainsInPolygons = polygons.some(function (p) { return checkPointContainsPolygon(newPosition_2, p); });
7716
+ if (isContainsInPolygons) {
7717
+ normalizedPosition = newPosition_2;
7718
+ }
7719
+ }
7720
+ return normalizedPosition;
7721
+ };
7722
+ var getSlideRailSVG = function (portSlideRailSVGClassName) {
7723
+ if (!element)
7724
+ return;
7725
+ var slideRailSVG = element.querySelector(".".concat(portSlideRailSVGClassName));
7726
+ return slideRailSVG;
7727
+ };
7728
+ //Calculate the position of the 4 vertices of a rectangle relative to element
7729
+ var calculateSlideRailRectSVGPositions = function (slideRailSVG) {
7730
+ var coordinates = getRectangleCorners(slideRailSVG);
7731
+ var ownerSVG = slideRailSVG.ownerSVGElement;
7732
+ var rotationAngle = getElementRotationInfo(ownerSVG);
7733
+ if (rotationAngle !== 0) {
7734
+ var rotationCenterX = elementWidth / 2;
7735
+ var rotationCenterY = elementHeight / 2;
7736
+ coordinates = getRotatedRectangleCoordinates(coordinates, rotationCenterX, rotationCenterY, rotationAngle);
7737
+ }
7738
+ return coordinates;
7739
+ };
7740
+ var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
7741
+ var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
7742
+ if (!slideRailSVG)
7743
+ return;
7744
+ var moveTo;
7745
+ //check and get new position if Rect element
7746
+ if (slideRailSVG instanceof SVGRectElement) {
7747
+ var _a = calculateSlideRailRectSVGPositions(slideRailSVG), a = _a[0], b = _a[1], c = _a[2], d = _a[3]; //Get 4 vertices of rect element
7748
+ var moveableAreas = [
7749
+ [a, b],
7750
+ [b, c],
7751
+ [c, d],
7752
+ [d, a]
7753
+ ];
7754
+ console.info("Port's moveable areas parsed from svg ".concat(portSlideRailSVGClassName), moveableAreas);
7755
+ var newPosition_3 = normalizePortPositionOnMoveableAreas(moveableAreas, position);
7756
+ if (newPosition_3) {
7757
+ moveTo = newPosition_3;
7758
+ }
7759
+ }
7760
+ else if (slideRailSVG instanceof SVGCircleElement) { //check and get new position if circle element
7761
+ var cx = Number(slideRailSVG.getAttribute('cx'));
7762
+ var cy = Number(slideRailSVG.getAttribute('cy'));
7763
+ var r = Number(slideRailSVG.getAttribute('r'));
7764
+ var circle = Flatten$1.circle(Flatten$1.point(cx, cy), r);
7765
+ var _b = circle.distanceTo(Flatten$1.point(position.x, position.y)), num = _b[0], segment = _b[1];
7766
+ if (num <= r) {
7767
+ moveTo = {
7768
+ x: segment.ps.x,
7769
+ y: segment.ps.y,
7770
+ };
7771
+ }
7772
+ }
7773
+ return moveTo;
7774
+ };
7775
+ var newPosition;
7776
+ if (portMoveableAreas && portMoveableAreas.length > 0) { //If moveable areas is defined
7777
+ newPosition = normalizePortPositionOnMoveableAreas(portMoveableAreas, elementRelativePosition);
7778
+ }
7779
+ else if (portSlideRailSVGClassName) { //If port slide rail svg classname is defined
7780
+ newPosition = normalizePortPositionOnSlideRailSVG(portSlideRailSVGClassName, elementRelativePosition);
7781
+ }
7782
+ return newPosition || elementRelativePosition;
7596
7783
  };
7597
7784
 
7598
7785
  var Port1 = React.forwardRef(function (props, ref) {
@@ -7635,6 +7822,10 @@ var Port = React.memo(Port1);
7635
7822
  // Render the svg <path> element
7636
7823
  function getCurvePathData(points, smoothing, closed) {
7637
7824
  if (smoothing === void 0) { smoothing = 0.2; }
7825
+ // append first 2 points for closed paths
7826
+ if (closed) {
7827
+ points = points.concat(points.slice(0, 2));
7828
+ }
7638
7829
  // Properties of a line
7639
7830
  var line = function (pointA, pointB) {
7640
7831
  var lengthX = pointB.x - pointA.x;
@@ -7667,6 +7858,18 @@ function getCurvePathData(points, smoothing, closed) {
7667
7858
  };
7668
7859
  pathData.push(command);
7669
7860
  }
7861
+ // copy last commands 1st controlpoint to first curveto
7862
+ if (closed) {
7863
+ var comLast = pathData[pathData.length - 1];
7864
+ var valuesLastC = comLast.values;
7865
+ var valuesFirstC = pathData[1].values;
7866
+ pathData[1] = {
7867
+ type: "C",
7868
+ values: [valuesLastC[0], valuesLastC[1], valuesFirstC.slice(2)].flat()
7869
+ };
7870
+ // delete last curveto
7871
+ pathData = pathData.slice(0, pathData.length - 1);
7872
+ }
7670
7873
  return pathData;
7671
7874
  }
7672
7875
  // convert pathdata to d attribute string
@@ -7680,7 +7883,7 @@ function pathDataToD(pathData, decimals) {
7680
7883
  return d;
7681
7884
  }
7682
7885
  function createSmoothPathString(points, smoothing, close) {
7683
- var pathData = getCurvePathData(points, smoothing);
7886
+ var pathData = getCurvePathData(points, smoothing, close);
7684
7887
  var pathString = pathDataToD(pathData);
7685
7888
  return pathString;
7686
7889
  }
@@ -7735,59 +7938,6 @@ function addPointToList(point, listPoints, path) {
7735
7938
  return __spreadArray([], listPoints, true);
7736
7939
  }
7737
7940
 
7738
- // const topLeftOffsetOfSquareHoldingRect = (x: number, y: number, rectWidth: number, rectHeight: number, rotation?: number): IPosition => {
7739
- // rotation = rotation || 0;
7740
- // const rotationInRadians = rotation * Math.PI / 180;
7741
- // //calculate the bouding edge of the square that holds the rectangle with the given width and height and rotation, knowing that the square is always parallel to the x and y axis
7742
- // //calculate a1 equal sin of rotation * height
7743
- // const a1 = Math.abs(Math.sin(rotationInRadians) * rectHeight);
7744
- // //calculate a2 equal cos of rotation * width
7745
- // const a2 = Math.abs(Math.cos(rotationInRadians) * rectWidth);
7746
- // const a = a1 + a2;
7747
- // console.info(`a1: ${a1}, a2: ${a2}, a: ${a}`);
7748
- // //calculate b1 equal cos of rotation * height
7749
- // const b1 = Math.abs(Math.cos(rotationInRadians) * rectHeight);
7750
- // //calculate b2 equal sin of rotation * width
7751
- // const b2 = Math.abs(Math.sin(rotationInRadians) * rectWidth);
7752
- // const b = b1 + b2;
7753
- // console.info(`b1: ${b1}, b2: ${b2}, b: ${b}`);
7754
- // //const squareEdge = Math.max(rectWidth, rectHeight);
7755
- // return {x, y};
7756
- // return { x: x - (b - rectWidth) / 2, y: y - (a - rectHeight) / 2 };
7757
- // }
7758
- function degreeToRadian(degree) {
7759
- return degree * (Math.PI / 180);
7760
- }
7761
- //rotate the four vertices of the rectangle
7762
- function getRotatedRectangleCoordinates(actualPoints, centerX, centerY, angle) {
7763
- var coordinatesAfterRotation = [];
7764
- for (var i = 0; i < 4; i++) {
7765
- var point = actualPoints[i];
7766
- var tempX = point.x - centerX;
7767
- var tempY = point.y - centerY;
7768
- var rotatedX = tempX * Math.cos(degreeToRadian(angle)) - tempY * Math.sin(degreeToRadian(angle));
7769
- var rotatedY = tempX * Math.sin(degreeToRadian(angle)) + tempY * Math.cos(degreeToRadian(angle));
7770
- point.x = rotatedX + centerX;
7771
- point.y = rotatedY + centerY;
7772
- coordinatesAfterRotation.push({ x: point.x, y: point.y });
7773
- }
7774
- return coordinatesAfterRotation;
7775
- }
7776
- //Calculate the angle between 2 points relative to the OX axis
7777
- function calculateAngleWithOx(pStart, pEnd) {
7778
- var deltaX = pEnd.x - pStart.x;
7779
- var deltaY = pEnd.y - pStart.y;
7780
- // Calculate the angle in radians
7781
- var angleInRadians = Math.atan2(deltaY, deltaX);
7782
- // Convert to degrees (optional)
7783
- var angleInDegrees = angleInRadians * (180 / Math.PI);
7784
- // Ensure the angle is positive (optional, depending on use case)
7785
- if (angleInDegrees < 0) {
7786
- angleInDegrees += 360;
7787
- }
7788
- return angleInDegrees;
7789
- }
7790
-
7791
7941
  //Defined remove icon for element link, shown when element link is selected.
7792
7942
  function CloseIcon(_a) {
7793
7943
  var onClick = _a.onClick;
@@ -7850,7 +8000,7 @@ var IElementLink = function (_a) {
7850
8000
  }, []);
7851
8001
  React.useLayoutEffect(function () {
7852
8002
  var pointsList = __spreadArray(__spreadArray([sourcePosition], points, true), [targetPosition], false);
7853
- var _pathStr = createSmoothPathString(pointsList, undefined);
8003
+ var _pathStr = createSmoothPathString(pointsList, undefined, false);
7854
8004
  setPathStr(_pathStr);
7855
8005
  }, [sourcePosition, points, targetPosition]);
7856
8006
  React.useEffect(function () {
@@ -8051,6 +8201,129 @@ var IElementLink = function (_a) {
8051
8201
  };
8052
8202
  var ElementLink = React.memo(IElementLink);
8053
8203
 
8204
+ var getSVGBBoxOutsideTransformedParent = function (svgElement) {
8205
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
8206
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
8207
+ // Define the four corners of the bounding box
8208
+ var corners = [
8209
+ { x: bbox.x, y: bbox.y },
8210
+ { x: bbox.x + bbox.width, y: bbox.y },
8211
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
8212
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
8213
+ ];
8214
+ // Function to apply the transformation matrix to a point
8215
+ function transformPoint(x, y, matrix) {
8216
+ return {
8217
+ x: matrix.a * x + matrix.c * y + matrix.e,
8218
+ y: matrix.b * x + matrix.d * y + matrix.f
8219
+ };
8220
+ }
8221
+ // Transform each corner according to the matrix
8222
+ if (matrix) {
8223
+ return corners.map(function (corner) {
8224
+ return transformPoint(corner.x, corner.y, matrix);
8225
+ });
8226
+ }
8227
+ else {
8228
+ return corners;
8229
+ }
8230
+ };
8231
+ //function returns the array of corners of the bbox of the element after applying the transformation matrix of the parent element
8232
+ var getRotatedSVGBBox = function (svgElement) {
8233
+ var bbox = svgElement.getBBox(); // Get bounding box of the element
8234
+ var matrix = svgElement.getCTM(); // Get the current transformation matrix of the parent element
8235
+ // Define the four corners of the bounding box
8236
+ var corners = [
8237
+ { x: bbox.x, y: bbox.y },
8238
+ { x: bbox.x + bbox.width, y: bbox.y },
8239
+ { x: bbox.x + bbox.width, y: bbox.y + bbox.height },
8240
+ { x: bbox.x, y: bbox.y + bbox.height } // Bottom-left
8241
+ ];
8242
+ // Function to apply the transformation matrix to a point
8243
+ function transformPoint(x, y, matrix) {
8244
+ return {
8245
+ x: matrix.a * x + matrix.c * y,
8246
+ y: matrix.b * x + matrix.d * y // + matrix.f
8247
+ };
8248
+ }
8249
+ // Transform each corner according to the matrix
8250
+ if (matrix) {
8251
+ return corners.map(function (corner) {
8252
+ return transformPoint(corner.x, corner.y, matrix);
8253
+ });
8254
+ }
8255
+ else {
8256
+ return corners;
8257
+ }
8258
+ };
8259
+
8260
+ var Logger = /** @class */ (function () {
8261
+ function Logger() {
8262
+ this.level = 'info';
8263
+ this.customLogger = null;
8264
+ }
8265
+ Logger.prototype.setLevel = function (level) {
8266
+ this.level = level;
8267
+ };
8268
+ Logger.prototype.setCustomLogger = function (logger) {
8269
+ this.customLogger = logger;
8270
+ };
8271
+ Logger.prototype.log = function (level, message) {
8272
+ var _a;
8273
+ var optionalParams = [];
8274
+ for (var _i = 2; _i < arguments.length; _i++) {
8275
+ optionalParams[_i - 2] = arguments[_i];
8276
+ }
8277
+ var levels = ['error', 'warn', 'info', 'debug'];
8278
+ if (this.level && levels.indexOf(level) <= levels.indexOf(this.level)) {
8279
+ if (this.customLogger) {
8280
+ this.customLogger.apply(this, __spreadArray([level, message], optionalParams, false));
8281
+ }
8282
+ else {
8283
+ console[level] ? (_a = console)[level].apply(_a, __spreadArray([message], optionalParams, false)) : console.log.apply(console, __spreadArray([message], optionalParams, false));
8284
+ }
8285
+ }
8286
+ };
8287
+ Logger.prototype.error = function (msg) {
8288
+ var optionalParams = [];
8289
+ for (var _i = 1; _i < arguments.length; _i++) {
8290
+ optionalParams[_i - 1] = arguments[_i];
8291
+ }
8292
+ this.log.apply(this, __spreadArray(['error', msg], optionalParams, false));
8293
+ };
8294
+ Logger.prototype.warn = function (msg) {
8295
+ var optionalParams = [];
8296
+ for (var _i = 1; _i < arguments.length; _i++) {
8297
+ optionalParams[_i - 1] = arguments[_i];
8298
+ }
8299
+ this.log.apply(this, __spreadArray(['warn', msg], optionalParams, false));
8300
+ };
8301
+ Logger.prototype.info = function (msg) {
8302
+ var optionalParams = [];
8303
+ for (var _i = 1; _i < arguments.length; _i++) {
8304
+ optionalParams[_i - 1] = arguments[_i];
8305
+ }
8306
+ this.log.apply(this, __spreadArray(['info', msg], optionalParams, false));
8307
+ };
8308
+ Logger.prototype.debug = function (msg) {
8309
+ var optionalParams = [];
8310
+ for (var _i = 1; _i < arguments.length; _i++) {
8311
+ optionalParams[_i - 1] = arguments[_i];
8312
+ }
8313
+ this.log.apply(this, __spreadArray(['debug', msg], optionalParams, false));
8314
+ };
8315
+ return Logger;
8316
+ }());
8317
+ var logger = new Logger();
8318
+
8319
+ function configureLogger(_a) {
8320
+ var level = _a.level, customLogger = _a.customLogger;
8321
+ if (level !== undefined)
8322
+ logger.setLevel(level);
8323
+ if (customLogger)
8324
+ logger.setCustomLogger(customLogger);
8325
+ }
8326
+
8054
8327
  var Ruler = function (_a) {
8055
8328
  var squareSize = _a.squareSize, border = _a.border;
8056
8329
  var numColumns = Math.ceil(3000 / squareSize);
@@ -8090,44 +8363,7 @@ var ElementWrapper = React.forwardRef(function (_a, ref) {
8090
8363
  return (React.createElement("svg", { className: cssClass, x: x, y: y, onClick: handleClick, onContextMenu: handleClick, onMouseDown: handleMouseDown, ref: ref, style: { overflow: "visible" }, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, onMouseUp: onMouseUp }, children));
8091
8364
  });
8092
8365
 
8093
- // Calculate the position of the 4 vertices of a rectangle relative to its parent svg
8094
- var getRectangleCorners = function (rectSVG) {
8095
- var ownerSVG = rectSVG.ownerSVGElement;
8096
- var rectStrokeWidth = Number(rectSVG.getAttribute('stroke-width')) || 0;
8097
- var strokeWidthOffset = rectStrokeWidth / 2;
8098
- if (!ownerSVG) {
8099
- throw new Error('Rectangle does not wrapper by svg.');
8100
- }
8101
- var ownerX = ownerSVG.x.baseVal.value;
8102
- var ownerY = ownerSVG.y.baseVal.value;
8103
- var ownerWidth = ownerSVG.width.baseVal.value;
8104
- var ownerHeight = ownerSVG.height.baseVal.value;
8105
- var a = { x: ownerX + strokeWidthOffset, y: ownerY + strokeWidthOffset };
8106
- var b = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + strokeWidthOffset };
8107
- var c = { x: ownerX + ownerWidth - strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
8108
- var d = { x: ownerX + strokeWidthOffset, y: ownerY + ownerHeight - strokeWidthOffset };
8109
- return [a, b, c, d];
8110
- };
8111
- //find rotation angle of svg element on g element
8112
- var getElementRotationInfo = function (element) {
8113
- var gElement = element;
8114
- var rotationAngle = 0;
8115
- while (!(gElement instanceof SVGGElement)) {
8116
- gElement = gElement.parentElement;
8117
- }
8118
- var transform = gElement.getAttribute('transform');
8119
- if (transform) {
8120
- // Match the rotation value using a regular expression
8121
- var rotateMatch = transform.match(/rotate\(([-\d.]+)(?:\s+[-\d.]+\s+[-\d.]+)?\)/);
8122
- if (rotateMatch) {
8123
- // The first capture group is the rotation angle
8124
- rotationAngle = parseFloat(rotateMatch[1]);
8125
- }
8126
- }
8127
- return rotationAngle;
8128
- };
8129
-
8130
- var Element = function (props) {
8366
+ var Element = React.forwardRef(function (props, forwardedRef) {
8131
8367
  var _a, _b;
8132
8368
  var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, cssClass = props.cssClass, portPlaceholderShape = props.portPlaceholderShape, children = props.children, container = props.container, parentAbsolutePosition = props.parentAbsolutePosition; props.textsPlaceHolderFlexStyle; props.textsPlaceHolderFlexboxPosition; props.textsPlaceHolderClassName; var texts = props.texts, portSlideRailSVGClassName = props.portSlideRailSVGClassName, portMoveableAreas = props.portMoveableAreas, portDirection = props.portDirection, defaultPortSize = props.defaultPortSize, onClick = props.onClick, onContextMenu = props.onContextMenu, renderShape = props.renderShape; props.onMoved; var onPortMoved = props.onPortMoved; props.onResized; var onPortMouseDown = props.onPortMouseDown, onPortMouseUp = props.onPortMouseUp, onMouseMove = props.onMouseMove, onMouseLeave = props.onMouseLeave, onMouseUp = props.onMouseUp, onMouseUpAtLinkedPortPlaceholder = props.onMouseUpAtLinkedPortPlaceholder, onTextUpdated = props.onTextUpdated;
8133
8369
  var _c = React.useState(), selectedPort = _c[0], setSelectedPort = _c[1];
@@ -8137,6 +8373,7 @@ var Element = function (props) {
8137
8373
  var _g = React.useState(), potentialPortPosition = _g[0], setPotentialPortPosition = _g[1];
8138
8374
  var _paperEventEmitterContext = React.useContext(paperEventEmitterContext);
8139
8375
  var elementRef = React.useRef(null);
8376
+ React.useImperativeHandle(forwardedRef, function () { return elementRef.current; });
8140
8377
  var elementLinkStarted = React.useRef();
8141
8378
  var portsRef = React.useRef(ports);
8142
8379
  var getElementAbsPosition = React.useCallback(function () {
@@ -8157,6 +8394,7 @@ var Element = function (props) {
8157
8394
  var off = (_a = props.onManuallyTriggerRenderPort) === null || _a === void 0 ? void 0 : _a.call(props, function (portId, elementId) {
8158
8395
  if (elementId !== id)
8159
8396
  return;
8397
+ logger.info('onManuallyTriggerRenderPort', id);
8160
8398
  setPorts(function (prev) { return __spreadArray([], prev, true); });
8161
8399
  });
8162
8400
  return function () {
@@ -8169,6 +8407,7 @@ var Element = function (props) {
8169
8407
  }, [ports]);
8170
8408
  //Listen a new port is created, after add new port to ports state
8171
8409
  React.useEffect(function () {
8410
+ logger.info('Ports changed', props.ports);
8172
8411
  setPorts(function (prev) {
8173
8412
  var _a, _b;
8174
8413
  return (_b = (_a = props.ports) === null || _a === void 0 ? void 0 : _a.map(function (p, index) {
@@ -8282,28 +8521,6 @@ var Element = function (props) {
8282
8521
  setSelectedPort(port);
8283
8522
  _paperEventEmitterContext.emitPortSelected(port, id);
8284
8523
  }, [_paperEventEmitterContext]);
8285
- //Normalize a point so that it can lie exactly on an area
8286
- var normalizePortPositionOnMoveableAreas = function (moveableAreas, position) {
8287
- var lines = moveableAreas.filter(function (area) { return area.length === 2; });
8288
- var polygons = moveableAreas.filter(function (area) { return area.length >= 3; });
8289
- var normalizedPosition;
8290
- //If moveableAreas is lines
8291
- if (lines.length > 0) {
8292
- var newPosition = findNearestProjectedPoint({ x: position.x, y: position.y }, lines);
8293
- if (newPosition) {
8294
- normalizedPosition = newPosition;
8295
- }
8296
- }
8297
- //If moveableAreas is polygons
8298
- else if (polygons.length > 0) {
8299
- var newPosition_1 = { x: position.x, y: position.y };
8300
- var isContainsInPolygons = polygons.some(function (p) { return checkPointContainsPolygon(newPosition_1, p); });
8301
- if (isContainsInPolygons) {
8302
- normalizedPosition = newPosition_1;
8303
- }
8304
- }
8305
- return normalizedPosition;
8306
- };
8307
8524
  //Calculate the position of the 4 vertices of a rectangle relative to element
8308
8525
  var calculateSlideRailRectSVGPositions = function (slideRailSVG) {
8309
8526
  var coordinates = getRectangleCorners(slideRailSVG);
@@ -8320,50 +8537,10 @@ var Element = function (props) {
8320
8537
  var _a;
8321
8538
  var slideRailSVG = (_a = elementRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(".".concat(portSlideRailSVGClassName));
8322
8539
  return slideRailSVG;
8323
- }, [elementRef.current]);
8324
- var normalizePortPositionOnSlideRailSVG = function (portSlideRailSVGClassName, position) {
8325
- var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
8326
- if (!slideRailSVG)
8327
- return;
8328
- var moveTo;
8329
- //check and get new position if Rect element
8330
- if (slideRailSVG instanceof SVGRectElement) {
8331
- var _a = calculateSlideRailRectSVGPositions(slideRailSVG), a = _a[0], b = _a[1], c = _a[2], d = _a[3]; //Get 4 vertices of rect element
8332
- var moveableAreas = [
8333
- [a, b],
8334
- [b, c],
8335
- [c, d],
8336
- [d, a]
8337
- ];
8338
- var newPosition = normalizePortPositionOnMoveableAreas(moveableAreas, position);
8339
- if (newPosition) {
8340
- moveTo = newPosition;
8341
- }
8342
- }
8343
- else if (slideRailSVG instanceof SVGCircleElement) { //check and get new position if circle element
8344
- var cx = Number(slideRailSVG.getAttribute('cx'));
8345
- var cy = Number(slideRailSVG.getAttribute('cy'));
8346
- var r = Number(slideRailSVG.getAttribute('r'));
8347
- var circle = Flatten$1.circle(Flatten$1.point(cx, cy), r);
8348
- var _b = circle.distanceTo(Flatten$1.point(position.x, position.y)), num = _b[0], segment = _b[1];
8349
- if (num <= r) {
8350
- moveTo = {
8351
- x: segment.ps.x,
8352
- y: segment.ps.y,
8353
- };
8354
- }
8355
- }
8356
- return moveTo;
8357
- };
8540
+ }, []);
8358
8541
  //Normalize port position
8359
8542
  var normalizePortPosition = function (tempNewPosition) {
8360
- var newPosition;
8361
- if (portMoveableAreas && portMoveableAreas.length > 0) { //If moveable areas is defined
8362
- newPosition = normalizePortPositionOnMoveableAreas(portMoveableAreas, tempNewPosition);
8363
- }
8364
- else if (portSlideRailSVGClassName) { //If port slide rail svg classname is defined
8365
- newPosition = normalizePortPositionOnSlideRailSVG(portSlideRailSVGClassName, tempNewPosition);
8366
- }
8543
+ var newPosition = correctPortPositionInElement(tempNewPosition, width, height, portMoveableAreas, portSlideRailSVGClassName, elementRef.current || undefined);
8367
8544
  return newPosition || tempNewPosition;
8368
8545
  };
8369
8546
  var handlePortMove = function (newX, newY) {
@@ -8515,7 +8692,7 @@ var Element = function (props) {
8515
8692
  }, [someElementLinkStarted]);
8516
8693
  //Get rotate angle of port by port direction is defined.
8517
8694
  var rotatePort = React.useCallback(function (x, y) {
8518
- // console.info('calculating port rotation', x, y)
8695
+ // logger.info('calculating port rotation', x, y)
8519
8696
  if (!portSlideRailSVGClassName)
8520
8697
  return 0;
8521
8698
  var slideRailSVG = getSlideRailSVG(portSlideRailSVGClassName);
@@ -8612,7 +8789,7 @@ var Element = function (props) {
8612
8789
  return React.createElement(Text$1, { id: t.id, key: index, content: t.content, x: ((_a = t.position) === null || _a === void 0 ? void 0 : _a.x) || 0, y: ((_b = t.position) === null || _b === void 0 ? void 0 : _b.y) || 0, width: t.size.width, height: t.size.height, editable: t.editable, align: t.align, fontSize: t.fontSize, border: t.border, container: container, style: t.style, parentAbsolutePosition: elementAbsPosition, onContentChanged: function (ev, newContent) { return onTextUpdated === null || onTextUpdated === void 0 ? void 0 : onTextUpdated(id, t.id, newContent); } });
8613
8790
  }),
8614
8791
  children));
8615
- };
8792
+ });
8616
8793
  var Element$1 = React.memo(Element);
8617
8794
 
8618
8795
  var createRect = function (x, y, width, height, strokeWidth, transformOrigin, transform) {
@@ -8865,6 +9042,15 @@ var automationAddPointsToLink = function (eleLink, elements, limitPoint) {
8865
9042
  return eleLink;
8866
9043
  };
8867
9044
 
9045
+ function adjustElementPositionOnParentPortArea(element, toBeAdjustedRelativePosition) {
9046
+ var _a;
9047
+ if (element.moveAsPortOnParent && element.parentElement) {
9048
+ var parentDOM = (_a = element.parentElementInTree) === null || _a === void 0 ? void 0 : _a.DOM;
9049
+ var newRelativePosition = transformAbsPositionToElementRelativePosition(toBeAdjustedRelativePosition, element);
9050
+ return correctPortPositionInElement(newRelativePosition, element.size.width, element.size.height, element.parentElement.portMoveableAreas, element.parentElement.portSlideRailSVGClassName, parentDOM);
9051
+ }
9052
+ return toBeAdjustedRelativePosition;
9053
+ }
8868
9054
  function convertElementsToTree(elements) {
8869
9055
  //Find child elements in the child elements, that is possible child of element, then return element with child of it.
8870
9056
  function findChildElementsOfNode(elementNodeInTree, possibleChildElements) {
@@ -8876,6 +9062,11 @@ function convertElementsToTree(elements) {
8876
9062
  var orphanedElements = possibleChildElements.filter(function (ele) { var _a; return ((_a = ele.parentElement) === null || _a === void 0 ? void 0 : _a.id) !== elementNodeInTree.id; });
8877
9063
  var childElementsWithChild = foundChildElements.map(function (_elementNodeInTree) {
8878
9064
  var newNode = findChildElementsOfNode(_elementNodeInTree, orphanedElements);
9065
+ newNode.parentElementInTree = elementNodeInTree;
9066
+ //Adjust position of element if it should move as a port on parent port area
9067
+ if (newNode.moveAsPortOnParent && newNode.parentElementInTree) {
9068
+ newNode.position = adjustElementPositionOnParentPortArea(newNode, newNode.position);
9069
+ }
8879
9070
  return newNode;
8880
9071
  });
8881
9072
  elementNodeInTree.childrenElementsInTree = childElementsWithChild;
@@ -8987,6 +9178,7 @@ var Paper = function (props) {
8987
9178
  var parentChangedCancelers = elementsRef.current.map(function (element) {
8988
9179
  var _a;
8989
9180
  return (_a = element.onParentChanged) === null || _a === void 0 ? void 0 : _a.call(element, function (newPa, oldPa) {
9181
+ logger.info('onParentChanged');
8990
9182
  updateElementsTree();
8991
9183
  });
8992
9184
  });
@@ -8994,7 +9186,7 @@ var Paper = function (props) {
8994
9186
  var addedPortCancelers = elementsRef.current.map(function (element) {
8995
9187
  var _a;
8996
9188
  return (_a = element.onAddedPort) === null || _a === void 0 ? void 0 : _a.call(element, function (newPort) {
8997
- console.log("A new port has been added to element ".concat(element.id));
9189
+ logger.info("A new port has been added to element ".concat(element.id));
8998
9190
  var prevElements = elementsRef.current;
8999
9191
  var newElements = prevElements.map(function (ele) {
9000
9192
  if (ele.id === element.id) {
@@ -9378,10 +9570,16 @@ var Paper = function (props) {
9378
9570
  setSelectedLink(undefined);
9379
9571
  };
9380
9572
  //update absolute position of element and absolute position of children elements
9381
- var updateElementPosition = function (element, x, y) {
9382
- var relativePosition = transformAbsPositionToElementRelativePosition({ x: x, y: y }, element);
9383
- element.position.x = relativePosition.x;
9384
- element.position.y = relativePosition.y;
9573
+ var updateElementPosition = function (element, x, y, isRelativePosition) {
9574
+ if (isRelativePosition) {
9575
+ element.position.x = x;
9576
+ element.position.y = y;
9577
+ }
9578
+ else {
9579
+ var relativePosition = transformAbsPositionToElementRelativePosition({ x: x, y: y }, element);
9580
+ element.position.x = relativePosition.x;
9581
+ element.position.y = relativePosition.y;
9582
+ }
9385
9583
  return element;
9386
9584
  };
9387
9585
  //use selection frame
@@ -9401,14 +9599,28 @@ var Paper = function (props) {
9401
9599
  if (!selectedElement)
9402
9600
  return;
9403
9601
  var oldPosition = __assign({}, selectedElement.position);
9404
- var newElementPosition = updateElementPosition(selectedElement, newX, newY);
9602
+ var newPosition = {
9603
+ x: newX,
9604
+ y: newY
9605
+ };
9606
+ console.info("Element ".concat(selectedElement.id, " is dragging to position ").concat(JSON.stringify(newPosition)));
9607
+ //Adjust position of element if it should move as a port on parent port area
9608
+ if (selectedElement.moveAsPortOnParent && selectedElement.parentElement) {
9609
+ newPosition = adjustElementPositionOnParentPortArea(selectedElement, newPosition);
9610
+ updateElementPosition(selectedElement, newPosition.x, newPosition.y, true);
9611
+ }
9612
+ else {
9613
+ updateElementPosition(selectedElement, newPosition.x, newPosition.y, false);
9614
+ }
9615
+ //let newElementPosition = updateElementPosition(selectedElement, newPosition.x, newPosition.y, true)
9405
9616
  var indexSelectedElement = elements.findIndex(function (e) { return e.id === selectedElement.id; });
9617
+ console.info("Element ".concat(selectedElement.id, " is moving to relative position ").concat(JSON.stringify(selectedElement.position)));
9406
9618
  //Set state to re-render UI with new position
9407
9619
  setElementsInTree(function (prev) { return __spreadArray([], prev, true); });
9408
9620
  if (props.onElementMoved) {
9409
- props.onElementMoved(newElementPosition.position, selectedElement, indexSelectedElement);
9621
+ props.onElementMoved(selectedElement.position, selectedElement, indexSelectedElement);
9410
9622
  }
9411
- paperEventEmitter.emitElementMoved(selectedElement, oldPosition, newElementPosition.position);
9623
+ paperEventEmitter.emitElementMoved(selectedElement, oldPosition, selectedElement.position);
9412
9624
  setMouseDownedOnPaper(false);
9413
9625
  },
9414
9626
  onResize: function (width, height) {
@@ -9472,7 +9684,7 @@ var Paper = function (props) {
9472
9684
  var targetElement = elementsRef.current.find(function (e) { return e.id === targetElementId; });
9473
9685
  if (!targetElement)
9474
9686
  return;
9475
- console.info("A port could have been created at position ".concat(JSON.stringify(position), " on element ").concat(targetElementId, " by linking from element ").concat(link.sourceElement.id));
9687
+ logger.info("A port could have been created at position ".concat(JSON.stringify(position), " on element ").concat(targetElementId, " by linking from element ").concat(link.sourceElement.id));
9476
9688
  if (props.onCreatingPortByLinking) {
9477
9689
  var sourcePort = link.sourcePort, sourceElement = link.sourceElement;
9478
9690
  //Handle create port via onCreatingPortByLinking prop
@@ -9569,7 +9781,7 @@ var Paper = function (props) {
9569
9781
  //use the defined react element or the default Element component
9570
9782
  var ReactElement = element.reactElement || Element$1;
9571
9783
  return (React.createElement("g", { id: "group-of-element-".concat(element.id), key: element.id },
9572
- React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, height: element.size.height, width: element.size.width, x: element.position.x, y: element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp,
9784
+ React.createElement(ReactElement, { key: "element-".concat(element.id), id: element.id, ref: function (refDOM) { return element.DOM = refDOM; }, height: element.size.height, width: element.size.width, x: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.x - element.size.width / 2 : element.position.x, y: element.positionAnchor === exports.PositioningAnchor.Center ? element.position.y - element.size.height / 2 : element.position.y, onClick: handleElementClicked, onContextMenu: handleContextMenu, onMouseUp: handleMouseUp, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, container: paperContainerRef.current, renderShape: element.renderShape, cssClass: element.cssClass, texts: element.texts, ports: element.ports, portMoveableAreas: element.portMoveableAreas, portSlideRailSVGClassName: element.portSlideRailSVGClassName, portDirection: element.portDirection, defaultPortSize: element.defaultPortSize, onPortMoved: handlePortMoved, onPortMouseDown: handlePortMouseDown, onPortMouseUp: handlePortMouseUp,
9573
9785
  // portPlaceholderShape={(<Circle x={0} y={0} width={10} height={10} fill='red' positioningAnchor={PositioningAnchor.Center} />)}
9574
9786
  onMouseUpAtLinkedPortPlaceholder: handleMouseUpAtLinkedPortPlaceholder, onTextUpdated: handleElementTextChange, onManuallyTriggerRenderPort: props.onManuallyTriggerRenderPort, textsPlaceHolderClassName: element.textsPlaceHolderClassName, textsPlaceHolderFlexStyle: element.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition: element.textsPlaceHolderFlexboxPosition, parentAbsolutePosition: element.parentElement ? getAbsolutePosition(element.parentElement) : undefined }, element.childrenElementsInTree && element.childrenElementsInTree.map(renderElementInTree))));
9575
9787
  }, [handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave]);
@@ -9630,6 +9842,7 @@ var Editor = function (_a) {
9630
9842
  var offs = [];
9631
9843
  if (editorContext) {
9632
9844
  offs.push(editorContext.onEditorContextUpdated(function () {
9845
+ logger.info("onEditorContextUpdated");
9633
9846
  setEditorStates(editorContext);
9634
9847
  }));
9635
9848
  }
@@ -9726,4 +9939,37 @@ exports.RectangularFrameRC = RectangularFrame;
9726
9939
  exports.ShapeWrapperRC = ShapeWrapper;
9727
9940
  exports.Text = Text$2;
9728
9941
  exports.TextRC = Text$1;
9942
+ exports.addPointToList = addPointToList;
9943
+ exports.calculateAngleWithOx = calculateAngleWithOx;
9944
+ exports.checkPointContainsPolygon = checkPointContainsPolygon;
9945
+ exports.checkPositionOnLine = checkPositionOnLine;
9946
+ exports.checkSamePosition = checkSamePosition;
9947
+ exports.configureLogger = configureLogger;
9948
+ exports.correctPortPositionInElement = correctPortPositionInElement;
9949
+ exports.createSmoothPathString = createSmoothPathString;
9729
9950
  exports.default = Editor;
9951
+ exports.degreeToRadian = degreeToRadian;
9952
+ exports.diamondEdgeInsideSquare = diamondEdgeInsideSquare;
9953
+ exports.dist = dist;
9954
+ exports.findNearestPointOnSegment = findNearestPointOnSegment;
9955
+ exports.findNearestPosition = findNearestPosition;
9956
+ exports.findNearestProjectedPoint = findNearestProjectedPoint;
9957
+ exports.generateSubstitutePosition = generateSubstitutePosition;
9958
+ exports.generateUniqueId = generateUniqueId;
9959
+ exports.getAbsolutePosition = getAbsolutePosition;
9960
+ exports.getCurvePathData = getCurvePathData;
9961
+ exports.getElementRotationInfo = getElementRotationInfo;
9962
+ exports.getFirstIntersection = getFirstIntersection;
9963
+ exports.getFourVertexesOfBBoxFromElement = getFourVertexesOfBBoxFromElement;
9964
+ exports.getIntersectionPositions = getIntersectionPositions;
9965
+ exports.getPortAbsolutePosition = getPortAbsolutePosition;
9966
+ exports.getRectangleCorners = getRectangleCorners;
9967
+ exports.getRelativePosition = getRelativePosition;
9968
+ exports.getRotatedRectangleCoordinates = getRotatedRectangleCoordinates;
9969
+ exports.getRotatedSVGBBox = getRotatedSVGBBox;
9970
+ exports.getSVGBBoxOutsideTransformedParent = getSVGBBoxOutsideTransformedParent;
9971
+ exports.makePolygonOfElement = makePolygonOfElement;
9972
+ exports.pathDataToD = pathDataToD;
9973
+ exports.removeDuplicatePosition = removeDuplicatePosition;
9974
+ exports.transformAbsPositionToElementRelativePosition = transformAbsPositionToElementRelativePosition;
9975
+ exports.transformAbsPositionToRelativePositionInsideElement = transformAbsPositionToRelativePositionInsideElement;