@html-graph/html-graph 8.18.0 → 8.19.0

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.
@@ -413,7 +413,12 @@ export declare interface DraggableNodesConfig {
413
413
 
414
414
  export declare type DraggingEdgeResolver = (portId: Identifier) => Identifier | null;
415
415
 
416
- declare type DraggingPortDirectionConfig = number | undefined | "closest-connectable-port";
416
+ export declare type DraggingPortDirectionConfig = number | undefined
417
+ /**
418
+ * @deprecated
419
+ * use "nearest-connectable-port" instead
420
+ */
421
+ | "closest-connectable-port" | "nearest-connectable-port";
417
422
 
418
423
  export declare interface EdgeCreationInProgressParams {
419
424
  readonly staticPortId: Identifier;
@@ -729,7 +734,7 @@ export declare class InteractiveEdgeShape implements StructuredEdgeShape {
729
734
  readonly targetArrow: SVGPathElement | null;
730
735
  /**
731
736
  * @deprecated
732
- * do use shape.svg instead
737
+ * use shape.svg instead
733
738
  */
734
739
  readonly handle: SVGGElement;
735
740
  readonly onAfterRender: EventHandler<StructuredEdgeRenderModel>;
@@ -776,7 +781,7 @@ export declare interface LayoutAlgorithmParams {
776
781
  readonly viewport: Viewport;
777
782
  }
778
783
 
779
- export declare type LayoutApplyOn = TopologyChangeMacrotask | TopologyChangeMicrotask | EventSubject<void>;
784
+ export declare type LayoutApplyOn = TopologyChangeMacrotask | TopologyChangeMicrotask | "topologyChangeMicrotask" | EventSubject<void>;
780
785
 
781
786
  export declare interface LayoutConfig {
782
787
  readonly algorithm?: LayoutAlgorithmConfig | undefined;
@@ -949,7 +954,7 @@ export declare interface StructuredEdgeShape extends EdgeShape {
949
954
 
950
955
  /**
951
956
  * @deprecated
952
- * use topologyChangeMicrotask instead
957
+ * use "topologyChangeMicrotask" instead
953
958
  */
954
959
  declare type TopologyChangeMacrotask = {
955
960
  type: "topologyChangeMacrotask";
@@ -1037,7 +1042,7 @@ declare interface UpdateNodeRequest_2 {
1037
1042
  }
1038
1043
 
1039
1044
  export declare interface UpdatePortRequest {
1040
- readonly direction?: number;
1045
+ readonly direction?: number | undefined;
1041
1046
  }
1042
1047
 
1043
1048
  declare interface UpdatePortRequest_2 {
@@ -619,7 +619,7 @@ const canvasErrorText = Object.freeze({
619
619
  removeNonexistentPort: (portId) => `Failed to remove port with ID ${JSON.stringify(portId)} because it does not exist`,
620
620
  accessNonexistentEdge: (edgeId) => `Failed to access edge with ID ${JSON.stringify(edgeId)} because it does not exist`,
621
621
  addEdgeWithExistingId: (edgeId) => `Failed to add edge with ID ${JSON.stringify(edgeId)} because an edge with this ID already exists`,
622
- 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)}`,
622
+ 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)}`,
623
623
  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`,
624
624
  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`,
625
625
  updateNonexistentEdge: (edgeId) => `Failed to update edge with ID ${JSON.stringify(edgeId)} because it does not exist`,
@@ -1471,48 +1471,52 @@ const createRoundedPath = (path, roundness) => {
1471
1471
  return parts.join(" ");
1472
1472
  };
1473
1473
  const createLine$1 = (from, to) => {
1474
- const horizontalLineDir = to.x - from.x >= 0;
1474
+ const fromLine = from.linePoint;
1475
+ const toLine = to.linePoint;
1476
+ const horizontalLineDir = toLine.x - fromLine.x >= 0;
1475
1477
  const fromPortDir = from.dirX >= 0;
1476
1478
  const toPortDir = to.dirX >= 0;
1477
1479
  const isSameDirPorts = fromPortDir === toPortDir;
1478
1480
  if (isSameDirPorts) {
1479
1481
  const isSameDirLine = fromPortDir === horizontalLineDir;
1480
- const centerX = (from.x + to.x) / 2;
1481
- const centerY2 = (from.y + to.y) / 2;
1482
+ const centerX = (fromLine.x + toLine.x) / 2;
1483
+ const centerY2 = (fromLine.y + toLine.y) / 2;
1482
1484
  const midpoint = { x: centerX, y: centerY2 };
1483
1485
  if (isSameDirLine) {
1484
1486
  return {
1485
1487
  points: [
1486
- { x: from.x, y: from.y },
1487
- { x: midpoint.x, y: from.y },
1488
- { x: midpoint.x, y: to.y },
1489
- { x: to.x, y: to.y }
1488
+ from.arrowPoint,
1489
+ { x: midpoint.x, y: fromLine.y },
1490
+ { x: midpoint.x, y: toLine.y },
1491
+ to.arrowPoint
1490
1492
  ],
1491
1493
  midpoint
1492
1494
  };
1493
1495
  }
1494
1496
  return {
1495
1497
  points: [
1496
- { x: from.x, y: from.y },
1497
- { x: from.x, y: midpoint.y },
1498
- { x: to.x, y: midpoint.y },
1499
- { x: to.x, y: to.y }
1498
+ from.arrowPoint,
1499
+ fromLine,
1500
+ { x: fromLine.x, y: midpoint.y },
1501
+ { x: toLine.x, y: midpoint.y },
1502
+ toLine,
1503
+ to.arrowPoint
1500
1504
  ],
1501
1505
  midpoint
1502
1506
  };
1503
1507
  }
1504
1508
  const isSameSourceDir = fromPortDir === horizontalLineDir;
1505
- const centerY = (from.y + to.y) / 2;
1509
+ const centerY = (fromLine.y + toLine.y) / 2;
1506
1510
  if (isSameSourceDir) {
1507
- const joint2 = { x: to.x, y: from.y };
1511
+ const joint2 = { x: toLine.x, y: fromLine.y };
1508
1512
  return {
1509
- points: [{ x: from.x, y: from.y }, joint2, { x: to.x, y: to.y }],
1513
+ points: [from.arrowPoint, joint2, toLine, to.arrowPoint],
1510
1514
  midpoint: { x: joint2.x, y: centerY }
1511
1515
  };
1512
1516
  }
1513
- const joint = { x: from.x, y: to.y };
1517
+ const joint = { x: fromLine.x, y: toLine.y };
1514
1518
  return {
1515
- points: [{ x: from.x, y: from.y }, joint, { x: to.x, y: to.y }],
1519
+ points: [from.arrowPoint, fromLine, joint, to.arrowPoint],
1516
1520
  midpoint: { x: joint.x, y: centerY }
1517
1521
  };
1518
1522
  };
@@ -1536,14 +1540,7 @@ class HorizontalEdgePath {
1536
1540
  fromDir,
1537
1541
  from
1538
1542
  ) : from;
1539
- const endArrow = hasTargetArrow ? createRotatedPoint(
1540
- {
1541
- x: to.x - arrowLength,
1542
- y: to.y
1543
- },
1544
- toDir,
1545
- to
1546
- ) : to;
1543
+ const endArrow = hasTargetArrow ? createRotatedPoint({ x: to.x - arrowLength, y: to.y }, toDir, to) : to;
1547
1544
  const gap = arrowLength + arrowOffset;
1548
1545
  const beginLine = createRotatedPoint(
1549
1546
  { x: from.x + gap, y: from.y },
@@ -1552,21 +1549,10 @@ class HorizontalEdgePath {
1552
1549
  );
1553
1550
  const endLine = createRotatedPoint({ x: to.x - gap, y: to.y }, toDir, to);
1554
1551
  const line = createLine$1(
1555
- {
1556
- x: beginLine.x,
1557
- y: beginLine.y,
1558
- dirX: fromDir.x
1559
- },
1560
- {
1561
- x: endLine.x,
1562
- y: endLine.y,
1563
- dirX: toDir.x
1564
- }
1565
- );
1566
- this.path = createRoundedPath(
1567
- [beginArrow, ...line.points, endArrow],
1568
- roundness
1552
+ { arrowPoint: beginArrow, linePoint: beginLine, dirX: fromDir.x },
1553
+ { arrowPoint: endArrow, linePoint: endLine, dirX: toDir.x }
1569
1554
  );
1555
+ this.path = createRoundedPath(line.points, roundness);
1570
1556
  this.midpoint = line.midpoint;
1571
1557
  }
1572
1558
  }
@@ -1683,48 +1669,52 @@ class StraightEdgePath {
1683
1669
  }
1684
1670
  }
1685
1671
  const createLine = (from, to) => {
1686
- const verticalLineDir = to.y - from.y >= 0;
1672
+ const fromLine = from.linePoint;
1673
+ const toLine = to.linePoint;
1674
+ const verticalLineDir = toLine.y - fromLine.y >= 0;
1687
1675
  const fromPortDir = from.dirY >= 0;
1688
1676
  const toPortDir = to.dirY >= 0;
1689
1677
  const isSameDirPorts = fromPortDir === toPortDir;
1690
1678
  if (isSameDirPorts) {
1691
1679
  const isSameDirLine = fromPortDir === verticalLineDir;
1692
- const centerX2 = (from.x + to.x) / 2;
1693
- const centerY = (from.y + to.y) / 2;
1680
+ const centerX2 = (fromLine.x + toLine.x) / 2;
1681
+ const centerY = (fromLine.y + toLine.y) / 2;
1694
1682
  const midpoint = { x: centerX2, y: centerY };
1695
1683
  if (isSameDirLine) {
1696
1684
  return {
1697
1685
  points: [
1698
- { x: from.x, y: from.y },
1699
- { x: from.x, y: midpoint.y },
1700
- { x: to.x, y: midpoint.y },
1701
- { x: to.x, y: to.y }
1686
+ from.arrowPoint,
1687
+ { x: fromLine.x, y: midpoint.y },
1688
+ { x: toLine.x, y: midpoint.y },
1689
+ to.arrowPoint
1702
1690
  ],
1703
1691
  midpoint
1704
1692
  };
1705
1693
  }
1706
1694
  return {
1707
1695
  points: [
1708
- { x: from.x, y: from.y },
1709
- { x: midpoint.x, y: from.y },
1710
- { x: midpoint.x, y: to.y },
1711
- { x: to.x, y: to.y }
1696
+ from.arrowPoint,
1697
+ fromLine,
1698
+ { x: midpoint.x, y: fromLine.y },
1699
+ { x: midpoint.x, y: toLine.y },
1700
+ toLine,
1701
+ to.arrowPoint
1712
1702
  ],
1713
1703
  midpoint
1714
1704
  };
1715
1705
  }
1716
1706
  const isSameSourceDir = fromPortDir === verticalLineDir;
1717
- const centerX = (from.x + to.x) / 2;
1707
+ const centerX = (fromLine.x + toLine.x) / 2;
1718
1708
  if (isSameSourceDir) {
1719
- const joint2 = { x: from.x, y: to.y };
1709
+ const joint2 = { x: fromLine.x, y: toLine.y };
1720
1710
  return {
1721
- points: [{ x: from.x, y: from.y }, joint2, { x: to.x, y: to.y }],
1711
+ points: [from.arrowPoint, joint2, toLine, to.arrowPoint],
1722
1712
  midpoint: { x: centerX, y: joint2.y }
1723
1713
  };
1724
1714
  }
1725
- const joint = { x: to.x, y: from.y };
1715
+ const joint = { x: toLine.x, y: fromLine.y };
1726
1716
  return {
1727
- points: [{ x: from.x, y: from.y }, joint, { x: to.x, y: to.y }],
1717
+ points: [from.arrowPoint, fromLine, joint, to.arrowPoint],
1728
1718
  midpoint: { x: centerX, y: joint.y }
1729
1719
  };
1730
1720
  };
@@ -1748,14 +1738,7 @@ class VerticalEdgePath {
1748
1738
  fromDir,
1749
1739
  from
1750
1740
  ) : from;
1751
- const endArrow = hasTargetArrow ? createRotatedPoint(
1752
- {
1753
- x: to.x - arrowLength,
1754
- y: to.y
1755
- },
1756
- toDir,
1757
- to
1758
- ) : to;
1741
+ const endArrow = hasTargetArrow ? createRotatedPoint({ x: to.x - arrowLength, y: to.y }, toDir, to) : to;
1759
1742
  const gap = arrowLength + arrowOffset;
1760
1743
  const beginLine = createRotatedPoint(
1761
1744
  { x: from.x + gap, y: from.y },
@@ -1764,21 +1747,10 @@ class VerticalEdgePath {
1764
1747
  );
1765
1748
  const endLine = createRotatedPoint({ x: to.x - gap, y: to.y }, toDir, to);
1766
1749
  const line = createLine(
1767
- {
1768
- x: beginLine.x,
1769
- y: beginLine.y,
1770
- dirY: fromDir.y
1771
- },
1772
- {
1773
- x: endLine.x,
1774
- y: endLine.y,
1775
- dirY: toDir.y
1776
- }
1777
- );
1778
- this.path = createRoundedPath(
1779
- [beginArrow, ...line.points, endArrow],
1780
- roundness
1750
+ { arrowPoint: beginArrow, linePoint: beginLine, dirY: fromDir.y },
1751
+ { arrowPoint: endArrow, linePoint: endLine, dirY: toDir.y }
1781
1752
  );
1753
+ this.path = createRoundedPath(line.points, roundness);
1782
1754
  this.midpoint = line.midpoint;
1783
1755
  }
1784
1756
  }
@@ -2293,6 +2265,9 @@ class BezierEdgeShape {
2293
2265
  this.pathShape.render(params);
2294
2266
  }
2295
2267
  }
2268
+ const horizontalizeDirection = (direction) => {
2269
+ return Math.cos(direction) > 0 ? 0 : Math.PI;
2270
+ };
2296
2271
  class HorizontalEdgeShape {
2297
2272
  constructor(params) {
2298
2273
  __publicField(this, "svg");
@@ -2373,7 +2348,18 @@ class HorizontalEdgeShape {
2373
2348
  this.onAfterRender = this.pathShape.onAfterRender;
2374
2349
  }
2375
2350
  render(params) {
2376
- this.pathShape.render(params);
2351
+ const { from, to, category } = params;
2352
+ this.pathShape.render({
2353
+ category,
2354
+ from: {
2355
+ ...from,
2356
+ direction: horizontalizeDirection(from.direction)
2357
+ },
2358
+ to: {
2359
+ ...to,
2360
+ direction: horizontalizeDirection(to.direction)
2361
+ }
2362
+ });
2377
2363
  }
2378
2364
  }
2379
2365
  class StraightEdgeShape {
@@ -2462,6 +2448,10 @@ class StraightEdgeShape {
2462
2448
  this.pathShape.render(params);
2463
2449
  }
2464
2450
  }
2451
+ const pi2 = Math.PI / 2;
2452
+ const verticalizeDirection = (direction) => {
2453
+ return Math.sin(direction) > 0 ? pi2 : -pi2;
2454
+ };
2465
2455
  class VerticalEdgeShape {
2466
2456
  constructor(params) {
2467
2457
  __publicField(this, "svg");
@@ -2542,7 +2532,18 @@ class VerticalEdgeShape {
2542
2532
  this.onAfterRender = this.pathShape.onAfterRender;
2543
2533
  }
2544
2534
  render(params) {
2545
- this.pathShape.render(params);
2535
+ const { from, to, category } = params;
2536
+ this.pathShape.render({
2537
+ category,
2538
+ from: {
2539
+ ...from,
2540
+ direction: verticalizeDirection(from.direction)
2541
+ },
2542
+ to: {
2543
+ ...to,
2544
+ direction: verticalizeDirection(to.direction)
2545
+ }
2546
+ });
2546
2547
  }
2547
2548
  }
2548
2549
  class DirectEdgeShape {
@@ -2690,7 +2691,7 @@ class InteractiveEdgeShape {
2690
2691
  // TODO: make private
2691
2692
  /**
2692
2693
  * @deprecated
2693
- * do use shape.svg instead
2694
+ * use shape.svg instead
2694
2695
  */
2695
2696
  __publicField(this, "handle", createEdgeGroup());
2696
2697
  __publicField(this, "onAfterRender");
@@ -3229,13 +3230,11 @@ class ViewportController {
3229
3230
  start = timestamp;
3230
3231
  }
3231
3232
  const progress = Math.min((timestamp - start) / duration, 1);
3232
- if (progress <= 1) {
3233
- this.viewportStore.patchViewportMatrix({
3234
- scale: previousViewportMatrix.scale + progress * deltaMatrix.scale,
3235
- x: previousViewportMatrix.x + progress * deltaMatrix.x,
3236
- y: previousViewportMatrix.y + progress * deltaMatrix.y
3237
- });
3238
- }
3233
+ this.viewportStore.patchViewportMatrix({
3234
+ scale: previousViewportMatrix.scale + progress * deltaMatrix.scale,
3235
+ x: previousViewportMatrix.x + progress * deltaMatrix.x,
3236
+ y: previousViewportMatrix.y + progress * deltaMatrix.y
3237
+ });
3239
3238
  if (progress < 1) {
3240
3239
  this.win.requestAnimationFrame(step);
3241
3240
  }
@@ -3591,7 +3590,7 @@ const resolveCreateEdgeRequest = (params, targetPortId) => {
3591
3590
  to: params.isDirect ? targetPortId : params.staticPortId
3592
3591
  };
3593
3592
  };
3594
- class ClosestConnectablePortDraggingPortDirectionResolver {
3593
+ class NearestConnectablePortDraggingPortDirectionResolver {
3595
3594
  constructor(graph, connectionAllowedVerifier) {
3596
3595
  this.graph = graph;
3597
3596
  this.connectionAllowedVerifier = connectionAllowedVerifier;
@@ -4432,13 +4431,16 @@ class UserConnectablePortsConfigurator {
4432
4431
  staticPortId,
4433
4432
  isDirect
4434
4433
  };
4434
+ const resolvedDirection = this.params.draggingPortDirectionResolver.resolve(
4435
+ {
4436
+ cursor,
4437
+ ...this.edgeInProgress
4438
+ }
4439
+ );
4435
4440
  const draggingParams = {
4436
4441
  overlayNodeId: OverlayId.DraggingNodeId,
4437
4442
  portCoords: cursorPoint,
4438
- portDirection: this.params.draggingPortDirectionResolver.resolve({
4439
- cursor,
4440
- ...this.edgeInProgress
4441
- }) ?? port.direction
4443
+ portDirection: resolvedDirection ?? port.direction
4442
4444
  };
4443
4445
  const [sourceParams, targetParams] = isDirect ? [staticParams, draggingParams] : [draggingParams, staticParams];
4444
4446
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(sourceParams));
@@ -4592,14 +4594,16 @@ class UserDraggableEdgesConfigurator {
4592
4594
  portCoords: staticPoint,
4593
4595
  portDirection: staticPort.direction
4594
4596
  };
4595
- const direction = this.params.draggingPortDirectionResolver.resolve({
4596
- cursor,
4597
- ...this.edgeInProgress
4598
- });
4597
+ const resolvedDirection = this.params.draggingPortDirectionResolver.resolve(
4598
+ {
4599
+ cursor,
4600
+ ...this.edgeInProgress
4601
+ }
4602
+ );
4599
4603
  const draggingParams = {
4600
4604
  overlayNodeId: OverlayId.DraggingNodeId,
4601
4605
  portCoords: draggingPoint,
4602
- portDirection: direction ?? draggingPort.direction
4606
+ portDirection: resolvedDirection ?? draggingPort.direction
4603
4607
  };
4604
4608
  const [sourceParams, targetParams] = isDirect ? [staticParams, draggingParams] : [draggingParams, staticParams];
4605
4609
  this.overlayCanvas.addNode(createAddNodeOverlayRequest(sourceParams));
@@ -5046,7 +5050,13 @@ const noopFn = () => {
5046
5050
  };
5047
5051
  const resolveDraggingPortDirectionResolver = (config, graph, connectionAllowedVerifier) => {
5048
5052
  if (config === "closest-connectable-port") {
5049
- return new ClosestConnectablePortDraggingPortDirectionResolver(
5053
+ return new NearestConnectablePortDraggingPortDirectionResolver(
5054
+ graph,
5055
+ connectionAllowedVerifier
5056
+ );
5057
+ }
5058
+ if (config === "nearest-connectable-port") {
5059
+ return new NearestConnectablePortDraggingPortDirectionResolver(
5050
5060
  graph,
5051
5061
  connectionAllowedVerifier
5052
5062
  );
@@ -6417,6 +6427,7 @@ const resolveAnimatedLayoutAlgorithm = (config) => {
6417
6427
  nodeMass: (config == null ? void 0 : config.nodeMass) ?? forceDirectedDefaults.nodeMass,
6418
6428
  edgeEquilibriumLength: (config == null ? void 0 : config.edgeEquilibriumLength) ?? forceDirectedDefaults.edgeEquilibriumLength,
6419
6429
  edgeStiffness: (config == null ? void 0 : config.edgeStiffness) ?? forceDirectedDefaults.edgeStiffness,
6430
+ // TODO: rename no `minVelocity`
6420
6431
  convergenceVelocity: (config == null ? void 0 : config.convergenceVelocity) ?? forceDirectedDefaults.convergenceVelocity,
6421
6432
  maxForce: (config == null ? void 0 : config.maxForce) ?? forceDirectedDefaults.maxForce,
6422
6433
  nodeForceCoefficient: (config == null ? void 0 : config.nodeForceCoefficient) ?? forceDirectedDefaults.nodeForceCoefficient,
@@ -6446,6 +6457,12 @@ const resolveLayoutApplyOn = (applyOn) => {
6446
6457
  trigger: applyOn
6447
6458
  };
6448
6459
  }
6460
+ if (applyOn === "topologyChangeMicrotask") {
6461
+ return {
6462
+ type: "topologyChangeSchedule",
6463
+ schedule: microtaskScheduleFn
6464
+ };
6465
+ }
6449
6466
  if ((applyOn == null ? void 0 : applyOn.type) === "topologyChangeMacrotask") {
6450
6467
  return {
6451
6468
  type: "topologyChangeSchedule",