orcasvn-react-diagrams 0.1.35 → 0.1.36

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
@@ -1192,80 +1192,87 @@ var LINK_TARGET_LABEL_POSITION_FROM_TARGET_PORT = { x: 15, y: 15 };
1192
1192
  var LINK_LABEL_POSITION_FROM_LINK_MID_POINT = { x: 0, y: 40 };
1193
1193
  var PORT_LABEL_POSITION = { x: 15, y: 0 };
1194
1194
  var TEXT_FONT_SIZE = 12;
1195
- var TEXT_MOVING_OFFSET_THRESHOLD = 10;
1196
1195
  //PORT
1197
1196
  var PORT_PLACEHOLDER_DEFAULT_SIZE = 8;
1198
1197
  var PORT_PLACEHOLDER_DEFAULT_STROKE = 'green';
1199
1198
  var PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH = 20;
1200
- var PORT_MOVING_OFFSET_THRESHOLD = 15;
1201
1199
  var PORT_DEFAULT_SIZE = 20;
1202
1200
 
1203
1201
  var SelectionFrame = function (props) {
1204
- var _a;
1205
- var bbox = (_a = props.targetSVGElement) === null || _a === void 0 ? void 0 : _a.getBBox();
1206
- var _b = React.useState(props.width || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _b[0], setWidth = _b[1];
1207
- var _c = React.useState(props.height || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _c[0], setHeight = _c[1];
1208
- var x = 0;
1209
- var y = 0;
1210
- var framePadding = props.framePadding || 0;
1202
+ var _a, _b;
1203
+ var propTargetSVGElement = props.targetSVGElement, propWidth = props.width, propHeight = props.height, propFramePadding = props.framePadding,
1204
+ // movingOffsetThreshold: propMovingOffsetThreshold,
1205
+ propMovingRate = props.movingRate, propOnMove = props.onMove, propContainer = props.container, propResizability = props.resizability, propOnResize = props.onResize, PropDragDropHandlerElement = props.dragDropHandlerElement, propStrokeWidth = props.strokeWidth, propAnchor = props.anchor;
1206
+ var bbox = propTargetSVGElement === null || propTargetSVGElement === void 0 ? void 0 : propTargetSVGElement.getBBox();
1207
+ var _c = React.useState(propWidth || (bbox === null || bbox === void 0 ? void 0 : bbox.width) || MIN_ELEMENT_SIZE), width = _c[0], setWidth = _c[1];
1208
+ var _d = React.useState(propHeight || (bbox === null || bbox === void 0 ? void 0 : bbox.height) || MIN_ELEMENT_SIZE), height = _d[0], setHeight = _d[1];
1209
+ var _e = React.useState((_a = props.x) !== null && _a !== void 0 ? _a : 0), x = _e[0], setX = _e[1];
1210
+ var _f = React.useState((_b = props.y) !== null && _b !== void 0 ? _b : 0), y = _f[0], setY = _f[1];
1211
+ var framePadding = propFramePadding || 0;
1211
1212
  var r = 5;
1212
- var _d = React.useState(false), draggingRect = _d[0], setDraggingRect = _d[1];
1213
- var _e = React.useState(false), draggingCircle = _e[0], setDraggingCircle = _e[1];
1214
- var _f = React.useState(0), startX = _f[0], setStartX = _f[1];
1215
- var _g = React.useState(0), startY = _g[0], setStartY = _g[1];
1216
- var _h = React.useState(0), lastMoveTime = _h[0], setLastMoveTime = _h[1];
1213
+ var _g = React.useState(false), draggingRect = _g[0], setDraggingRect = _g[1];
1214
+ var _h = React.useState(false), draggingCircle = _h[0], setDraggingCircle = _h[1];
1215
+ var _j = React.useState(0), startX = _j[0], setStartX = _j[1];
1216
+ var _k = React.useState(0), startY = _k[0], setStartY = _k[1];
1217
+ var _l = React.useState(0), xFromMouse = _l[0], setXFromMouse = _l[1];
1218
+ var _m = React.useState(0), yFromMouse = _m[0], setYFromMouse = _m[1];
1219
+ var _o = React.useState(0), lastMoveTime = _o[0], setLastMoveTime = _o[1];
1220
+ var getMousePosition = function (event) {
1221
+ var elementBounding = propContainer.getBoundingClientRect();
1222
+ //Coordinates of mouse on paper.
1223
+ var mousePosition = {
1224
+ x: event.clientX - elementBounding.left,
1225
+ y: event.clientY - elementBounding.top
1226
+ };
1227
+ return mousePosition;
1228
+ };
1217
1229
  var addRectHandleMouseDown = function (event) {
1218
1230
  event.stopPropagation();
1219
1231
  if (!draggingCircle) {
1220
- //mouse down on rect
1221
1232
  setDraggingRect(true);
1222
1233
  setStartX(event.clientX);
1223
1234
  setStartY(event.clientY);
1235
+ var mousePosition = getMousePosition(event);
1236
+ var xFromMouse_1 = x - mousePosition.x;
1237
+ var yFromMouse_1 = y - mousePosition.y;
1238
+ setXFromMouse(xFromMouse_1);
1239
+ setYFromMouse(yFromMouse_1);
1224
1240
  }
1225
1241
  };
1226
1242
  var rectHandleMouseMove = React.useCallback(function (event) {
1227
1243
  var mouseEvent = event;
1228
1244
  if (draggingRect) {
1229
- var offsetX = mouseEvent.clientX - startX;
1230
- var offsetY = mouseEvent.clientY - startY;
1231
- if (props.movingOffsetThreshold && Math.abs(offsetX) > props.movingOffsetThreshold) {
1232
- offsetX = offsetX / Math.abs(offsetX) * props.movingOffsetThreshold;
1233
- }
1234
- if (props.movingOffsetThreshold && Math.abs(offsetY) > props.movingOffsetThreshold) {
1235
- offsetY = offsetY / Math.abs(offsetY) * props.movingOffsetThreshold;
1236
- }
1237
- if (Date.now() - lastMoveTime < (props.movingRate || 0)) {
1238
- return;
1239
- }
1240
- // console.info('Selection frame moved by: ', offsetX, offsetY);
1241
- if (props.onMove) {
1242
- props.onMove(offsetX, offsetY);
1245
+ //Coordinates of mouse on paper.
1246
+ var mousePosition = getMousePosition(mouseEvent);
1247
+ var newX = mousePosition.x + xFromMouse;
1248
+ var newY = mousePosition.y + yFromMouse;
1249
+ if (propOnMove) {
1250
+ console.log('newX', newX, 'newY', newY);
1251
+ setX(newX);
1252
+ setY(newY);
1253
+ propOnMove(newX, newY);
1243
1254
  setLastMoveTime(Date.now());
1244
1255
  setStartX(mouseEvent.clientX);
1245
1256
  setStartY(mouseEvent.clientY);
1246
1257
  }
1247
1258
  }
1248
- }, [draggingRect, props.onMove, props.movingRate, startX, startY, lastMoveTime]);
1259
+ }, [draggingRect, propOnMove, propMovingRate, startX, startY, lastMoveTime, xFromMouse, yFromMouse]);
1249
1260
  React.useEffect(function () {
1250
1261
  var addRectHandleMouseUp = function () {
1251
- //mouse up
1252
1262
  setDraggingRect(false);
1263
+ setXFromMouse(0);
1264
+ setYFromMouse(0);
1253
1265
  };
1254
- //select container if it is a string
1255
- //const container = typeof props.container === 'string' ? document.querySelector(props.container) : props.container;
1256
- var container = props.container;
1257
- //add event listeners
1258
- container === null || container === void 0 ? void 0 : container.addEventListener('mousemove', rectHandleMouseMove);
1259
- container === null || container === void 0 ? void 0 : container.addEventListener('mouseup', addRectHandleMouseUp);
1266
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mousemove', rectHandleMouseMove);
1267
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.addEventListener('mouseup', addRectHandleMouseUp);
1260
1268
  return function () {
1261
- container === null || container === void 0 ? void 0 : container.removeEventListener('mousemove', rectHandleMouseMove);
1262
- container === null || container === void 0 ? void 0 : container.removeEventListener('mouseup', addRectHandleMouseUp);
1269
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mousemove', rectHandleMouseMove);
1270
+ propContainer === null || propContainer === void 0 ? void 0 : propContainer.removeEventListener('mouseup', addRectHandleMouseUp);
1263
1271
  };
1264
- }, [props.container, rectHandleMouseMove]);
1272
+ }, [propContainer, rectHandleMouseMove]);
1265
1273
  var circleHandleMouseDown = function (event) {
1266
1274
  event.stopPropagation();
1267
1275
  if (!draggingRect) {
1268
- // mouse down on resizing circle
1269
1276
  setStartX(event.clientX);
1270
1277
  setStartY(event.clientY);
1271
1278
  setDraggingCircle(true);
@@ -1277,7 +1284,7 @@ var SelectionFrame = function (props) {
1277
1284
  if (draggingCircle) {
1278
1285
  var offsetX = mouseEvent.clientX - startX;
1279
1286
  var offsetY = mouseEvent.clientY - startY;
1280
- if (Date.now() - lastMoveTime < (props.movingRate || 0)) {
1287
+ if (Date.now() - lastMoveTime < (propMovingRate || 0)) {
1281
1288
  return;
1282
1289
  }
1283
1290
  setStartX(mouseEvent.clientX);
@@ -1285,7 +1292,7 @@ var SelectionFrame = function (props) {
1285
1292
  setLastMoveTime(Date.now());
1286
1293
  var newWidth = width;
1287
1294
  var newHeight = height;
1288
- if (props.resizability.keepRatio) {
1295
+ if (propResizability.keepRatio) {
1289
1296
  var resizingRatio = Math.abs(offsetX) > Math.abs(offsetY) ? (Math.abs(offsetX) / width) : (Math.abs(offsetY) / height);
1290
1297
  var increasing = Math.abs(offsetX) > Math.abs(offsetY) ? offsetX > 0 : offsetY > 0;
1291
1298
  offsetX = increasing ? resizingRatio * width : -resizingRatio * width;
@@ -1301,36 +1308,33 @@ var SelectionFrame = function (props) {
1301
1308
  }
1302
1309
  setWidth(newWidth);
1303
1310
  setHeight(newHeight);
1304
- if (props.onResize) {
1305
- props.onResize(newWidth, newHeight);
1311
+ if (propOnResize) {
1312
+ propOnResize(newWidth, newHeight);
1306
1313
  }
1307
- //}
1308
1314
  }
1309
1315
  };
1310
1316
  var circleHandleMouseUp = function () {
1311
1317
  setDraggingCircle(false);
1312
1318
  };
1313
- //select container if it is a string
1314
- //const container = typeof props.container === 'string' ? document.querySelector(props.container) : props.container;
1315
- var container = props.container;
1319
+ var container = propContainer;
1316
1320
  container.addEventListener('mousemove', circleHandleMouseMove);
1317
1321
  container.addEventListener('mouseup', circleHandleMouseUp);
1318
1322
  return function () {
1319
1323
  container.removeEventListener('mousemove', circleHandleMouseMove);
1320
1324
  container.removeEventListener('mouseup', circleHandleMouseUp);
1321
1325
  };
1322
- }, [draggingCircle, startX, startY, x, y]);
1326
+ }, [draggingCircle, width, height, lastMoveTime, propContainer, propMovingRate, propOnResize, propResizability, startX, startY]);
1323
1327
  var rectangleSize = Math.max(width, height);
1324
1328
  var leftX = framePadding;
1325
1329
  var topY = framePadding;
1326
- if (props.anchor === exports.PositioningAnchor.Center) {
1330
+ if (propAnchor === exports.PositioningAnchor.Center) {
1327
1331
  leftX -= rectangleSize / 2;
1328
1332
  topY -= rectangleSize / 2;
1329
1333
  }
1330
1334
  return (React.createElement(React.Fragment, null,
1331
- props.dragDropHandlerElement && React.createElement(props.dragDropHandlerElement, { dragging: draggingRect, onMouseDown: addRectHandleMouseDown }),
1332
- React.createElement("rect", { vectorEffect: "non-scaling-stroke", x: leftX, y: topY, width: width, height: height, fill: 'none', stroke: 'blue', strokeWidth: props.strokeWidth || 5, cursor: draggingRect ? 'grabbing' : 'grab', onMouseDown: addRectHandleMouseDown }),
1333
- props.resizability.enabled ?
1335
+ PropDragDropHandlerElement && React.createElement(PropDragDropHandlerElement, { dragging: draggingRect, onMouseDown: addRectHandleMouseDown }),
1336
+ React.createElement("rect", { vectorEffect: "non-scaling-stroke", x: leftX, y: topY, width: width, height: height, fill: 'none', stroke: 'blue', strokeWidth: propStrokeWidth || 5, cursor: draggingRect ? 'grabbing' : 'grab', onMouseDown: addRectHandleMouseDown }),
1337
+ propResizability.enabled ?
1334
1338
  (React.createElement("circle", { cursor: 'se-resize', cx: leftX + width, cy: topY + height, r: r, fill: 'blue', stroke: 'blue', onMouseDown: circleHandleMouseDown })) : null));
1335
1339
  };
1336
1340
 
@@ -1600,9 +1604,17 @@ var paperEventEmitterContext = React.createContext({
1600
1604
  });
1601
1605
 
1602
1606
  var Text = React.forwardRef(function (_a, ref) {
1603
- var id = _a.id, content = _a.content, x = _a.x, y = _a.y, width = _a.width, height = _a.height, editable = _a.editable, _b = _a.align, align = _b === void 0 ? exports.TextAlign.left : _b, fontSizeProp = _a.fontSize, border = _a.border, container = _a.container, onSelected = _a.onSelected, onMoved = _a.onMoved, onResized = _a.onResized, onContentChanged = _a.onContentChanged;
1607
+ var id = _a.id, content = _a.content, x = _a.x, y = _a.y, width = _a.width, height = _a.height, editable = _a.editable, _b = _a.align, align = _b === void 0 ? exports.TextAlign.left : _b, fontSizeProp = _a.fontSize, border = _a.border, container = _a.container, parentAbsolutePosition = _a.parentAbsolutePosition, onSelected = _a.onSelected, onMoved = _a.onMoved, onResized = _a.onResized, onContentChanged = _a.onContentChanged;
1608
+ console.log(content, x, y, parentAbsolutePosition);
1604
1609
  var _c = React.useState(false), isSelected = _c[0], setIsSelected = _c[1];
1605
1610
  var _d = React.useState(false), isEditing = _d[0], setIsEditing = _d[1];
1611
+ var absolutePosition = React.useMemo(function () {
1612
+ var _a, _b;
1613
+ return {
1614
+ x: ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0) + x,
1615
+ y: ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0) + y,
1616
+ };
1617
+ }, [x, y, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y]);
1606
1618
  var svgRef = React.useRef();
1607
1619
  var _e = React.useContext(paperEventEmitterContext), onPaperClicked = _e.onPaperClicked, emitTextSelected = _e.emitTextSelected, onPortSelected = _e.onPortSelected, onElementSelected = _e.onElementSelected, onTextSelected = _e.onTextSelected;
1608
1620
  React.useEffect(function () {
@@ -1638,7 +1650,7 @@ var Text = React.forwardRef(function (_a, ref) {
1638
1650
  //Handle click on svg element
1639
1651
  var handleClick = function (ev) {
1640
1652
  ev.stopPropagation();
1641
- var position = (x === undefined || y === undefined) ? undefined : {
1653
+ var position = {
1642
1654
  x: x,
1643
1655
  y: y,
1644
1656
  };
@@ -1662,6 +1674,8 @@ var Text = React.forwardRef(function (_a, ref) {
1662
1674
  onContentChanged === null || onContentChanged === void 0 ? void 0 : onContentChanged(ev, ev.target.value);
1663
1675
  };
1664
1676
  useSelectionFrame({
1677
+ x: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.x,
1678
+ y: absolutePosition === null || absolutePosition === void 0 ? void 0 : absolutePosition.y,
1665
1679
  container: container,
1666
1680
  targetSVGElement: (isSelected && svgRef.current) ? svgRef.current : undefined,
1667
1681
  resizability: {
@@ -1671,7 +1685,6 @@ var Text = React.forwardRef(function (_a, ref) {
1671
1685
  onMove: onMoved,
1672
1686
  onResize: onResized,
1673
1687
  strokeWidth: 3,
1674
- movingOffsetThreshold: TEXT_MOVING_OFFSET_THRESHOLD,
1675
1688
  });
1676
1689
  var textAlign = React.useMemo(function () {
1677
1690
  switch (align) {
@@ -1731,217 +1744,6 @@ var Text = React.forwardRef(function (_a, ref) {
1731
1744
  });
1732
1745
  var Text$1 = React.memo(Text);
1733
1746
 
1734
- var Port1 = React.forwardRef(function (props, ref) {
1735
- var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle,
1736
- // onManuallyTriggerRenderHandler,
1737
- renderShape = props.renderShape;
1738
- var _a = React.useState(false); _a[0]; _a[1];
1739
- var textRef = React.useRef(null);
1740
- // useEffect(() => {
1741
- // const off = onManuallyTriggerRenderHandler?.(() => {
1742
- // setUpdated(prev => !prev);
1743
- // });
1744
- // return () => {
1745
- // off?.();
1746
- // }
1747
- // }, [])
1748
- var rotationAngle = React.useMemo(function () {
1749
- if (!calculateRotationAngle)
1750
- return 0;
1751
- return calculateRotationAngle(x, y);
1752
- }, [calculateRotationAngle, x, y]);
1753
- React.useEffect(function () {
1754
- console.info('Testing - rendering Port ' + id);
1755
- });
1756
- var renderLabel = function (label) {
1757
- var content = label.content, size = label.size;
1758
- var position = label.position || PORT_LABEL_POSITION;
1759
- return React.createElement(Text$1, { id: label.id, ref: textRef, x: x + position.x, y: y + position.y, width: size.width, height: size.height, editable: label.editable, content: content, fontSize: label.fontSize, border: label.border, container: container, onMoved: function (x, y) { return onPortLabelMoved === null || onPortLabelMoved === void 0 ? void 0 : onPortLabelMoved(x, y, id); }, onResized: function (width, height) { return onPortLabelResized === null || onPortLabelResized === void 0 ? void 0 : onPortLabelResized(width, height, id); }, onContentChanged: function (ev, newValue) { return onPortLabelContentChanged === null || onPortLabelContentChanged === void 0 ? void 0 : onPortLabelContentChanged(ev, newValue, id); } });
1760
- };
1761
- var renderedShape = React.useMemo(function () {
1762
- if (renderShape) {
1763
- var RenderShape = renderShape;
1764
- return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle })));
1765
- }
1766
- else {
1767
- return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" });
1768
- }
1769
- }, [props]);
1770
- return (React.createElement(React.Fragment, null,
1771
- renderedShape,
1772
- label && renderLabel(label)));
1773
- });
1774
- var Port = React.memo(Port1);
1775
-
1776
- // Render the svg <path> element
1777
- function getCurvePathData(points, smoothing, closed) {
1778
- if (smoothing === void 0) { smoothing = 0.2; }
1779
- // Properties of a line
1780
- var line = function (pointA, pointB) {
1781
- var lengthX = pointB.x - pointA.x;
1782
- var lengthY = pointB.y - pointA.y;
1783
- return {
1784
- length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
1785
- angle: Math.atan2(lengthY, lengthX)
1786
- };
1787
- };
1788
- // Position of a control point
1789
- var controlPoint = function (current, previous, next, reverse) {
1790
- var p = previous || current;
1791
- var n = next || current;
1792
- var o = line(p, n);
1793
- var angle = o.angle + (reverse ? Math.PI : 0);
1794
- var length = o.length * smoothing;
1795
- var x = current.x + Math.cos(angle) * length;
1796
- var y = current.y + Math.sin(angle) * length;
1797
- return { x: x, y: y };
1798
- };
1799
- var pathData = [];
1800
- pathData.push({ type: "M", values: [points[0].x, points[0].y] });
1801
- for (var i = 1; i < points.length; i++) {
1802
- var point = points[i];
1803
- var cp1 = controlPoint(points[i - 1], points[i - 2], point);
1804
- var cp2 = controlPoint(point, points[i - 1], points[i + 1], true);
1805
- var command = {
1806
- type: "C",
1807
- values: [cp1.x, cp1.y, cp2.x, cp2.y, point.x, point.y]
1808
- };
1809
- pathData.push(command);
1810
- }
1811
- return pathData;
1812
- }
1813
- // convert pathdata to d attribute string
1814
- function pathDataToD(pathData, decimals) {
1815
- if (decimals === void 0) { decimals = 3; }
1816
- var d = pathData
1817
- .map(function (com) {
1818
- return "".concat(com.type).concat(com.values.map(function (value) { return +value.toFixed(decimals); }).join(" "));
1819
- })
1820
- .join(" ");
1821
- return d;
1822
- }
1823
- function createSmoothPathString(points, smoothing, close) {
1824
- var pathData = getCurvePathData(points, smoothing);
1825
- var pathString = pathDataToD(pathData);
1826
- return pathString;
1827
- }
1828
- // a helper function to measure the distance between 2 points
1829
- function dist(p1, p2) {
1830
- var dx = p2.x - p1.x;
1831
- var dy = p2.y - p1.y;
1832
- return Math.sqrt(dx * dx + dy * dy);
1833
- }
1834
- //find distance from starting point of path to a point
1835
- function getLengthForPoint(p, thePath, precision) {
1836
- if (precision === void 0) { precision = 50; }
1837
- var pathLength = thePath.getTotalLength();
1838
- var theRecord = pathLength; //length of path
1839
- var division = pathLength / precision;
1840
- var theSegment;
1841
- for (var i = 0; i < precision; i++) {
1842
- // get a point on the path for thia distance
1843
- var _p = thePath.getPointAtLength(i * division);
1844
- // get the distance between the new point _p and the point p
1845
- var theDistance = dist(_p, p);
1846
- if (theDistance < theRecord) {
1847
- // if the distance is smaller than the record set the new record
1848
- theRecord = theDistance;
1849
- theSegment = i;
1850
- }
1851
- }
1852
- return (theSegment * division);
1853
- }
1854
- //Add points to the list of points in the correct position
1855
- function addPointToList(point, listPoints, path) {
1856
- var getAddIndex = function (startIndex, endIndex) {
1857
- //Add in the middle if there are only 2 points
1858
- if ((endIndex - startIndex) === 1) {
1859
- return startIndex + 1;
1860
- }
1861
- var middleIndex = Math.ceil((startIndex + endIndex) / 2);
1862
- var lengthOfMiddlePoint = getLengthForPoint(listPoints[middleIndex], path); //distance from start point to mid point
1863
- var lengthOfAddedPoint = getLengthForPoint(point, path); //distance from adding point to mid point
1864
- //compare if lengthOfMiddlePoint is less than lengthOfAddedPoint,
1865
- //then new point can be added in the range of mid point to end point,
1866
- //otherwise it can be added in the range of start point to middle point.
1867
- if (lengthOfAddedPoint < lengthOfMiddlePoint) {
1868
- return getAddIndex(startIndex, middleIndex);
1869
- }
1870
- else {
1871
- return getAddIndex(middleIndex, endIndex);
1872
- }
1873
- };
1874
- var addedIndex = getAddIndex(0, listPoints.length - 1);
1875
- listPoints.splice(addedIndex, 0, point);
1876
- return __spreadArray([], listPoints, true);
1877
- }
1878
-
1879
- // const topLeftOffsetOfSquareHoldingRect = (x: number, y: number, rectWidth: number, rectHeight: number, rotation?: number): IPosition => {
1880
- // rotation = rotation || 0;
1881
- // const rotationInRadians = rotation * Math.PI / 180;
1882
- // //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
1883
- // //calculate a1 equal sin of rotation * height
1884
- // const a1 = Math.abs(Math.sin(rotationInRadians) * rectHeight);
1885
- // //calculate a2 equal cos of rotation * width
1886
- // const a2 = Math.abs(Math.cos(rotationInRadians) * rectWidth);
1887
- // const a = a1 + a2;
1888
- // console.info(`a1: ${a1}, a2: ${a2}, a: ${a}`);
1889
- // //calculate b1 equal cos of rotation * height
1890
- // const b1 = Math.abs(Math.cos(rotationInRadians) * rectHeight);
1891
- // //calculate b2 equal sin of rotation * width
1892
- // const b2 = Math.abs(Math.sin(rotationInRadians) * rectWidth);
1893
- // const b = b1 + b2;
1894
- // console.info(`b1: ${b1}, b2: ${b2}, b: ${b}`);
1895
- // //const squareEdge = Math.max(rectWidth, rectHeight);
1896
- // return {x, y};
1897
- // return { x: x - (b - rectWidth) / 2, y: y - (a - rectHeight) / 2 };
1898
- // }
1899
- function degreeToRadian(degree) {
1900
- return degree * (Math.PI / 180);
1901
- }
1902
- //rotate the four vertices of the rectangle
1903
- function getRotatedRectangleCoordinates(actualPoints, centerX, centerY, angle) {
1904
- var coordinatesAfterRotation = [];
1905
- for (var i = 0; i < 4; i++) {
1906
- var point = actualPoints[i];
1907
- var tempX = point.x - centerX;
1908
- var tempY = point.y - centerY;
1909
- var rotatedX = tempX * Math.cos(degreeToRadian(angle)) - tempY * Math.sin(degreeToRadian(angle));
1910
- var rotatedY = tempX * Math.sin(degreeToRadian(angle)) + tempY * Math.cos(degreeToRadian(angle));
1911
- point.x = rotatedX + centerX;
1912
- point.y = rotatedY + centerY;
1913
- coordinatesAfterRotation.push({ x: point.x, y: point.y });
1914
- }
1915
- return coordinatesAfterRotation;
1916
- }
1917
- //Calculate the angle between 2 points relative to the OX axis
1918
- function calculateAngleWithOx(pStart, pEnd) {
1919
- var deltaX = pEnd.x - pStart.x;
1920
- var deltaY = pEnd.y - pStart.y;
1921
- // Calculate the angle in radians
1922
- var angleInRadians = Math.atan2(deltaY, deltaX);
1923
- // Convert to degrees (optional)
1924
- var angleInDegrees = angleInRadians * (180 / Math.PI);
1925
- // Ensure the angle is positive (optional, depending on use case)
1926
- if (angleInDegrees < 0) {
1927
- angleInDegrees += 360;
1928
- }
1929
- return angleInDegrees;
1930
- }
1931
-
1932
- //Defined remove icon for element link, shown when element link is selected.
1933
- function CloseIcon(_a) {
1934
- var onClick = _a.onClick;
1935
- return (React.createElement("svg", { width: 20, height: 20, viewBox: "0 0 24.00 24.00", xmlns: "http://www.w3.org/2000/svg", fill: "#ff0000", transform: "rotate(0)", onMouseDown: function (ev) { ev.stopPropagation(); }, onClick: onClick, cursor: 'pointer' },
1936
- React.createElement("g", { id: "SVGRepo_bgCarrier", strokeWidth: "0", transform: "translate(3.84,3.84), scale(0.68)" },
1937
- React.createElement("rect", { x: "0", y: "0", width: "24.00", height: "24.00", rx: "12", fill: "#ffffff", strokeWidth: "0" })),
1938
- React.createElement("g", { id: "SVGRepo_tracerCarrier", strokeLinecap: "round", strokeLinejoin: "round", stroke: "#CCCCCC", "stroke-width": "0.048" }),
1939
- React.createElement("g", { id: "SVGRepo_iconCarrier" },
1940
- React.createElement("g", null,
1941
- React.createElement("path", { fill: "none", d: "M0 0h24v24H0z" }),
1942
- React.createElement("path", { d: "M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.414L9.172 7.757 7.757 9.172 10.586 12l-2.829 2.828 1.415 1.415L12 13.414l2.828 2.829 1.415-1.415L13.414 12l2.829-2.828-1.415-1.415L12 10.586z" })))));
1943
- }
1944
-
1945
1747
  /**
1946
1748
  * Created by Alex Bol on 2/18/2017.
1947
1749
  */
@@ -7772,8 +7574,233 @@ var getAbsolutePosition = function (element) {
7772
7574
  x: x,
7773
7575
  y: y,
7774
7576
  };
7577
+ };
7578
+ var transformAbsPositionToElementRelativePosition = function (position, element) {
7579
+ var parentElement = element.parentElement;
7580
+ if (!parentElement) {
7581
+ return position;
7582
+ }
7583
+ var absoluteParentElement = getAbsolutePosition(parentElement);
7584
+ return {
7585
+ x: position.x - absoluteParentElement.x,
7586
+ y: position.y - absoluteParentElement.y,
7587
+ };
7588
+ };
7589
+ var transformAbsPositionToRelativePositionInsideElement = function (absolutePosition, parentAbsolutePosition) {
7590
+ var _a, _b;
7591
+ var position = {
7592
+ x: absolutePosition.x - ((_a = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x) !== null && _a !== void 0 ? _a : 0),
7593
+ y: absolutePosition.y - ((_b = parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y) !== null && _b !== void 0 ? _b : 0),
7594
+ };
7595
+ return position;
7775
7596
  };
7776
7597
 
7598
+ var Port1 = React.forwardRef(function (props, ref) {
7599
+ var id = props.id, x = props.x, y = props.y, width = props.width, height = props.height, container = props.container, label = props.label, parentAbsolutePosition = props.parentAbsolutePosition, onPortLabelMoved = props.onPortLabelMoved, onPortLabelResized = props.onPortLabelResized, onPortLabelContentChanged = props.onPortLabelContentChanged, onSelected = props.onSelected, onMouseDown = props.onMouseDown, onMouseUp = props.onMouseUp, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, onMouseMove = props.onMouseMove, calculateRotationAngle = props.calculateRotationAngle,
7600
+ // onManuallyTriggerRenderHandler,
7601
+ renderShape = props.renderShape;
7602
+ var textRef = React.useRef(null);
7603
+ var rotationAngle = React.useMemo(function () {
7604
+ if (!calculateRotationAngle)
7605
+ return 0;
7606
+ return calculateRotationAngle(x, y);
7607
+ }, [calculateRotationAngle, x, y]);
7608
+ var renderLabel = function (label) {
7609
+ var content = label.content, size = label.size;
7610
+ var position = label.position || PORT_LABEL_POSITION;
7611
+ return React.createElement(Text$1, { id: label.id, ref: textRef, x: x + position.x, y: y + position.y, parentAbsolutePosition: parentAbsolutePosition, width: size.width, height: size.height, editable: label.editable, content: content, fontSize: label.fontSize, border: label.border, container: container, onMoved: function (xOnPaper, yOnPaper) {
7612
+ if (onPortLabelMoved) {
7613
+ var relativePosInSideEle = transformAbsPositionToRelativePositionInsideElement({ x: xOnPaper, y: yOnPaper }, parentAbsolutePosition);
7614
+ var newXPort = relativePosInSideEle.x - x;
7615
+ var newYPort = relativePosInSideEle.y - y;
7616
+ onPortLabelMoved(newXPort, newYPort, id);
7617
+ }
7618
+ }, onResized: function (width, height) { return onPortLabelResized === null || onPortLabelResized === void 0 ? void 0 : onPortLabelResized(width, height, id); }, onContentChanged: function (ev, newValue) { return onPortLabelContentChanged === null || onPortLabelContentChanged === void 0 ? void 0 : onPortLabelContentChanged(ev, newValue, id); } });
7619
+ };
7620
+ var renderedShape = React.useMemo(function () {
7621
+ if (renderShape) {
7622
+ var RenderShape = renderShape;
7623
+ return (React.createElement(RenderShape, __assign({ ref: ref }, props, { rotation: rotationAngle })));
7624
+ }
7625
+ else {
7626
+ return React.createElement(Circle, { onMouseDown: function (e) { return onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(id, e); }, onMouseUp: function (e) { return onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(id, e); }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseMove: function (e) { return onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(id, e); }, onClick: function (e) { return onSelected === null || onSelected === void 0 ? void 0 : onSelected(id, e); }, ref: ref, x: x, y: y, positioningAnchor: exports.PositioningAnchor.Center, height: height, width: width, stroke: "black", fill: "black" });
7627
+ }
7628
+ }, [props]);
7629
+ return (React.createElement(React.Fragment, null,
7630
+ renderedShape,
7631
+ label && renderLabel(label)));
7632
+ });
7633
+ var Port = React.memo(Port1);
7634
+
7635
+ // Render the svg <path> element
7636
+ function getCurvePathData(points, smoothing, closed) {
7637
+ if (smoothing === void 0) { smoothing = 0.2; }
7638
+ // Properties of a line
7639
+ var line = function (pointA, pointB) {
7640
+ var lengthX = pointB.x - pointA.x;
7641
+ var lengthY = pointB.y - pointA.y;
7642
+ return {
7643
+ length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
7644
+ angle: Math.atan2(lengthY, lengthX)
7645
+ };
7646
+ };
7647
+ // Position of a control point
7648
+ var controlPoint = function (current, previous, next, reverse) {
7649
+ var p = previous || current;
7650
+ var n = next || current;
7651
+ var o = line(p, n);
7652
+ var angle = o.angle + (reverse ? Math.PI : 0);
7653
+ var length = o.length * smoothing;
7654
+ var x = current.x + Math.cos(angle) * length;
7655
+ var y = current.y + Math.sin(angle) * length;
7656
+ return { x: x, y: y };
7657
+ };
7658
+ var pathData = [];
7659
+ pathData.push({ type: "M", values: [points[0].x, points[0].y] });
7660
+ for (var i = 1; i < points.length; i++) {
7661
+ var point = points[i];
7662
+ var cp1 = controlPoint(points[i - 1], points[i - 2], point);
7663
+ var cp2 = controlPoint(point, points[i - 1], points[i + 1], true);
7664
+ var command = {
7665
+ type: "C",
7666
+ values: [cp1.x, cp1.y, cp2.x, cp2.y, point.x, point.y]
7667
+ };
7668
+ pathData.push(command);
7669
+ }
7670
+ return pathData;
7671
+ }
7672
+ // convert pathdata to d attribute string
7673
+ function pathDataToD(pathData, decimals) {
7674
+ if (decimals === void 0) { decimals = 3; }
7675
+ var d = pathData
7676
+ .map(function (com) {
7677
+ return "".concat(com.type).concat(com.values.map(function (value) { return +value.toFixed(decimals); }).join(" "));
7678
+ })
7679
+ .join(" ");
7680
+ return d;
7681
+ }
7682
+ function createSmoothPathString(points, smoothing, close) {
7683
+ var pathData = getCurvePathData(points, smoothing);
7684
+ var pathString = pathDataToD(pathData);
7685
+ return pathString;
7686
+ }
7687
+ // a helper function to measure the distance between 2 points
7688
+ function dist(p1, p2) {
7689
+ var dx = p2.x - p1.x;
7690
+ var dy = p2.y - p1.y;
7691
+ return Math.sqrt(dx * dx + dy * dy);
7692
+ }
7693
+ //find distance from starting point of path to a point
7694
+ function getLengthForPoint(p, thePath, precision) {
7695
+ if (precision === void 0) { precision = 50; }
7696
+ var pathLength = thePath.getTotalLength();
7697
+ var theRecord = pathLength; //length of path
7698
+ var division = pathLength / precision;
7699
+ var theSegment;
7700
+ for (var i = 0; i < precision; i++) {
7701
+ // get a point on the path for thia distance
7702
+ var _p = thePath.getPointAtLength(i * division);
7703
+ // get the distance between the new point _p and the point p
7704
+ var theDistance = dist(_p, p);
7705
+ if (theDistance < theRecord) {
7706
+ // if the distance is smaller than the record set the new record
7707
+ theRecord = theDistance;
7708
+ theSegment = i;
7709
+ }
7710
+ }
7711
+ return (theSegment * division);
7712
+ }
7713
+ //Add points to the list of points in the correct position
7714
+ function addPointToList(point, listPoints, path) {
7715
+ var getAddIndex = function (startIndex, endIndex) {
7716
+ //Add in the middle if there are only 2 points
7717
+ if ((endIndex - startIndex) === 1) {
7718
+ return startIndex + 1;
7719
+ }
7720
+ var middleIndex = Math.ceil((startIndex + endIndex) / 2);
7721
+ var lengthOfMiddlePoint = getLengthForPoint(listPoints[middleIndex], path); //distance from start point to mid point
7722
+ var lengthOfAddedPoint = getLengthForPoint(point, path); //distance from adding point to mid point
7723
+ //compare if lengthOfMiddlePoint is less than lengthOfAddedPoint,
7724
+ //then new point can be added in the range of mid point to end point,
7725
+ //otherwise it can be added in the range of start point to middle point.
7726
+ if (lengthOfAddedPoint < lengthOfMiddlePoint) {
7727
+ return getAddIndex(startIndex, middleIndex);
7728
+ }
7729
+ else {
7730
+ return getAddIndex(middleIndex, endIndex);
7731
+ }
7732
+ };
7733
+ var addedIndex = getAddIndex(0, listPoints.length - 1);
7734
+ listPoints.splice(addedIndex, 0, point);
7735
+ return __spreadArray([], listPoints, true);
7736
+ }
7737
+
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
+ //Defined remove icon for element link, shown when element link is selected.
7792
+ function CloseIcon(_a) {
7793
+ var onClick = _a.onClick;
7794
+ return (React.createElement("svg", { width: 20, height: 20, viewBox: "0 0 24.00 24.00", xmlns: "http://www.w3.org/2000/svg", fill: "#ff0000", transform: "rotate(0)", onMouseDown: function (ev) { ev.stopPropagation(); }, onClick: onClick, cursor: 'pointer' },
7795
+ React.createElement("g", { id: "SVGRepo_bgCarrier", strokeWidth: "0", transform: "translate(3.84,3.84), scale(0.68)" },
7796
+ React.createElement("rect", { x: "0", y: "0", width: "24.00", height: "24.00", rx: "12", fill: "#ffffff", strokeWidth: "0" })),
7797
+ React.createElement("g", { id: "SVGRepo_tracerCarrier", strokeLinecap: "round", strokeLinejoin: "round", stroke: "#CCCCCC", "stroke-width": "0.048" }),
7798
+ React.createElement("g", { id: "SVGRepo_iconCarrier" },
7799
+ React.createElement("g", null,
7800
+ React.createElement("path", { fill: "none", d: "M0 0h24v24H0z" }),
7801
+ React.createElement("path", { d: "M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.414L9.172 7.757 7.757 9.172 10.586 12l-2.829 2.828 1.415 1.415L12 13.414l2.828 2.829 1.415-1.415L13.414 12l2.829-2.828-1.415-1.415L12 10.586z" })))));
7802
+ }
7803
+
7777
7804
  var makerStart = React.createElement("circle", { cx: 10, cy: 10, r: 10, fill: "blue" });
7778
7805
  var makerEnd = React.createElement("path", { d: "M0 0 L 20 10 L0 20 Z", fill: "blue" }); //<path d="M0 0 L 10 5 L0 10 Z"></path>
7779
7806
  var IElementLink = function (_a) {
@@ -7792,6 +7819,11 @@ var IElementLink = function (_a) {
7792
7819
  var labelRef = React.useRef(null);
7793
7820
  var sourceLabelRef = React.useRef(null);
7794
7821
  var targetLabelRef = React.useRef(null);
7822
+ var angleMarkerStart = '0';
7823
+ var angleMarkerEnd = '0';
7824
+ var markerStartPosition;
7825
+ var markerEndPosition;
7826
+ var centerPathPosition = undefined;
7795
7827
  React.useEffect(function () {
7796
7828
  var paperClickListener = onPaperClicked(function () {
7797
7829
  setSelectedLabelRef({
@@ -7908,16 +7940,22 @@ var IElementLink = function (_a) {
7908
7940
  setDraggingPointIndex(_draggingPointIndex);
7909
7941
  setPoints(pointsWithoutStartEndPoint);
7910
7942
  };
7911
- var handleLabelMoved = function (offsetX, offsetY) {
7943
+ var handleLabelMoved = function (newX, newY) {
7944
+ if (!onLabelMoved)
7945
+ return;
7946
+ var newPosition;
7912
7947
  switch (selectedLabelRef.current) {
7913
7948
  case labelRef.current:
7914
- onLabelMoved === null || onLabelMoved === void 0 ? void 0 : onLabelMoved(offsetX, offsetY, 'middle');
7949
+ newPosition = transformAbsPositionToRelativePositionInsideElement({ x: newX, y: newY }, centerPathPosition);
7950
+ onLabelMoved(newPosition.x, newPosition.y, 'middle');
7915
7951
  break;
7916
7952
  case sourceLabelRef.current:
7917
- onLabelMoved === null || onLabelMoved === void 0 ? void 0 : onLabelMoved(offsetX, offsetY, 'source');
7953
+ newPosition = transformAbsPositionToRelativePositionInsideElement({ x: newX, y: newY }, sourcePosition);
7954
+ onLabelMoved(newPosition.x, newPosition.y, 'source');
7918
7955
  break;
7919
7956
  case targetLabelRef.current:
7920
- onLabelMoved === null || onLabelMoved === void 0 ? void 0 : onLabelMoved(offsetX, offsetY, 'target');
7957
+ newPosition = transformAbsPositionToRelativePositionInsideElement({ x: newX, y: newY }, targetPosition);
7958
+ onLabelMoved(newPosition.x, newPosition.y, 'target');
7921
7959
  break;
7922
7960
  }
7923
7961
  };
@@ -7952,7 +7990,6 @@ var IElementLink = function (_a) {
7952
7990
  onSelected === null || onSelected === void 0 ? void 0 : onSelected();
7953
7991
  };
7954
7992
  var renderLabel = function (label, labelType, relativePositionTo) {
7955
- if (relativePositionTo === void 0) { relativePositionTo = { x: 0, y: 0 }; }
7956
7993
  var content = label.content, size = label.size;
7957
7994
  var relativePosition = label.position;
7958
7995
  var curLabelRef;
@@ -7979,16 +8016,15 @@ var IElementLink = function (_a) {
7979
8016
  throw new Error('This type of label does not exist.');
7980
8017
  }
7981
8018
  var position = {
7982
- x: relativePosition.x + relativePositionTo.x,
7983
- y: relativePosition.y + relativePositionTo.y,
8019
+ x: relativePosition.x,
8020
+ y: relativePosition.y,
7984
8021
  };
8022
+ if (relativePositionTo) {
8023
+ position.x += relativePositionTo.x;
8024
+ position.y += relativePositionTo.y;
8025
+ }
7985
8026
  return (React.createElement(Text$1, { id: label.id, x: position.x, y: position.y, width: size.width, height: size.height, editable: label.editable, content: content, fontSize: label.fontSize, border: label.border, ref: curLabelRef, container: container, onSelected: function () { return setSelectedLabelRef(curLabelRef); }, onMoved: handleLabelMoved, onResized: handleLabelResized, onContentChanged: handleLabelContentChanged }));
7986
8027
  };
7987
- var angleMarkerStart = '0';
7988
- var angleMarkerEnd = '0';
7989
- var markerStartPosition;
7990
- var markerEndPosition;
7991
- var centerPathPosition;
7992
8028
  if ((_b = pathRef.current) === null || _b === void 0 ? void 0 : _b.getAttribute('d')) {
7993
8029
  if (markerStart) {
7994
8030
  markerStartPosition = pathRef.current.getPointAtLength(markerDistanceFromPort);
@@ -8093,7 +8129,7 @@ var getElementRotationInfo = function (element) {
8093
8129
 
8094
8130
  var Element = function (props) {
8095
8131
  var _a, _b;
8096
- 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; 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;
8132
+ 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;
8097
8133
  var _c = React.useState(), selectedPort = _c[0], setSelectedPort = _c[1];
8098
8134
  var _d = React.useState(), hoveredPort = _d[0], setHoveredPort = _d[1];
8099
8135
  var _e = React.useState([]), ports = _e[0], setPorts = _e[1];
@@ -8103,6 +8139,18 @@ var Element = function (props) {
8103
8139
  var elementRef = React.useRef(null);
8104
8140
  var elementLinkStarted = React.useRef();
8105
8141
  var portsRef = React.useRef(ports);
8142
+ var getElementAbsPosition = React.useCallback(function () {
8143
+ var position = {
8144
+ x: x,
8145
+ y: y,
8146
+ };
8147
+ if (parentAbsolutePosition) {
8148
+ position.x += parentAbsolutePosition.x;
8149
+ position.y += parentAbsolutePosition.y;
8150
+ }
8151
+ return position;
8152
+ }, [x, y, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.x, parentAbsolutePosition === null || parentAbsolutePosition === void 0 ? void 0 : parentAbsolutePosition.y]);
8153
+ var elementAbsPosition = React.useMemo(function () { return getElementAbsPosition(); }, [getElementAbsPosition]);
8106
8154
  //Listen to manually trigger render event
8107
8155
  React.useEffect(function () {
8108
8156
  var _a;
@@ -8119,13 +8167,8 @@ var Element = function (props) {
8119
8167
  React.useEffect(function () {
8120
8168
  portsRef.current = ports;
8121
8169
  }, [ports]);
8122
- React.useEffect(function () {
8123
- var _a;
8124
- console.info('Rendering Element ' + ((_a = texts === null || texts === void 0 ? void 0 : texts[0]) === null || _a === void 0 ? void 0 : _a.content) || id, props.ports);
8125
- });
8126
8170
  //Listen a new port is created, after add new port to ports state
8127
8171
  React.useEffect(function () {
8128
- console.info('Ports changed', props.ports);
8129
8172
  setPorts(function (prev) {
8130
8173
  var _a, _b;
8131
8174
  return (_b = (_a = props.ports) === null || _a === void 0 ? void 0 : _a.map(function (p, index) {
@@ -8323,11 +8366,14 @@ var Element = function (props) {
8323
8366
  }
8324
8367
  return newPosition || tempNewPosition;
8325
8368
  };
8326
- var handlePortMove = function (offsetX, offsetY) {
8369
+ var handlePortMove = function (newX, newY) {
8327
8370
  if (!selectedPort)
8328
8371
  return;
8329
8372
  var oldPosition = __assign({}, selectedPort.position);
8330
- var tempNewPosition = { x: oldPosition.x + offsetX, y: oldPosition.y + offsetY };
8373
+ var tempNewPosition = transformAbsPositionToRelativePositionInsideElement({
8374
+ x: newX,
8375
+ y: newY,
8376
+ }, elementAbsPosition);
8331
8377
  //handle to keep the port always in the correct allowed position
8332
8378
  var newPosition = normalizePortPosition(tempNewPosition);
8333
8379
  if (newPosition) {
@@ -8360,15 +8406,17 @@ var Element = function (props) {
8360
8406
  }
8361
8407
  }, [_paperEventEmitterContext, potentialPortPosition]);
8362
8408
  //Update state when label of port is moved
8363
- var handlePortLabelMoved = React.useCallback(function (offsetX, offsetY, portId) {
8409
+ var handlePortLabelMoved = React.useCallback(function (newX, newY, portId) {
8364
8410
  setPorts(function (prevPorts) {
8365
8411
  return prevPorts.map(function (p) {
8366
8412
  if (p.id === portId && p.label) {
8367
- if (!p.label.position) {
8368
- p.label.position = PORT_LABEL_POSITION;
8369
- }
8370
- p.label.position.x += offsetX;
8371
- p.label.position.y += offsetY;
8413
+ var newLabel = Object.assign(Object.create(Object.getPrototypeOf(p.label)), p.label);
8414
+ var newPosition = {
8415
+ x: newX,
8416
+ y: newY
8417
+ };
8418
+ newLabel.position = newPosition;
8419
+ p.label = newLabel;
8372
8420
  }
8373
8421
  return p;
8374
8422
  });
@@ -8527,9 +8575,11 @@ var Element = function (props) {
8527
8575
  enabled: false,
8528
8576
  keepRatio: false
8529
8577
  },
8578
+ x: selectedPort ? elementAbsPosition.x + selectedPort.position.x : undefined,
8579
+ y: selectedPort ? elementAbsPosition.y + selectedPort.position.y : undefined,
8530
8580
  // width: selectedPort?.size.width,
8531
8581
  // height: selectedPort?.size.height,
8532
- movingOffsetThreshold: PORT_MOVING_OFFSET_THRESHOLD,
8582
+ // movingOffsetThreshold: PORT_MOVING_OFFSET_THRESHOLD,
8533
8583
  onMove: handlePortMove
8534
8584
  });
8535
8585
  useSelectionFrame({
@@ -8547,7 +8597,7 @@ var Element = function (props) {
8547
8597
  : React.createElement("rect", { x: potentialPortPosition.x - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, y: potentialPortPosition.y - PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH / 2, width: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, height: PORT_PLACEHOLDER_DEFAULT_STROKE_WIDTH, rx: PORT_PLACEHOLDER_DEFAULT_SIZE, ry: PORT_PLACEHOLDER_DEFAULT_SIZE, stroke: PORT_PLACEHOLDER_DEFAULT_STROKE, fill: "none", strokeWidth: 3 })), ports === null || ports === void 0 ? void 0 :
8548
8598
  ports.map(function (p, index) {
8549
8599
  var _a, _b, _c, _d, _e, _f;
8550
- return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container,
8600
+ return React.createElement(Port, { key: p.id, ref: p.ref, id: p.id, x: p.position.x, y: p.position.y, parentAbsolutePosition: elementAbsPosition, width: (_c = (_b = (_a = p.size) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : defaultPortSize) !== null && _c !== void 0 ? _c : PORT_DEFAULT_SIZE, height: (_f = (_e = (_d = p.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : defaultPortSize) !== null && _f !== void 0 ? _f : PORT_DEFAULT_SIZE, container: container,
8551
8601
  // rotation={rotatePort(p)}
8552
8602
  calculateRotationAngle: rotatePort, label: p.label, onPortLabelMoved: handlePortLabelMoved, onPortLabelResized: handlePortLabelResized, onPortLabelContentChanged: handlePortLabelContentChanged, onSelected: handleSelectedPort, onMouseDown: handlePortMouseDown, onMouseUp: handlePortMouseUp, onMouseMove: handlePortMouseMove,
8553
8603
  // onMouseEnter={() => {
@@ -8559,7 +8609,7 @@ var Element = function (props) {
8559
8609
  }), texts === null || texts === void 0 ? void 0 :
8560
8610
  texts.map(function (t, index) {
8561
8611
  var _a, _b;
8562
- 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, y: (_b = t.position) === null || _b === void 0 ? void 0 : _b.y, 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, onContentChanged: function (ev, newContent) { return onTextUpdated === null || onTextUpdated === void 0 ? void 0 : onTextUpdated(id, t.id, newContent); } });
8612
+ 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); } });
8563
8613
  }),
8564
8614
  children));
8565
8615
  };
@@ -8857,6 +8907,7 @@ var Paper = function (props) {
8857
8907
  var linksRef = React.useRef(links); //Cache links to avoid re-render when links changed
8858
8908
  var textsRef = React.useRef(texts); //Cache texts to avoid re-render when texts changed
8859
8909
  var size = props.size;
8910
+ var selectedElementAbsPosition = React.useMemo(function () { return selectedElement ? getAbsolutePosition(selectedElement) : null; }, [selectedElement]);
8860
8911
  React.useEffect(function () {
8861
8912
  setElements(props.elements);
8862
8913
  }, [props.elements]);
@@ -9235,35 +9286,24 @@ var Paper = function (props) {
9235
9286
  setTempLink(null);
9236
9287
  }
9237
9288
  }, [paperEventEmitter, createElementLink, props.onPortMouseUp, props.onLinksChanged]);
9238
- var handleLinkLabelMoved = React.useCallback(function (offsetX, offsetY, index, labelType) {
9289
+ var handleLinkLabelMoved = React.useCallback(function (newX, newY, index, labelType) {
9239
9290
  var prevLinks = linksRef.current;
9240
9291
  var newLinks = __spreadArray([], prevLinks, true);
9241
9292
  var currentLink = newLinks[index];
9293
+ var newPosition = {
9294
+ x: newX,
9295
+ y: newY,
9296
+ };
9242
9297
  switch (labelType) {
9243
9298
  case 'middle': {
9244
- var oldPosition = currentLink.label.position || LINK_LABEL_POSITION_FROM_LINK_MID_POINT;
9245
- var newPosition = {
9246
- x: oldPosition.x + offsetX,
9247
- y: oldPosition.y + offsetY,
9248
- };
9249
9299
  currentLink.label.position = newPosition;
9250
9300
  break;
9251
9301
  }
9252
9302
  case 'source': {
9253
- var oldPosition = currentLink.sourceLabel.position || LINK_SOURCE_LABEL_POSITION_FROM_SOURCE_PORT;
9254
- var newPosition = {
9255
- x: oldPosition.x + offsetX,
9256
- y: oldPosition.y + offsetY,
9257
- };
9258
9303
  currentLink.sourceLabel.position = newPosition;
9259
9304
  break;
9260
9305
  }
9261
9306
  case 'target': {
9262
- var oldPosition = currentLink.targetLabel.position || LINK_TARGET_LABEL_POSITION_FROM_TARGET_PORT;
9263
- var newPosition = {
9264
- x: oldPosition.x + offsetX,
9265
- y: oldPosition.y + offsetY,
9266
- };
9267
9307
  currentLink.targetLabel.position = newPosition;
9268
9308
  break;
9269
9309
  }
@@ -9338,9 +9378,10 @@ var Paper = function (props) {
9338
9378
  setSelectedLink(undefined);
9339
9379
  };
9340
9380
  //update absolute position of element and absolute position of children elements
9341
- var updateElementPosition = function (element, movementX, movementY) {
9342
- element.position.x += movementX;
9343
- element.position.y += movementY;
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;
9344
9385
  return element;
9345
9386
  };
9346
9387
  //use selection frame
@@ -9351,14 +9392,16 @@ var Paper = function (props) {
9351
9392
  enabled: true,
9352
9393
  keepRatio: true
9353
9394
  },
9395
+ x: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.x,
9396
+ y: selectedElementAbsPosition === null || selectedElementAbsPosition === void 0 ? void 0 : selectedElementAbsPosition.y,
9354
9397
  width: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.width,
9355
9398
  height: selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.size.height,
9356
9399
  //movingOffsetThreshold: ELEMENT_MOVING_OFFSET_THRESHOLD,
9357
- onMove: function (offsetX, offsetY) {
9400
+ onMove: function (newX, newY) {
9358
9401
  if (!selectedElement)
9359
9402
  return;
9360
9403
  var oldPosition = __assign({}, selectedElement.position);
9361
- var newElementPosition = updateElementPosition(selectedElement, offsetX, offsetY);
9404
+ var newElementPosition = updateElementPosition(selectedElement, newX, newY);
9362
9405
  var indexSelectedElement = elements.findIndex(function (e) { return e.id === selectedElement.id; });
9363
9406
  //Set state to re-render UI with new position
9364
9407
  setElementsInTree(function (prev) { return __spreadArray([], prev, true); });
@@ -9392,8 +9435,8 @@ var Paper = function (props) {
9392
9435
  avoid causing the components using it to re-render unnecessarily
9393
9436
  */
9394
9437
  var onLabelMoved = React.useCallback(function (index) {
9395
- return function (offsetX, offsetY, labelType) {
9396
- handleLinkLabelMoved(offsetX, offsetY, index, labelType);
9438
+ return function (newX, newY, labelType) {
9439
+ handleLinkLabelMoved(newX, newY, index, labelType);
9397
9440
  };
9398
9441
  }, [handleLinkLabelMoved]);
9399
9442
  /*
@@ -9528,7 +9571,7 @@ var Paper = function (props) {
9528
9571
  return (React.createElement("g", { id: "group-of-element-".concat(element.id), key: element.id },
9529
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,
9530
9573
  // portPlaceholderShape={(<Circle x={0} y={0} width={10} height={10} fill='red' positioningAnchor={PositioningAnchor.Center} />)}
9531
- onMouseUpAtLinkedPortPlaceholder: handleMouseUpAtLinkedPortPlaceholder, onTextUpdated: handleElementTextChange, onManuallyTriggerRenderPort: props.onManuallyTriggerRenderPort, textsPlaceHolderClassName: element.textsPlaceHolderClassName, textsPlaceHolderFlexStyle: element.textsPlaceHolderFlexStyle, textsPlaceHolderFlexboxPosition: element.textsPlaceHolderFlexboxPosition }, element.childrenElementsInTree && element.childrenElementsInTree.map(renderElementInTree))));
9574
+ 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))));
9532
9575
  }, [handleElementClicked, handleContextMenu, handlePortMoved, handlePortMouseDown, handlePortMouseUp, handleMouseUpAtLinkedPortPlaceholder, handleElementTextChange, handleMouseUp, handleMouseMove, handleMouseLeave]);
9533
9576
  var ElementsInTree = React.useMemo(function () {
9534
9577
  return elementsInTree.map(function (element, index) {