@html-graph/html-graph 8.17.0 → 8.18.1

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.
@@ -623,7 +623,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
623
623
  removeNonexistentPort: (portId) => `Failed to remove port with ID ${JSON.stringify(portId)} because it does not exist`,
624
624
  accessNonexistentEdge: (edgeId) => `Failed to access edge with ID ${JSON.stringify(edgeId)} because it does not exist`,
625
625
  addEdgeWithExistingId: (edgeId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} because an edge with this ID already exists`,
626
- addEdgeWithElementInUse: (edgeId, useEdgeId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} because its SVG element is already attached to edge with ID ${JSON.stringify(useEdgeId)}`,
626
+ addEdgeWithElementInUse: (edgeId, useEdgeId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} because its element is already attached to edge with ID ${JSON.stringify(useEdgeId)}`,
627
627
  addEdgeFromNonexistentPort: (edgeId, portId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} from port with ID ${JSON.stringify(portId)} because the port does not exist`,
628
628
  addEdgeToNonexistentPort: (edgeId, portId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} to port with ID ${JSON.stringify(portId)} because the port does not exist`,
629
629
  updateNonexistentEdge: (edgeId) => `Failed to update edge with ID ${JSON.stringify(edgeId)} because it does not exist`,
@@ -1475,48 +1475,52 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1475
1475
  return parts.join(" ");
1476
1476
  };
1477
1477
  const createLine$1 = (from, to) => {
1478
- const horizontalLineDir = to.x - from.x >= 0;
1478
+ const fromLine = from.linePoint;
1479
+ const toLine = to.linePoint;
1480
+ const horizontalLineDir = toLine.x - fromLine.x >= 0;
1479
1481
  const fromPortDir = from.dirX >= 0;
1480
1482
  const toPortDir = to.dirX >= 0;
1481
1483
  const isSameDirPorts = fromPortDir === toPortDir;
1482
1484
  if (isSameDirPorts) {
1483
1485
  const isSameDirLine = fromPortDir === horizontalLineDir;
1484
- const centerX = (from.x + to.x) / 2;
1485
- const centerY2 = (from.y + to.y) / 2;
1486
+ const centerX = (fromLine.x + toLine.x) / 2;
1487
+ const centerY2 = (fromLine.y + toLine.y) / 2;
1486
1488
  const midpoint = { x: centerX, y: centerY2 };
1487
1489
  if (isSameDirLine) {
1488
1490
  return {
1489
1491
  points: [
1490
- { x: from.x, y: from.y },
1491
- { x: midpoint.x, y: from.y },
1492
- { x: midpoint.x, y: to.y },
1493
- { x: to.x, y: to.y }
1492
+ from.arrowPoint,
1493
+ { x: midpoint.x, y: fromLine.y },
1494
+ { x: midpoint.x, y: toLine.y },
1495
+ to.arrowPoint
1494
1496
  ],
1495
1497
  midpoint
1496
1498
  };
1497
1499
  }
1498
1500
  return {
1499
1501
  points: [
1500
- { x: from.x, y: from.y },
1501
- { x: from.x, y: midpoint.y },
1502
- { x: to.x, y: midpoint.y },
1503
- { x: to.x, y: to.y }
1502
+ from.arrowPoint,
1503
+ fromLine,
1504
+ { x: fromLine.x, y: midpoint.y },
1505
+ { x: toLine.x, y: midpoint.y },
1506
+ toLine,
1507
+ to.arrowPoint
1504
1508
  ],
1505
1509
  midpoint
1506
1510
  };
1507
1511
  }
1508
1512
  const isSameSourceDir = fromPortDir === horizontalLineDir;
1509
- const centerY = (from.y + to.y) / 2;
1513
+ const centerY = (fromLine.y + toLine.y) / 2;
1510
1514
  if (isSameSourceDir) {
1511
- const joint2 = { x: to.x, y: from.y };
1515
+ const joint2 = { x: toLine.x, y: fromLine.y };
1512
1516
  return {
1513
- points: [{ x: from.x, y: from.y }, joint2, { x: to.x, y: to.y }],
1517
+ points: [from.arrowPoint, joint2, toLine, to.arrowPoint],
1514
1518
  midpoint: { x: joint2.x, y: centerY }
1515
1519
  };
1516
1520
  }
1517
- const joint = { x: from.x, y: to.y };
1521
+ const joint = { x: fromLine.x, y: toLine.y };
1518
1522
  return {
1519
- points: [{ x: from.x, y: from.y }, joint, { x: to.x, y: to.y }],
1523
+ points: [from.arrowPoint, fromLine, joint, to.arrowPoint],
1520
1524
  midpoint: { x: joint.x, y: centerY }
1521
1525
  };
1522
1526
  };
@@ -1540,14 +1544,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1540
1544
  fromDir,
1541
1545
  from
1542
1546
  ) : from;
1543
- const endArrow = hasTargetArrow ? createRotatedPoint(
1544
- {
1545
- x: to.x - arrowLength,
1546
- y: to.y
1547
- },
1548
- toDir,
1549
- to
1550
- ) : to;
1547
+ const endArrow = hasTargetArrow ? createRotatedPoint({ x: to.x - arrowLength, y: to.y }, toDir, to) : to;
1551
1548
  const gap = arrowLength + arrowOffset;
1552
1549
  const beginLine = createRotatedPoint(
1553
1550
  { x: from.x + gap, y: from.y },
@@ -1556,21 +1553,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1556
1553
  );
1557
1554
  const endLine = createRotatedPoint({ x: to.x - gap, y: to.y }, toDir, to);
1558
1555
  const line = createLine$1(
1559
- {
1560
- x: beginLine.x,
1561
- y: beginLine.y,
1562
- dirX: fromDir.x
1563
- },
1564
- {
1565
- x: endLine.x,
1566
- y: endLine.y,
1567
- dirX: toDir.x
1568
- }
1569
- );
1570
- this.path = createRoundedPath(
1571
- [beginArrow, ...line.points, endArrow],
1572
- roundness
1556
+ { arrowPoint: beginArrow, linePoint: beginLine, dirX: fromDir.x },
1557
+ { arrowPoint: endArrow, linePoint: endLine, dirX: toDir.x }
1573
1558
  );
1559
+ this.path = createRoundedPath(line.points, roundness);
1574
1560
  this.midpoint = line.midpoint;
1575
1561
  }
1576
1562
  }
@@ -1687,48 +1673,52 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1687
1673
  }
1688
1674
  }
1689
1675
  const createLine = (from, to) => {
1690
- const verticalLineDir = to.y - from.y >= 0;
1676
+ const fromLine = from.linePoint;
1677
+ const toLine = to.linePoint;
1678
+ const verticalLineDir = toLine.y - fromLine.y >= 0;
1691
1679
  const fromPortDir = from.dirY >= 0;
1692
1680
  const toPortDir = to.dirY >= 0;
1693
1681
  const isSameDirPorts = fromPortDir === toPortDir;
1694
1682
  if (isSameDirPorts) {
1695
1683
  const isSameDirLine = fromPortDir === verticalLineDir;
1696
- const centerX2 = (from.x + to.x) / 2;
1697
- const centerY = (from.y + to.y) / 2;
1684
+ const centerX2 = (fromLine.x + toLine.x) / 2;
1685
+ const centerY = (fromLine.y + toLine.y) / 2;
1698
1686
  const midpoint = { x: centerX2, y: centerY };
1699
1687
  if (isSameDirLine) {
1700
1688
  return {
1701
1689
  points: [
1702
- { x: from.x, y: from.y },
1703
- { x: from.x, y: midpoint.y },
1704
- { x: to.x, y: midpoint.y },
1705
- { x: to.x, y: to.y }
1690
+ from.arrowPoint,
1691
+ { x: fromLine.x, y: midpoint.y },
1692
+ { x: toLine.x, y: midpoint.y },
1693
+ to.arrowPoint
1706
1694
  ],
1707
1695
  midpoint
1708
1696
  };
1709
1697
  }
1710
1698
  return {
1711
1699
  points: [
1712
- { x: from.x, y: from.y },
1713
- { x: midpoint.x, y: from.y },
1714
- { x: midpoint.x, y: to.y },
1715
- { x: to.x, y: to.y }
1700
+ from.arrowPoint,
1701
+ fromLine,
1702
+ { x: midpoint.x, y: fromLine.y },
1703
+ { x: midpoint.x, y: toLine.y },
1704
+ toLine,
1705
+ to.arrowPoint
1716
1706
  ],
1717
1707
  midpoint
1718
1708
  };
1719
1709
  }
1720
1710
  const isSameSourceDir = fromPortDir === verticalLineDir;
1721
- const centerX = (from.x + to.x) / 2;
1711
+ const centerX = (fromLine.x + toLine.x) / 2;
1722
1712
  if (isSameSourceDir) {
1723
- const joint2 = { x: from.x, y: to.y };
1713
+ const joint2 = { x: fromLine.x, y: toLine.y };
1724
1714
  return {
1725
- points: [{ x: from.x, y: from.y }, joint2, { x: to.x, y: to.y }],
1715
+ points: [from.arrowPoint, joint2, toLine, to.arrowPoint],
1726
1716
  midpoint: { x: centerX, y: joint2.y }
1727
1717
  };
1728
1718
  }
1729
- const joint = { x: to.x, y: from.y };
1719
+ const joint = { x: toLine.x, y: fromLine.y };
1730
1720
  return {
1731
- points: [{ x: from.x, y: from.y }, joint, { x: to.x, y: to.y }],
1721
+ points: [from.arrowPoint, fromLine, joint, to.arrowPoint],
1732
1722
  midpoint: { x: centerX, y: joint.y }
1733
1723
  };
1734
1724
  };
@@ -1752,14 +1742,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1752
1742
  fromDir,
1753
1743
  from
1754
1744
  ) : from;
1755
- const endArrow = hasTargetArrow ? createRotatedPoint(
1756
- {
1757
- x: to.x - arrowLength,
1758
- y: to.y
1759
- },
1760
- toDir,
1761
- to
1762
- ) : to;
1745
+ const endArrow = hasTargetArrow ? createRotatedPoint({ x: to.x - arrowLength, y: to.y }, toDir, to) : to;
1763
1746
  const gap = arrowLength + arrowOffset;
1764
1747
  const beginLine = createRotatedPoint(
1765
1748
  { x: from.x + gap, y: from.y },
@@ -1768,21 +1751,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1768
1751
  );
1769
1752
  const endLine = createRotatedPoint({ x: to.x - gap, y: to.y }, toDir, to);
1770
1753
  const line = createLine(
1771
- {
1772
- x: beginLine.x,
1773
- y: beginLine.y,
1774
- dirY: fromDir.y
1775
- },
1776
- {
1777
- x: endLine.x,
1778
- y: endLine.y,
1779
- dirY: toDir.y
1780
- }
1781
- );
1782
- this.path = createRoundedPath(
1783
- [beginArrow, ...line.points, endArrow],
1784
- roundness
1754
+ { arrowPoint: beginArrow, linePoint: beginLine, dirY: fromDir.y },
1755
+ { arrowPoint: endArrow, linePoint: endLine, dirY: toDir.y }
1785
1756
  );
1757
+ this.path = createRoundedPath(line.points, roundness);
1786
1758
  this.midpoint = line.midpoint;
1787
1759
  }
1788
1760
  }
@@ -2297,6 +2269,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2297
2269
  this.pathShape.render(params);
2298
2270
  }
2299
2271
  }
2272
+ const horizontalizeDirection = (direction) => {
2273
+ return Math.cos(direction) > 0 ? 0 : Math.PI;
2274
+ };
2300
2275
  class HorizontalEdgeShape {
2301
2276
  constructor(params) {
2302
2277
  __publicField(this, "svg");
@@ -2377,7 +2352,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2377
2352
  this.onAfterRender = this.pathShape.onAfterRender;
2378
2353
  }
2379
2354
  render(params) {
2380
- this.pathShape.render(params);
2355
+ const { from, to, category } = params;
2356
+ this.pathShape.render({
2357
+ category,
2358
+ from: {
2359
+ ...from,
2360
+ direction: horizontalizeDirection(from.direction)
2361
+ },
2362
+ to: {
2363
+ ...to,
2364
+ direction: horizontalizeDirection(to.direction)
2365
+ }
2366
+ });
2381
2367
  }
2382
2368
  }
2383
2369
  class StraightEdgeShape {
@@ -2466,6 +2452,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2466
2452
  this.pathShape.render(params);
2467
2453
  }
2468
2454
  }
2455
+ const pi2 = Math.PI / 2;
2456
+ const verticalizeDirection = (direction) => {
2457
+ return Math.sin(direction) > 0 ? pi2 : -pi2;
2458
+ };
2469
2459
  class VerticalEdgeShape {
2470
2460
  constructor(params) {
2471
2461
  __publicField(this, "svg");
@@ -2546,7 +2536,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2546
2536
  this.onAfterRender = this.pathShape.onAfterRender;
2547
2537
  }
2548
2538
  render(params) {
2549
- this.pathShape.render(params);
2539
+ const { from, to, category } = params;
2540
+ this.pathShape.render({
2541
+ category,
2542
+ from: {
2543
+ ...from,
2544
+ direction: verticalizeDirection(from.direction)
2545
+ },
2546
+ to: {
2547
+ ...to,
2548
+ direction: verticalizeDirection(to.direction)
2549
+ }
2550
+ });
2550
2551
  }
2551
2552
  }
2552
2553
  class DirectEdgeShape {
@@ -3233,13 +3234,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3233
3234
  start = timestamp;
3234
3235
  }
3235
3236
  const progress = Math.min((timestamp - start) / duration, 1);
3236
- if (progress <= 1) {
3237
- this.viewportStore.patchViewportMatrix({
3238
- scale: previousViewportMatrix.scale + progress * deltaMatrix.scale,
3239
- x: previousViewportMatrix.x + progress * deltaMatrix.x,
3240
- y: previousViewportMatrix.y + progress * deltaMatrix.y
3241
- });
3242
- }
3237
+ this.viewportStore.patchViewportMatrix({
3238
+ scale: previousViewportMatrix.scale + progress * deltaMatrix.scale,
3239
+ x: previousViewportMatrix.x + progress * deltaMatrix.x,
3240
+ y: previousViewportMatrix.y + progress * deltaMatrix.y
3241
+ });
3243
3242
  if (progress < 1) {
3244
3243
  this.win.requestAnimationFrame(step);
3245
3244
  }
@@ -3309,7 +3308,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3309
3308
  }
3310
3309
  const target = event.currentTarget;
3311
3310
  const portId = this.canvas.graph.findPortIdsByElement(target)[0];
3312
- const dragAllowed = this.params.portDragAllowedVerifier(portId, {
3311
+ const dragAllowed = this.params.onPointerDownVerifier(portId, {
3313
3312
  x: mouseEvent.clientX,
3314
3313
  y: mouseEvent.clientY
3315
3314
  });
@@ -3351,7 +3350,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3351
3350
  const touch = touchEvent.touches[0];
3352
3351
  const target = event.currentTarget;
3353
3352
  const portId = this.canvas.graph.findPortIdsByElement(target)[0];
3354
- const dragAllowed = this.params.portDragAllowedVerifier(portId, {
3353
+ const dragAllowed = this.params.onPointerDownVerifier(portId, {
3355
3354
  x: touch.clientX,
3356
3355
  y: touch.clientY
3357
3356
  });
@@ -3589,6 +3588,52 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3589
3588
  }
3590
3589
  }
3591
3590
  }
3591
+ const resolveCreateEdgeRequest = (params, targetPortId) => {
3592
+ return {
3593
+ from: params.isDirect ? params.staticPortId : targetPortId,
3594
+ to: params.isDirect ? targetPortId : params.staticPortId
3595
+ };
3596
+ };
3597
+ class ClosestConnectablePortDraggingPortDirectionResolver {
3598
+ constructor(graph, connectionAllowedVerifier) {
3599
+ this.graph = graph;
3600
+ this.connectionAllowedVerifier = connectionAllowedVerifier;
3601
+ }
3602
+ resolve(params) {
3603
+ let closestDirection = void 0;
3604
+ let closestDistance = Infinity;
3605
+ const { cursor } = params;
3606
+ this.graph.getAllPortIds().forEach((portId) => {
3607
+ const { element, direction, nodeId } = this.graph.getPort(portId);
3608
+ const { x, y } = this.graph.getNode(nodeId);
3609
+ if (x === null || y === null) {
3610
+ return;
3611
+ }
3612
+ const request = resolveCreateEdgeRequest(params, portId);
3613
+ if (!this.connectionAllowedVerifier(request)) {
3614
+ return;
3615
+ }
3616
+ const { top, left, width, height } = element.getBoundingClientRect();
3617
+ const center = { x: left + width / 2, y: top + height / 2 };
3618
+ const dx = cursor.x - center.x;
3619
+ const dy = cursor.y - center.y;
3620
+ const distance = Math.sqrt(dx * dx + dy * dy);
3621
+ if (distance < closestDistance) {
3622
+ closestDistance = distance;
3623
+ closestDirection = direction;
3624
+ }
3625
+ });
3626
+ return closestDirection;
3627
+ }
3628
+ }
3629
+ class ConstantDraggingPortDirectionResolver {
3630
+ constructor(direction) {
3631
+ this.direction = direction;
3632
+ }
3633
+ resolve() {
3634
+ return this.direction;
3635
+ }
3636
+ }
3592
3637
  class UserDraggableNodesConfigurator {
3593
3638
  constructor(canvas, element, window2, pointInsideVerifier, params) {
3594
3639
  __publicField(this, "grabbedNode", null);
@@ -4310,8 +4355,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4310
4355
  class UserConnectablePortsConfigurator {
4311
4356
  constructor(canvas, overlayLayer, viewportStore, window2, pointInsideVerifier, params) {
4312
4357
  __publicField(this, "overlayCanvas");
4313
- __publicField(this, "staticPortId", null);
4314
- __publicField(this, "isTargetDragging", true);
4358
+ __publicField(this, "edgeInProgress", null);
4315
4359
  __publicField(this, "onEdgeCreated", (edgeId) => {
4316
4360
  this.params.onAfterEdgeCreated(edgeId);
4317
4361
  });
@@ -4329,7 +4373,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4329
4373
  const draggablePortsParams = {
4330
4374
  mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4331
4375
  mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4332
- portDragAllowedVerifier: (portId, cursor) => {
4376
+ onPointerDownVerifier: (portId, cursor) => {
4333
4377
  const connectionType = this.params.connectionTypeResolver(portId);
4334
4378
  if (connectionType === null) {
4335
4379
  return false;
@@ -4345,13 +4389,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4345
4389
  this.resetDragState();
4346
4390
  },
4347
4391
  onPointerOutside: () => {
4348
- const staticPortId = this.staticPortId;
4349
- const isTargetDragging = this.isTargetDragging;
4392
+ const params2 = this.edgeInProgress;
4350
4393
  this.resetDragState();
4351
- this.params.onEdgeCreationInterrupted({
4352
- staticPortId,
4353
- isDirect: isTargetDragging
4354
- });
4394
+ this.params.onEdgeCreationInterrupted(params2);
4355
4395
  }
4356
4396
  };
4357
4397
  DraggablePortsConfigurator.configure(
@@ -4371,9 +4411,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4371
4411
  params
4372
4412
  );
4373
4413
  }
4374
- grabPort(portId, cursor, connectionType) {
4375
- const port = this.canvas.graph.getPort(portId);
4376
- this.staticPortId = portId;
4414
+ grabPort(staticPortId, cursor, connectionType) {
4415
+ const port = this.canvas.graph.getPort(staticPortId);
4377
4416
  const portRect = port.element.getBoundingClientRect();
4378
4417
  const portX = portRect.x + portRect.width / 2;
4379
4418
  const portY = portRect.y + portRect.height / 2;
@@ -4391,13 +4430,23 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4391
4430
  portCoords: portPoint,
4392
4431
  portDirection: port.direction
4393
4432
  };
4433
+ const isDirect = connectionType === "direct";
4434
+ this.edgeInProgress = {
4435
+ staticPortId,
4436
+ isDirect
4437
+ };
4438
+ const resolvedDirection = this.params.draggingPortDirectionResolver.resolve(
4439
+ {
4440
+ cursor,
4441
+ ...this.edgeInProgress
4442
+ }
4443
+ );
4394
4444
  const draggingParams = {
4395
4445
  overlayNodeId: OverlayId.DraggingNodeId,
4396
4446
  portCoords: cursorPoint,
4397
- portDirection: this.params.dragPortDirection
4447
+ portDirection: resolvedDirection ?? port.direction
4398
4448
  };
4399
- this.isTargetDragging = connectionType === "direct";
4400
- const [sourceParams, targetParams] = this.isTargetDragging ? [staticParams, draggingParams] : [draggingParams, staticParams];
4449
+ const [sourceParams, targetParams] = isDirect ? [staticParams, draggingParams] : [draggingParams, staticParams];
4401
4450
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(sourceParams));
4402
4451
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(targetParams));
4403
4452
  this.overlayCanvas.addEdge({
@@ -4407,25 +4456,24 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4407
4456
  });
4408
4457
  }
4409
4458
  resetDragState() {
4410
- this.staticPortId = null;
4411
- this.isTargetDragging = true;
4459
+ this.edgeInProgress = null;
4412
4460
  this.overlayCanvas.clear();
4413
4461
  }
4414
4462
  tryCreateConnection(cursor) {
4415
- const draggingPortId = findPortAtPoint(this.canvas.graph, cursor);
4416
- if (draggingPortId === null) {
4417
- this.params.onEdgeCreationInterrupted({
4418
- staticPortId: this.staticPortId,
4419
- isDirect: this.isTargetDragging
4420
- });
4463
+ const targetPortId = findPortAtPoint(this.canvas.graph, cursor);
4464
+ if (targetPortId === null) {
4465
+ this.params.onEdgeCreationInterrupted(this.edgeInProgress);
4421
4466
  return;
4422
4467
  }
4423
- const staticPortId = this.staticPortId;
4424
- const sourceId = this.isTargetDragging ? staticPortId : draggingPortId;
4425
- const targetId = this.isTargetDragging ? draggingPortId : staticPortId;
4426
- const request = { from: sourceId, to: targetId };
4468
+ const request = resolveCreateEdgeRequest(
4469
+ this.edgeInProgress,
4470
+ targetPortId
4471
+ );
4427
4472
  const connectionAllowed = this.params.connectionAllowedVerifier(request);
4428
- const processedRequest = this.params.connectionPreprocessor(request);
4473
+ const processedRequest = this.params.connectionPreprocessor({
4474
+ from: request.from,
4475
+ to: request.to
4476
+ });
4429
4477
  if (connectionAllowed && processedRequest !== null) {
4430
4478
  this.canvas.graph.onAfterEdgeAdded.subscribe(this.onEdgeCreated);
4431
4479
  this.canvas.addEdge(processedRequest);
@@ -4434,23 +4482,26 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4434
4482
  this.params.onEdgeCreationPrevented(request);
4435
4483
  }
4436
4484
  }
4437
- moveDraggingPort(dragPoint) {
4485
+ moveDraggingPort(cursor) {
4438
4486
  const canvasRect = this.overlayLayer.getBoundingClientRect();
4439
4487
  const nodeContentCoords = this.canvas.viewport.createContentCoords({
4440
- x: dragPoint.x - canvasRect.x,
4441
- y: dragPoint.y - canvasRect.y
4488
+ x: cursor.x - canvasRect.x,
4489
+ y: cursor.y - canvasRect.y
4490
+ });
4491
+ const direction = this.params.draggingPortDirectionResolver.resolve({
4492
+ cursor,
4493
+ ...this.edgeInProgress
4442
4494
  });
4443
4495
  this.overlayCanvas.updateNode(OverlayId.DraggingNodeId, {
4444
4496
  x: nodeContentCoords.x,
4445
4497
  y: nodeContentCoords.y
4446
- });
4498
+ }).updatePort(OverlayId.DraggingNodeId, { direction });
4447
4499
  }
4448
4500
  }
4449
4501
  class UserDraggableEdgesConfigurator {
4450
4502
  constructor(canvas, overlayLayer, viewportStore, window2, pointInsideVerifier, params) {
4451
4503
  __publicField(this, "overlayCanvas");
4452
- __publicField(this, "staticPortId", null);
4453
- __publicField(this, "isTargetDragging", true);
4504
+ __publicField(this, "edgeInProgress", null);
4454
4505
  __publicField(this, "draggingEdgePayload", null);
4455
4506
  __publicField(this, "onEdgeReattached", (edgeId) => {
4456
4507
  this.params.onAfterEdgeReattached(edgeId);
@@ -4469,7 +4520,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4469
4520
  const draggablePortsParams = {
4470
4521
  mouseDownEventVerifier: this.params.mouseDownEventVerifier,
4471
4522
  mouseUpEventVerifier: this.params.mouseUpEventVerifier,
4472
- portDragAllowedVerifier: (portId, cursor) => {
4523
+ onPointerDownVerifier: (portId, cursor) => {
4473
4524
  return this.tryStartEdgeDragging(portId, cursor);
4474
4525
  },
4475
4526
  onPointerMove: (cursor) => {
@@ -4515,10 +4566,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4515
4566
  }
4516
4567
  const edge = this.canvas.graph.getEdge(edgeId);
4517
4568
  const isSourceDragging = portId === edge.from;
4518
- const isTargetDragging = portId === edge.to;
4569
+ const isDirect = portId === edge.to;
4519
4570
  const staticPortId = isSourceDragging ? edge.to : edge.from;
4520
- this.staticPortId = staticPortId;
4521
- this.isTargetDragging = isTargetDragging;
4571
+ this.edgeInProgress = { staticPortId, isDirect };
4522
4572
  const draggingPort = this.canvas.graph.getPort(portId);
4523
4573
  const staticPort = this.canvas.graph.getPort(staticPortId);
4524
4574
  const staticRect = staticPort.element.getBoundingClientRect();
@@ -4548,12 +4598,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4548
4598
  portCoords: staticPoint,
4549
4599
  portDirection: staticPort.direction
4550
4600
  };
4601
+ const resolvedDirection = this.params.draggingPortDirectionResolver.resolve(
4602
+ {
4603
+ cursor,
4604
+ ...this.edgeInProgress
4605
+ }
4606
+ );
4551
4607
  const draggingParams = {
4552
4608
  overlayNodeId: OverlayId.DraggingNodeId,
4553
4609
  portCoords: draggingPoint,
4554
- portDirection: draggingPort.direction
4610
+ portDirection: resolvedDirection ?? draggingPort.direction
4555
4611
  };
4556
- const [sourceParams, targetParams] = this.isTargetDragging ? [staticParams, draggingParams] : [draggingParams, staticParams];
4612
+ const [sourceParams, targetParams] = isDirect ? [staticParams, draggingParams] : [draggingParams, staticParams];
4557
4613
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(sourceParams));
4558
4614
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(targetParams));
4559
4615
  const overlayEdgeShape = this.params.draggingEdgeShapeFactory !== null ? this.params.draggingEdgeShapeFactory(OverlayId.EdgeId) : edge.shape;
@@ -4567,30 +4623,43 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4567
4623
  }
4568
4624
  resetDragState() {
4569
4625
  this.draggingEdgePayload = null;
4570
- this.staticPortId = null;
4571
- this.isTargetDragging = true;
4626
+ this.edgeInProgress = null;
4572
4627
  this.overlayCanvas.clear();
4573
4628
  }
4574
- moveDraggingPort(dragPoint) {
4629
+ moveDraggingPort(cursor) {
4575
4630
  const canvasRect = this.overlayLayer.getBoundingClientRect();
4576
4631
  const nodeViewCoords = {
4577
- x: dragPoint.x - canvasRect.x,
4578
- y: dragPoint.y - canvasRect.y
4632
+ x: cursor.x - canvasRect.x,
4633
+ y: cursor.y - canvasRect.y
4579
4634
  };
4580
4635
  const nodeContentCoords = this.canvas.viewport.createContentCoords(nodeViewCoords);
4636
+ const direction = this.params.draggingPortDirectionResolver.resolve({
4637
+ cursor,
4638
+ ...this.edgeInProgress
4639
+ });
4581
4640
  this.overlayCanvas.updateNode(OverlayId.DraggingNodeId, {
4582
4641
  x: nodeContentCoords.x,
4583
4642
  y: nodeContentCoords.y
4584
- });
4643
+ }).updatePort(OverlayId.DraggingNodeId, { direction });
4585
4644
  }
4586
4645
  tryCreateConnection(cursor) {
4587
4646
  const draggingPortId = findPortAtPoint(this.canvas.graph, cursor);
4588
4647
  this.overlayCanvas.removeEdge(OverlayId.EdgeId);
4589
4648
  if (draggingPortId === null) {
4590
- this.handleEdgeReattachInterrupted();
4649
+ const edge2 = this.draggingEdgePayload;
4650
+ this.params.onEdgeReattachInterrupted({
4651
+ id: edge2.id,
4652
+ from: edge2.from,
4653
+ to: edge2.to,
4654
+ shape: edge2.shape,
4655
+ priority: edge2.priority
4656
+ });
4591
4657
  return;
4592
4658
  }
4593
- const [from, to] = this.isTargetDragging ? [this.staticPortId, draggingPortId] : [draggingPortId, this.staticPortId];
4659
+ const { from, to } = resolveCreateEdgeRequest(
4660
+ this.edgeInProgress,
4661
+ draggingPortId
4662
+ );
4594
4663
  const edge = this.draggingEdgePayload;
4595
4664
  const request = {
4596
4665
  id: edge.id,
@@ -4619,16 +4688,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4619
4688
  });
4620
4689
  }
4621
4690
  }
4622
- handleEdgeReattachInterrupted() {
4623
- const edge = this.draggingEdgePayload;
4624
- this.params.onEdgeReattachInterrupted({
4625
- id: edge.id,
4626
- from: edge.from,
4627
- to: edge.to,
4628
- shape: edge.shape,
4629
- priority: edge.priority
4630
- });
4631
- }
4632
4691
  }
4633
4692
  class ManualLayoutApplicationStrategyConfigurator {
4634
4693
  constructor(applier, trigger) {
@@ -4993,6 +5052,87 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4993
5052
  });
4994
5053
  const noopFn = () => {
4995
5054
  };
5055
+ const resolveDraggingPortDirectionResolver = (config, graph, connectionAllowedVerifier) => {
5056
+ if (config === "closest-connectable-port") {
5057
+ return new ClosestConnectablePortDraggingPortDirectionResolver(
5058
+ graph,
5059
+ connectionAllowedVerifier
5060
+ );
5061
+ }
5062
+ return new ConstantDraggingPortDirectionResolver(config);
5063
+ };
5064
+ const resolveEdgeShapeFactory = (config) => {
5065
+ if (typeof config === "function") {
5066
+ return config;
5067
+ }
5068
+ switch (config.type) {
5069
+ case "straight":
5070
+ return () => new StraightEdgeShape({
5071
+ color: config.color,
5072
+ width: config.width,
5073
+ arrowLength: config.arrowLength,
5074
+ arrowOffset: config.arrowOffset,
5075
+ arrowRenderer: config.arrowRenderer,
5076
+ hasSourceArrow: config.hasSourceArrow,
5077
+ hasTargetArrow: config.hasTargetArrow,
5078
+ cycleSquareSide: config.cycleSquareSide,
5079
+ roundness: config.roundness,
5080
+ detourDistance: config.detourDistance,
5081
+ detourDirection: config.detourDirection
5082
+ });
5083
+ case "horizontal":
5084
+ return () => new HorizontalEdgeShape({
5085
+ color: config.color,
5086
+ width: config.width,
5087
+ arrowLength: config.arrowLength,
5088
+ arrowOffset: config.arrowOffset,
5089
+ arrowRenderer: config.arrowRenderer,
5090
+ hasSourceArrow: config.hasSourceArrow,
5091
+ hasTargetArrow: config.hasTargetArrow,
5092
+ cycleSquareSide: config.cycleSquareSide,
5093
+ roundness: config.roundness,
5094
+ detourDistance: config.detourDistance
5095
+ });
5096
+ case "vertical":
5097
+ return () => new VerticalEdgeShape({
5098
+ color: config.color,
5099
+ width: config.width,
5100
+ arrowLength: config.arrowLength,
5101
+ arrowOffset: config.arrowOffset,
5102
+ arrowRenderer: config.arrowRenderer,
5103
+ hasSourceArrow: config.hasSourceArrow,
5104
+ hasTargetArrow: config.hasTargetArrow,
5105
+ cycleSquareSide: config.cycleSquareSide,
5106
+ roundness: config.roundness,
5107
+ detourDistance: config.detourDistance
5108
+ });
5109
+ case "direct":
5110
+ return () => new DirectEdgeShape({
5111
+ color: config.color,
5112
+ width: config.width,
5113
+ arrowLength: config.arrowLength,
5114
+ arrowRenderer: config.arrowRenderer,
5115
+ hasSourceArrow: config.hasSourceArrow,
5116
+ hasTargetArrow: config.hasTargetArrow,
5117
+ sourceOffset: config.sourceOffset,
5118
+ targetOffset: config.targetOffset
5119
+ });
5120
+ default:
5121
+ return () => new BezierEdgeShape({
5122
+ color: config.color,
5123
+ width: config.width,
5124
+ arrowLength: config.arrowLength,
5125
+ arrowRenderer: config.arrowRenderer,
5126
+ hasSourceArrow: config.hasSourceArrow,
5127
+ hasTargetArrow: config.hasTargetArrow,
5128
+ cycleRadius: config.cycleRadius,
5129
+ smallCycleRadius: config.smallCycleRadius,
5130
+ curvature: config.curvature,
5131
+ detourDistance: config.detourDistance,
5132
+ detourDirection: config.detourDirection
5133
+ });
5134
+ }
5135
+ };
4996
5136
  const createDraggableNodesParams = (config) => {
4997
5137
  var _a, _b, _c, _d, _e, _f;
4998
5138
  const nodeDragVerifier = config.nodeDragVerifier ?? (() => true);
@@ -5187,102 +5327,36 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5187
5327
  maxViewportScale: backgroundConfig.maxViewportScale ?? 10
5188
5328
  };
5189
5329
  };
5190
- const resolveEdgeShapeFactory = (config) => {
5191
- if (typeof config === "function") {
5192
- return config;
5193
- }
5194
- switch (config.type) {
5195
- case "straight":
5196
- return () => new StraightEdgeShape({
5197
- color: config.color,
5198
- width: config.width,
5199
- arrowLength: config.arrowLength,
5200
- arrowOffset: config.arrowOffset,
5201
- arrowRenderer: config.arrowRenderer,
5202
- hasSourceArrow: config.hasSourceArrow,
5203
- hasTargetArrow: config.hasTargetArrow,
5204
- cycleSquareSide: config.cycleSquareSide,
5205
- roundness: config.roundness,
5206
- detourDistance: config.detourDistance,
5207
- detourDirection: config.detourDirection
5208
- });
5209
- case "horizontal":
5210
- return () => new HorizontalEdgeShape({
5211
- color: config.color,
5212
- width: config.width,
5213
- arrowLength: config.arrowLength,
5214
- arrowOffset: config.arrowOffset,
5215
- arrowRenderer: config.arrowRenderer,
5216
- hasSourceArrow: config.hasSourceArrow,
5217
- hasTargetArrow: config.hasTargetArrow,
5218
- cycleSquareSide: config.cycleSquareSide,
5219
- roundness: config.roundness,
5220
- detourDistance: config.detourDistance
5221
- });
5222
- case "vertical":
5223
- return () => new VerticalEdgeShape({
5224
- color: config.color,
5225
- width: config.width,
5226
- arrowLength: config.arrowLength,
5227
- arrowOffset: config.arrowOffset,
5228
- arrowRenderer: config.arrowRenderer,
5229
- hasSourceArrow: config.hasSourceArrow,
5230
- hasTargetArrow: config.hasTargetArrow,
5231
- cycleSquareSide: config.cycleSquareSide,
5232
- roundness: config.roundness,
5233
- detourDistance: config.detourDistance
5234
- });
5235
- case "direct":
5236
- return () => new DirectEdgeShape({
5237
- color: config.color,
5238
- width: config.width,
5239
- arrowLength: config.arrowLength,
5240
- arrowRenderer: config.arrowRenderer,
5241
- hasSourceArrow: config.hasSourceArrow,
5242
- hasTargetArrow: config.hasTargetArrow,
5243
- sourceOffset: config.sourceOffset,
5244
- targetOffset: config.targetOffset
5245
- });
5246
- default:
5247
- return () => new BezierEdgeShape({
5248
- color: config.color,
5249
- width: config.width,
5250
- arrowLength: config.arrowLength,
5251
- arrowRenderer: config.arrowRenderer,
5252
- hasSourceArrow: config.hasSourceArrow,
5253
- hasTargetArrow: config.hasTargetArrow,
5254
- cycleRadius: config.cycleRadius,
5255
- smallCycleRadius: config.smallCycleRadius,
5256
- curvature: config.curvature,
5257
- detourDistance: config.detourDistance,
5258
- detourDirection: config.detourDirection
5259
- });
5260
- }
5261
- };
5262
5330
  const defaults$3 = Object.freeze({
5263
5331
  connectionTypeResolver: () => "direct",
5264
5332
  connectionPreprocessor: (request) => request,
5265
5333
  connectionAllowedVerifier: () => true,
5266
5334
  mouseEventVerifier: (event) => event.button === 0
5267
5335
  });
5268
- const createConnectablePortsParams = (config, defaultEdgeShapeFactory, defaultDragPortDirection) => {
5336
+ const createConnectablePortsParams = (config, defaultEdgeShapeFactory, graph) => {
5269
5337
  var _a, _b, _c;
5338
+ const connectionAllowedVerifier = config.connectionAllowedVerifier ?? defaults$3.connectionAllowedVerifier;
5270
5339
  return {
5271
5340
  connectionTypeResolver: config.connectionTypeResolver ?? defaults$3.connectionTypeResolver,
5341
+ connectionAllowedVerifier,
5342
+ draggingPortDirectionResolver: resolveDraggingPortDirectionResolver(
5343
+ config.dragPortDirection,
5344
+ graph,
5345
+ connectionAllowedVerifier
5346
+ ),
5347
+ edgeShapeFactory: config.edgeShape !== void 0 ? resolveEdgeShapeFactory(config.edgeShape) : defaultEdgeShapeFactory,
5272
5348
  connectionPreprocessor: config.connectionPreprocessor ?? defaults$3.connectionPreprocessor,
5273
- connectionAllowedVerifier: config.connectionAllowedVerifier ?? defaults$3.connectionAllowedVerifier,
5274
5349
  mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaults$3.mouseEventVerifier,
5275
5350
  mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaults$3.mouseEventVerifier,
5276
5351
  onAfterEdgeCreated: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeCreated) ?? noopFn,
5277
5352
  onEdgeCreationInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeCreationInterrupted) ?? noopFn,
5278
- onEdgeCreationPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeCreationPrevented) ?? noopFn,
5279
- dragPortDirection: config.dragPortDirection ?? defaultDragPortDirection,
5280
- edgeShapeFactory: config.edgeShape !== void 0 ? resolveEdgeShapeFactory(config.edgeShape) : defaultEdgeShapeFactory
5353
+ onEdgeCreationPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeCreationPrevented) ?? noopFn
5281
5354
  };
5282
5355
  };
5283
5356
  const defaults$2 = Object.freeze({
5284
5357
  connectionAllowedVerifier: () => true,
5285
5358
  connectionPreprocessor: (request) => request,
5359
+ // TODO: remove ctrl key
5286
5360
  mouseDownEventVerifier: (event) => event.button === 0 && event.ctrlKey,
5287
5361
  mouseUpEventVerifier: (event) => event.button === 0
5288
5362
  });
@@ -5296,16 +5370,22 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5296
5370
  return null;
5297
5371
  }
5298
5372
  };
5373
+ const connectionAllowedVerifier = config.connectionAllowedVerifier ?? defaults$2.connectionAllowedVerifier;
5299
5374
  return {
5300
5375
  connectionPreprocessor: config.connectionPreprocessor ?? defaults$2.connectionPreprocessor,
5301
- connectionAllowedVerifier: config.connectionAllowedVerifier ?? defaults$2.connectionAllowedVerifier,
5376
+ connectionAllowedVerifier,
5302
5377
  mouseDownEventVerifier: config.mouseDownEventVerifier ?? defaults$2.mouseDownEventVerifier,
5303
5378
  mouseUpEventVerifier: config.mouseUpEventVerifier ?? defaults$2.mouseUpEventVerifier,
5304
5379
  draggingEdgeResolver: config.draggingEdgeResolver ?? defaultDraggingEdgeResolver,
5305
5380
  draggingEdgeShapeFactory: config.draggingEdgeShape !== void 0 ? resolveEdgeShapeFactory(config.draggingEdgeShape) : null,
5306
5381
  onAfterEdgeReattached: ((_a = config.events) == null ? void 0 : _a.onAfterEdgeReattached) ?? noopFn,
5307
5382
  onEdgeReattachInterrupted: ((_b = config.events) == null ? void 0 : _b.onEdgeReattachInterrupted) ?? noopFn,
5308
- onEdgeReattachPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeReattachPrevented) ?? noopFn
5383
+ onEdgeReattachPrevented: ((_c = config.events) == null ? void 0 : _c.onEdgeReattachPrevented) ?? noopFn,
5384
+ draggingPortDirectionResolver: resolveDraggingPortDirectionResolver(
5385
+ config.dragPortDirection,
5386
+ graph,
5387
+ connectionAllowedVerifier
5388
+ )
5309
5389
  };
5310
5390
  };
5311
5391
  const createVirtualScrollParams = (config) => {
@@ -6927,7 +7007,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6927
7007
  const params = createConnectablePortsParams(
6928
7008
  this.connectablePortsConfig,
6929
7009
  graphControllerParams.edges.shapeFactory,
6930
- graphControllerParams.ports.direction
7010
+ canvas.graph
6931
7011
  );
6932
7012
  UserConnectablePortsConfigurator.configure(
6933
7013
  canvas,