@crazyhappyone/auto-graph 0.2.9 → 0.2.11
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/cli/index.cjs +201 -38
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +201 -38
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +201 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +201 -38
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5384,7 +5384,7 @@ function segmentCrossesAnyObstacle(a, b, obstacles) {
|
|
|
5384
5384
|
}
|
|
5385
5385
|
|
|
5386
5386
|
// src/routing/routes.ts
|
|
5387
|
-
function checkBacktracking(points, source, target, diagnostics) {
|
|
5387
|
+
function checkBacktracking(points, source, target, diagnostics, maxRatio) {
|
|
5388
5388
|
if (points.length < 2) return;
|
|
5389
5389
|
const direct = Math.hypot(target.x - source.x, target.y - source.y);
|
|
5390
5390
|
if (direct <= 0) return;
|
|
@@ -5394,7 +5394,7 @@ function checkBacktracking(points, source, target, diagnostics) {
|
|
|
5394
5394
|
const b = points[i + 1];
|
|
5395
5395
|
routeLen += Math.hypot(b.x - a.x, b.y - a.y);
|
|
5396
5396
|
}
|
|
5397
|
-
const threshold =
|
|
5397
|
+
const threshold = maxRatio ?? 20;
|
|
5398
5398
|
if (routeLen > direct * threshold) {
|
|
5399
5399
|
diagnostics.push({
|
|
5400
5400
|
severity: "warning",
|
|
@@ -5412,8 +5412,20 @@ function routeEdge(input) {
|
|
|
5412
5412
|
const diagnostics = [];
|
|
5413
5413
|
const softObstacles = input.obstacles ?? [];
|
|
5414
5414
|
const hardObstacles = input.hardObstacles ?? [];
|
|
5415
|
+
let bestRejectedPath;
|
|
5416
|
+
let bestRejectedCrossings = Number.POSITIVE_INFINITY;
|
|
5415
5417
|
const softObstacleIndex = input.obstacleIndex ?? createBoxSpatialIndex(indexedBoxes(softObstacles));
|
|
5416
5418
|
const hardObstacleIndex = input.hardObstacleIndex ?? createBoxSpatialIndex(indexedBoxes(hardObstacles));
|
|
5419
|
+
const recordRejected = (candidate) => {
|
|
5420
|
+
if (routeIntersectsObstacles(candidate, hardObstacles, hardObstacleIndex)) {
|
|
5421
|
+
return;
|
|
5422
|
+
}
|
|
5423
|
+
const crossings = countObstacleCrossings(candidate, softObstacles);
|
|
5424
|
+
if (crossings < bestRejectedCrossings) {
|
|
5425
|
+
bestRejectedCrossings = crossings;
|
|
5426
|
+
bestRejectedPath = candidate;
|
|
5427
|
+
}
|
|
5428
|
+
};
|
|
5417
5429
|
const maxAttempts = input.maxRoutingAttempts ?? 5;
|
|
5418
5430
|
const defaultAnchors = defaultAnchorsForGeometry(
|
|
5419
5431
|
input.source.box,
|
|
@@ -5473,13 +5485,14 @@ function routeEdge(input) {
|
|
|
5473
5485
|
targetAnchor
|
|
5474
5486
|
);
|
|
5475
5487
|
const allObstacles = [...softObstacles, ...hardObstacles];
|
|
5488
|
+
const corridorMargin = input.corridorMargin ?? 32;
|
|
5476
5489
|
const corridorObstacles = filterObstaclesByCorridor(
|
|
5477
5490
|
source,
|
|
5478
5491
|
target,
|
|
5479
5492
|
allObstacles,
|
|
5480
5493
|
[],
|
|
5481
5494
|
// endpointObstacles passed separately via options
|
|
5482
|
-
|
|
5495
|
+
corridorMargin
|
|
5483
5496
|
);
|
|
5484
5497
|
const cornerObstacles = corridorObstacles.length === 0 && allObstacles.length > 0 ? allObstacles : corridorObstacles;
|
|
5485
5498
|
let cornerPath = findCornerGraphPath(
|
|
@@ -5502,7 +5515,7 @@ function routeEdge(input) {
|
|
|
5502
5515
|
source,
|
|
5503
5516
|
target,
|
|
5504
5517
|
allObstacles,
|
|
5505
|
-
{ endpointObstacles, margin: 0 },
|
|
5518
|
+
{ endpointObstacles, margin: 0, corridorMargin },
|
|
5506
5519
|
diagnostics
|
|
5507
5520
|
);
|
|
5508
5521
|
if (path !== null && path.length >= 2) {
|
|
@@ -5519,9 +5532,16 @@ function routeEdge(input) {
|
|
|
5519
5532
|
softObstacles,
|
|
5520
5533
|
softObstacleIndex
|
|
5521
5534
|
) && !routeIntersectsObstacles(finalized, hardObstacles, hardObstacleIndex)) {
|
|
5522
|
-
checkBacktracking(
|
|
5535
|
+
checkBacktracking(
|
|
5536
|
+
finalized,
|
|
5537
|
+
source,
|
|
5538
|
+
target,
|
|
5539
|
+
diagnostics,
|
|
5540
|
+
input.maxBacktrackingRatio
|
|
5541
|
+
);
|
|
5523
5542
|
return { points: finalized, diagnostics };
|
|
5524
5543
|
}
|
|
5544
|
+
recordRejected(finalized);
|
|
5525
5545
|
if (cornerPath !== null) {
|
|
5526
5546
|
const fullCornerPath = cornerObstacles.length < allObstacles.length ? findCornerGraphPath(
|
|
5527
5547
|
source,
|
|
@@ -5548,15 +5568,22 @@ function routeEdge(input) {
|
|
|
5548
5568
|
hardObstacles,
|
|
5549
5569
|
hardObstacleIndex
|
|
5550
5570
|
)) {
|
|
5551
|
-
checkBacktracking(
|
|
5571
|
+
checkBacktracking(
|
|
5572
|
+
fullFinalized,
|
|
5573
|
+
source,
|
|
5574
|
+
target,
|
|
5575
|
+
diagnostics,
|
|
5576
|
+
input.maxBacktrackingRatio
|
|
5577
|
+
);
|
|
5552
5578
|
return { points: fullFinalized, diagnostics };
|
|
5553
5579
|
}
|
|
5580
|
+
recordRejected(fullFinalized);
|
|
5554
5581
|
}
|
|
5555
5582
|
const gridPath = findObstacleFreePath(
|
|
5556
5583
|
source,
|
|
5557
5584
|
target,
|
|
5558
5585
|
allObstacles,
|
|
5559
|
-
{ endpointObstacles, margin: 0 },
|
|
5586
|
+
{ endpointObstacles, margin: 0, corridorMargin },
|
|
5560
5587
|
diagnostics
|
|
5561
5588
|
);
|
|
5562
5589
|
if (gridPath !== null && gridPath.length >= 2) {
|
|
@@ -5577,9 +5604,16 @@ function routeEdge(input) {
|
|
|
5577
5604
|
hardObstacles,
|
|
5578
5605
|
hardObstacleIndex
|
|
5579
5606
|
)) {
|
|
5580
|
-
checkBacktracking(
|
|
5607
|
+
checkBacktracking(
|
|
5608
|
+
gridFinalized,
|
|
5609
|
+
source,
|
|
5610
|
+
target,
|
|
5611
|
+
diagnostics,
|
|
5612
|
+
input.maxBacktrackingRatio
|
|
5613
|
+
);
|
|
5581
5614
|
return { points: gridFinalized, diagnostics };
|
|
5582
5615
|
}
|
|
5616
|
+
recordRejected(gridFinalized);
|
|
5583
5617
|
}
|
|
5584
5618
|
}
|
|
5585
5619
|
}
|
|
@@ -5643,7 +5677,8 @@ function routeEdge(input) {
|
|
|
5643
5677
|
finalizedClean,
|
|
5644
5678
|
candidate.points[0],
|
|
5645
5679
|
candidate.points[candidate.points.length - 1],
|
|
5646
|
-
diagnostics
|
|
5680
|
+
diagnostics,
|
|
5681
|
+
input.maxBacktrackingRatio
|
|
5647
5682
|
);
|
|
5648
5683
|
return { points: finalizedClean, diagnostics };
|
|
5649
5684
|
}
|
|
@@ -5709,13 +5744,41 @@ function routeEdge(input) {
|
|
|
5709
5744
|
code: "routing.obstacle.unavoidable",
|
|
5710
5745
|
message: "No bounded orthogonal route candidate avoided all soft obstacles."
|
|
5711
5746
|
});
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5747
|
+
const finalizedSoftBest = finalizeRoute(
|
|
5748
|
+
bestPoints2,
|
|
5749
|
+
softObstacles,
|
|
5750
|
+
hardObstacles,
|
|
5751
|
+
diagnostics
|
|
5752
|
+
);
|
|
5753
|
+
let softFallback = finalizedSoftBest;
|
|
5754
|
+
if (bestRejectedPath !== void 0) {
|
|
5755
|
+
const finalizedRejected = finalizeRoute(
|
|
5756
|
+
bestRejectedPath,
|
|
5715
5757
|
softObstacles,
|
|
5716
5758
|
hardObstacles,
|
|
5717
5759
|
diagnostics
|
|
5718
|
-
)
|
|
5760
|
+
);
|
|
5761
|
+
const rejectedCrossings = countObstacleCrossings(
|
|
5762
|
+
finalizedRejected,
|
|
5763
|
+
softObstacles
|
|
5764
|
+
);
|
|
5765
|
+
const heuristicCrossings = countObstacleCrossings(
|
|
5766
|
+
finalizedSoftBest,
|
|
5767
|
+
softObstacles
|
|
5768
|
+
);
|
|
5769
|
+
if (rejectedCrossings < heuristicCrossings) {
|
|
5770
|
+
softFallback = finalizedRejected;
|
|
5771
|
+
}
|
|
5772
|
+
}
|
|
5773
|
+
checkBacktracking(
|
|
5774
|
+
softFallback,
|
|
5775
|
+
softFallback[0],
|
|
5776
|
+
softFallback[softFallback.length - 1],
|
|
5777
|
+
diagnostics,
|
|
5778
|
+
input.maxBacktrackingRatio
|
|
5779
|
+
);
|
|
5780
|
+
return {
|
|
5781
|
+
points: softFallback,
|
|
5719
5782
|
diagnostics
|
|
5720
5783
|
};
|
|
5721
5784
|
}
|
|
@@ -5747,6 +5810,22 @@ function routeEdge(input) {
|
|
|
5747
5810
|
maxAttempts
|
|
5748
5811
|
);
|
|
5749
5812
|
}
|
|
5813
|
+
if (bestRejectedPath !== void 0) {
|
|
5814
|
+
diagnostics.push({
|
|
5815
|
+
severity: "warning",
|
|
5816
|
+
code: "routing.obstacle.unavoidable",
|
|
5817
|
+
message: "Using A* route with minor soft-obstacle crossings to avoid hard evidence obstacles."
|
|
5818
|
+
});
|
|
5819
|
+
return {
|
|
5820
|
+
points: finalizeRoute(
|
|
5821
|
+
bestRejectedPath,
|
|
5822
|
+
softObstacles,
|
|
5823
|
+
hardObstacles,
|
|
5824
|
+
diagnostics
|
|
5825
|
+
),
|
|
5826
|
+
diagnostics
|
|
5827
|
+
};
|
|
5828
|
+
}
|
|
5750
5829
|
diagnostics.push({
|
|
5751
5830
|
severity: "error",
|
|
5752
5831
|
code: "routing.evidence.crossing_forbidden",
|
|
@@ -5794,13 +5873,41 @@ function routeEdge(input) {
|
|
|
5794
5873
|
code: "routing.obstacle.unavoidable",
|
|
5795
5874
|
message: "No bounded orthogonal route candidate avoided all obstacles."
|
|
5796
5875
|
});
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5876
|
+
const finalizedBestPoints = finalizeRoute(
|
|
5877
|
+
bestPoints,
|
|
5878
|
+
softObstacles,
|
|
5879
|
+
hardObstacles,
|
|
5880
|
+
diagnostics
|
|
5881
|
+
);
|
|
5882
|
+
let fallbackPoints = finalizedBestPoints;
|
|
5883
|
+
if (bestRejectedPath !== void 0) {
|
|
5884
|
+
const finalizedRejected = finalizeRoute(
|
|
5885
|
+
bestRejectedPath,
|
|
5800
5886
|
softObstacles,
|
|
5801
5887
|
hardObstacles,
|
|
5802
5888
|
diagnostics
|
|
5803
|
-
)
|
|
5889
|
+
);
|
|
5890
|
+
const rejectedCrossings = countObstacleCrossings(
|
|
5891
|
+
finalizedRejected,
|
|
5892
|
+
softObstacles
|
|
5893
|
+
);
|
|
5894
|
+
const heuristicCrossings = countObstacleCrossings(
|
|
5895
|
+
finalizedBestPoints,
|
|
5896
|
+
softObstacles
|
|
5897
|
+
);
|
|
5898
|
+
if (rejectedCrossings < heuristicCrossings) {
|
|
5899
|
+
fallbackPoints = finalizedRejected;
|
|
5900
|
+
}
|
|
5901
|
+
}
|
|
5902
|
+
checkBacktracking(
|
|
5903
|
+
fallbackPoints,
|
|
5904
|
+
fallbackPoints[0],
|
|
5905
|
+
fallbackPoints[fallbackPoints.length - 1],
|
|
5906
|
+
diagnostics,
|
|
5907
|
+
input.maxBacktrackingRatio
|
|
5908
|
+
);
|
|
5909
|
+
return {
|
|
5910
|
+
points: fallbackPoints,
|
|
5804
5911
|
diagnostics
|
|
5805
5912
|
};
|
|
5806
5913
|
}
|
|
@@ -6299,6 +6406,24 @@ function routeIntersectsObstacles(points, obstacles, spatialIndex) {
|
|
|
6299
6406
|
}
|
|
6300
6407
|
return false;
|
|
6301
6408
|
}
|
|
6409
|
+
function countObstacleCrossings(points, obstacles) {
|
|
6410
|
+
let count = 0;
|
|
6411
|
+
for (const obstacle of obstacles) {
|
|
6412
|
+
validateBox(obstacle);
|
|
6413
|
+
for (let pointIndex = 0; pointIndex < points.length - 1; pointIndex += 1) {
|
|
6414
|
+
const a = points[pointIndex];
|
|
6415
|
+
const b = points[pointIndex + 1];
|
|
6416
|
+
if (a === void 0 || b === void 0) {
|
|
6417
|
+
continue;
|
|
6418
|
+
}
|
|
6419
|
+
if (intersectsAabb(segmentBox2(a, b), obstacle)) {
|
|
6420
|
+
count += 1;
|
|
6421
|
+
break;
|
|
6422
|
+
}
|
|
6423
|
+
}
|
|
6424
|
+
}
|
|
6425
|
+
return count;
|
|
6426
|
+
}
|
|
6302
6427
|
function routeIntersectsEndpointInteriors(points, endpointInteriors) {
|
|
6303
6428
|
for (let index = 0; index < points.length - 1; index += 1) {
|
|
6304
6429
|
const a = points[index];
|
|
@@ -6744,7 +6869,8 @@ function solveDiagram(diagram, options = {}) {
|
|
|
6744
6869
|
constrained.boxes,
|
|
6745
6870
|
constrained.locks,
|
|
6746
6871
|
options?.overlapSpacing ?? 40,
|
|
6747
|
-
Math.max(0, options?.minLaneGutter ?? 0)
|
|
6872
|
+
Math.max(0, options?.minLaneGutter ?? 0),
|
|
6873
|
+
options.distributeContainedChildren ?? true
|
|
6748
6874
|
);
|
|
6749
6875
|
removeResolvedOverlapDiagnostics(diagnostics, constrained.boxes);
|
|
6750
6876
|
diagnostics.push(...swimlaneContracts.diagnostics);
|
|
@@ -6911,7 +7037,8 @@ function solveDiagram(diagram, options = {}) {
|
|
|
6911
7037
|
diagram.direction,
|
|
6912
7038
|
options,
|
|
6913
7039
|
diagnostics,
|
|
6914
|
-
coordinatedGroups
|
|
7040
|
+
coordinatedGroups,
|
|
7041
|
+
contentBounds
|
|
6915
7042
|
);
|
|
6916
7043
|
const edgeTextAnnotations = coordinateEdgeTextAnnotations(
|
|
6917
7044
|
coordinatedEdges,
|
|
@@ -7333,7 +7460,7 @@ function reportCjkTypographyDiagnostics(path, typography, previousStyle, diagnos
|
|
|
7333
7460
|
function containsCjk(value) {
|
|
7334
7461
|
return /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/u.test(value);
|
|
7335
7462
|
}
|
|
7336
|
-
function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottomFlow, nodeBoxes, locks, overlapSpacing, laneGutter) {
|
|
7463
|
+
function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottomFlow, nodeBoxes, locks, overlapSpacing, laneGutter, distributeContainedChildren) {
|
|
7337
7464
|
const layouts = /* @__PURE__ */ new Map();
|
|
7338
7465
|
const diagnostics = [];
|
|
7339
7466
|
const movedChildIds = /* @__PURE__ */ new Set();
|
|
@@ -7352,7 +7479,9 @@ function applySwimlaneLayoutContracts(swimlanes, constraints, edges, topToBottom
|
|
|
7352
7479
|
locks,
|
|
7353
7480
|
diagnostics,
|
|
7354
7481
|
movedChildIds,
|
|
7355
|
-
laneGutter
|
|
7482
|
+
laneGutter,
|
|
7483
|
+
constraints,
|
|
7484
|
+
distributeContainedChildren
|
|
7356
7485
|
);
|
|
7357
7486
|
if (layout2 !== void 0) {
|
|
7358
7487
|
layouts.set(swimlane.id, layout2);
|
|
@@ -7544,7 +7673,7 @@ function isStackRunaway(boxes, nodes, direction, options) {
|
|
|
7544
7673
|
const maxWidth = Math.max(...nodeBoxes.map((box) => box.width));
|
|
7545
7674
|
return xSpread <= Math.max(maxWidth, options.overlapSpacing ?? 40);
|
|
7546
7675
|
}
|
|
7547
|
-
function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, locks, diagnostics, movedChildIds, laneGutter) {
|
|
7676
|
+
function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, locks, diagnostics, movedChildIds, laneGutter, constraints, distributeContainedChildren) {
|
|
7548
7677
|
const headerHeight = swimlane.headerHeight ?? 28;
|
|
7549
7678
|
const padding = swimlane.padding ?? 16;
|
|
7550
7679
|
const laneBounds = swimlane.lanes.map((lane) => {
|
|
@@ -7569,7 +7698,9 @@ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes
|
|
|
7569
7698
|
locks,
|
|
7570
7699
|
diagnostics,
|
|
7571
7700
|
movedChildIds,
|
|
7572
|
-
laneGutter
|
|
7701
|
+
laneGutter,
|
|
7702
|
+
constraints,
|
|
7703
|
+
distributeContainedChildren
|
|
7573
7704
|
);
|
|
7574
7705
|
}
|
|
7575
7706
|
return applyHorizontalSwimlaneContract(
|
|
@@ -7584,13 +7715,29 @@ function applySingleSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes
|
|
|
7584
7715
|
laneGutter
|
|
7585
7716
|
);
|
|
7586
7717
|
}
|
|
7587
|
-
function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, laneBounds, headerHeight, padding, locks, diagnostics, movedChildIds, laneGutter) {
|
|
7718
|
+
function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBoxes, laneBounds, headerHeight, padding, locks, diagnostics, movedChildIds, laneGutter, constraints, distributeContainedChildren) {
|
|
7588
7719
|
const populatedBounds = laneBounds.filter(
|
|
7589
7720
|
(box) => box !== void 0
|
|
7590
7721
|
);
|
|
7591
7722
|
const top = Math.min(...populatedBounds.map((box) => box.y));
|
|
7592
7723
|
const left = Math.min(...populatedBounds.map((box) => box.x));
|
|
7593
7724
|
const maxChildHeight = Math.max(...populatedBounds.map((box) => box.height));
|
|
7725
|
+
const containedChildIds = /* @__PURE__ */ new Set();
|
|
7726
|
+
if (distributeContainedChildren) {
|
|
7727
|
+
for (const c of constraints) {
|
|
7728
|
+
if (c.kind !== "containment") continue;
|
|
7729
|
+
if (nodeBoxes.get(c.containerId) === void 0) continue;
|
|
7730
|
+
const distributable = c.childIds.filter((childId) => {
|
|
7731
|
+
if (nodeBoxes.get(childId) === void 0) return false;
|
|
7732
|
+
const lock = locks.get(childId);
|
|
7733
|
+
return lock === void 0 || lock.source === "fixed-position";
|
|
7734
|
+
});
|
|
7735
|
+
if (distributable.length < 2) continue;
|
|
7736
|
+
for (const childId of distributable) {
|
|
7737
|
+
containedChildIds.add(childId);
|
|
7738
|
+
}
|
|
7739
|
+
}
|
|
7740
|
+
}
|
|
7594
7741
|
const flowRanks = topToBottomFlow ? rankVerticalSwimlaneChildren(swimlane, edges) : /* @__PURE__ */ new Map();
|
|
7595
7742
|
const maxRank = flowRanks.size === 0 ? 0 : Math.max(...Array.from(flowRanks.values()));
|
|
7596
7743
|
const rankStackGap = Math.max(8, padding / 2);
|
|
@@ -7607,7 +7754,8 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
|
|
|
7607
7754
|
nodeBoxes,
|
|
7608
7755
|
flowRanks,
|
|
7609
7756
|
locks,
|
|
7610
|
-
rankStackGap
|
|
7757
|
+
rankStackGap,
|
|
7758
|
+
containedChildIds
|
|
7611
7759
|
);
|
|
7612
7760
|
const slotWidth = Math.max(
|
|
7613
7761
|
Math.max(...populatedBounds.map((box) => box.width)),
|
|
@@ -7629,7 +7777,10 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
|
|
|
7629
7777
|
const distributable = lane.children.filter(
|
|
7630
7778
|
(childId) => !locks.has(childId)
|
|
7631
7779
|
);
|
|
7632
|
-
|
|
7780
|
+
const coveredByContainment = lane.children.some(
|
|
7781
|
+
(childId) => containedChildIds.has(childId)
|
|
7782
|
+
);
|
|
7783
|
+
if (!coveredByContainment && distributable.length >= CROSS_AXIS_SPREAD_THRESHOLD) {
|
|
7633
7784
|
moveRankedVerticalLaneChildren(
|
|
7634
7785
|
lane.children,
|
|
7635
7786
|
nodeBoxes,
|
|
@@ -7657,6 +7808,9 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
|
|
|
7657
7808
|
);
|
|
7658
7809
|
continue;
|
|
7659
7810
|
}
|
|
7811
|
+
const rankedCoveredByContainment = lane.children.some(
|
|
7812
|
+
(childId) => containedChildIds.has(childId)
|
|
7813
|
+
);
|
|
7660
7814
|
moveRankedVerticalLaneChildren(
|
|
7661
7815
|
lane.children,
|
|
7662
7816
|
nodeBoxes,
|
|
@@ -7667,7 +7821,8 @@ function applyVerticalSwimlaneContract(swimlane, edges, topToBottomFlow, nodeBox
|
|
|
7667
7821
|
rankSpacing,
|
|
7668
7822
|
rankStackGap,
|
|
7669
7823
|
{ x: target.x, y: laneContentTop },
|
|
7670
|
-
slotWidth - padding * 2
|
|
7824
|
+
slotWidth - padding * 2,
|
|
7825
|
+
rankedCoveredByContainment
|
|
7671
7826
|
);
|
|
7672
7827
|
}
|
|
7673
7828
|
return {
|
|
@@ -7783,9 +7938,12 @@ function crossAxisSpreadWidth(items, gap) {
|
|
|
7783
7938
|
0
|
|
7784
7939
|
);
|
|
7785
7940
|
}
|
|
7786
|
-
function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap) {
|
|
7941
|
+
function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap, containedChildIds) {
|
|
7787
7942
|
let maxWidth = 0;
|
|
7788
7943
|
for (const lane of swimlane.lanes) {
|
|
7944
|
+
if (containedChildIds !== void 0 && lane.children.some((childId) => containedChildIds.has(childId))) {
|
|
7945
|
+
continue;
|
|
7946
|
+
}
|
|
7789
7947
|
for (const stack of rankStacks(
|
|
7790
7948
|
lane.children,
|
|
7791
7949
|
nodeBoxes,
|
|
@@ -7798,7 +7956,7 @@ function maxCrossAxisSpreadWidth(swimlane, nodeBoxes, flowRanks, locks, gap) {
|
|
|
7798
7956
|
}
|
|
7799
7957
|
return maxWidth;
|
|
7800
7958
|
}
|
|
7801
|
-
function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics, movedChildIds, flowRanks, rankSpacing, rankStackGap, target, contentWidth) {
|
|
7959
|
+
function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics, movedChildIds, flowRanks, rankSpacing, rankStackGap, target, contentWidth, suppressSpread) {
|
|
7802
7960
|
for (const [rank, stack] of rankStacks(childIds, nodeBoxes, flowRanks)) {
|
|
7803
7961
|
const unlocked = [];
|
|
7804
7962
|
for (const item of stack) {
|
|
@@ -7827,7 +7985,7 @@ function moveRankedVerticalLaneChildren(childIds, nodeBoxes, locks, diagnostics,
|
|
|
7827
7985
|
}
|
|
7828
7986
|
nodeBoxes.set(childId, next);
|
|
7829
7987
|
} else {
|
|
7830
|
-
const shouldSpread = unlocked.length >= CROSS_AXIS_SPREAD_THRESHOLD;
|
|
7988
|
+
const shouldSpread = !suppressSpread && unlocked.length >= CROSS_AXIS_SPREAD_THRESHOLD;
|
|
7831
7989
|
if (!shouldSpread) {
|
|
7832
7990
|
let yOffset = 0;
|
|
7833
7991
|
for (const { childId, box } of unlocked) {
|
|
@@ -8956,14 +9114,21 @@ function evidenceOverlapDiagnostic(block, conflict) {
|
|
|
8956
9114
|
}
|
|
8957
9115
|
};
|
|
8958
9116
|
}
|
|
8959
|
-
function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacles, textObstacles, hardObstacles, direction, options, diagnostics, groups) {
|
|
9117
|
+
function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacles, textObstacles, hardObstacles, direction, options, diagnostics, groups, contentBounds) {
|
|
8960
9118
|
const coordinated = [];
|
|
8961
9119
|
const coordinatedNodeById = new Map(
|
|
8962
9120
|
coordinatedNodes.map((node) => [node.id, node])
|
|
8963
9121
|
);
|
|
9122
|
+
const corridorMarginOption = options.corridorMargin ?? "auto";
|
|
9123
|
+
const corridorMargin = typeof corridorMarginOption === "number" ? corridorMarginOption : Math.max(
|
|
9124
|
+
200,
|
|
9125
|
+
Math.hypot(contentBounds.width, contentBounds.height) * 0.3
|
|
9126
|
+
);
|
|
9127
|
+
const routingGutter = options.routingGutter ?? 160;
|
|
9128
|
+
const queryGutter = (options.routeKind ?? "orthogonal") === "obstacle-avoiding" ? Math.max(routingGutter, corridorMargin) : routingGutter;
|
|
8964
9129
|
const nodeObstacleIndex = createBoxSpatialIndex(
|
|
8965
9130
|
obstacles.map((box, index) => ({ id: `node-obstacle:${index}`, box })),
|
|
8966
|
-
|
|
9131
|
+
queryGutter
|
|
8967
9132
|
);
|
|
8968
9133
|
for (const edge of edges) {
|
|
8969
9134
|
const source = nodes.get(edge.source.nodeId);
|
|
@@ -8985,11 +9150,7 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
|
|
|
8985
9150
|
const sourcePort = coordinatedNodeById.get(edge.source.nodeId)?.ports?.find((port) => port.id === edge.source.portId);
|
|
8986
9151
|
const targetPort = coordinatedNodeById.get(edge.target.nodeId)?.ports?.find((port) => port.id === edge.target.portId);
|
|
8987
9152
|
const routeTextObstacles = textObstacles.filter((annotation) => !isEdgeConnectedTextAnnotation(edge, annotation)).map((annotation) => annotation.box);
|
|
8988
|
-
const corridor = edgeCorridorBox(
|
|
8989
|
-
source.box,
|
|
8990
|
-
target.box,
|
|
8991
|
-
options.routingGutter ?? 160
|
|
8992
|
-
);
|
|
9153
|
+
const corridor = edgeCorridorBox(source.box, target.box, queryGutter);
|
|
8993
9154
|
const routeNodeObstacles = queryBoxSpatialIndex(nodeObstacleIndex, corridor).map((entry) => entry.box).filter(
|
|
8994
9155
|
(obstacle) => !sameBox(obstacle, source.obstacleBox) && !sameBox(obstacle, target.obstacleBox)
|
|
8995
9156
|
);
|
|
@@ -9007,7 +9168,9 @@ function coordinateEdges(edges, nodes, coordinatedNodes, obstacles, softObstacle
|
|
|
9007
9168
|
...routeTextObstacles
|
|
9008
9169
|
],
|
|
9009
9170
|
hardObstacles,
|
|
9010
|
-
|
|
9171
|
+
corridorMargin,
|
|
9172
|
+
...options.maxRoutingAttempts === void 0 ? {} : { maxRoutingAttempts: options.maxRoutingAttempts },
|
|
9173
|
+
...options.maxBacktrackingRatio === void 0 ? {} : { maxBacktrackingRatio: options.maxBacktrackingRatio }
|
|
9011
9174
|
});
|
|
9012
9175
|
diagnostics.push(
|
|
9013
9176
|
...route.diagnostics.map((diagnostic) => ({
|