@cardenelabs/cdl 0.123.0 → 0.124.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.
- package/CHANGELOG.md +13 -1
- package/README.md +6 -1
- package/dist/index.cjs +60 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +60 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +60 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +60 -1
- package/dist/react.js.map +1 -1
- package/dist/{render-CVczwfRb.d.cts → render-U6omSNH2.d.cts} +3 -2
- package/dist/{render-CVczwfRb.d.ts → render-U6omSNH2.d.ts} +3 -2
- package/package.json +1 -1
- package/src/layout/edges.ts +103 -4
- package/src/types.ts +3 -2
package/dist/react.cjs
CHANGED
|
@@ -9107,6 +9107,55 @@ function bowSharedStraightPaths(edges, nodes, skipIds, textMetrics = "proportion
|
|
|
9107
9107
|
function nodeRect(n) {
|
|
9108
9108
|
return { x: n.cx - n.w / 2, y: n.cy - n.h / 2, w: n.w, h: n.h };
|
|
9109
9109
|
}
|
|
9110
|
+
function countPathObstacleCrossings(d, obstacles) {
|
|
9111
|
+
const segments = flattenPathSegments(extractPathSegments(d));
|
|
9112
|
+
return obstacles.filter((obstacle) => segmentsCrossRect(segments, nodeRect(obstacle))).length;
|
|
9113
|
+
}
|
|
9114
|
+
function makeBackDetourCandidate(A, B, from, to, obstacles, detourY, side) {
|
|
9115
|
+
const lowIsA = A.y >= B.y;
|
|
9116
|
+
const low = lowIsA ? A : B;
|
|
9117
|
+
const lowBendY = low.y - VERTICAL_DETOUR_EXIT;
|
|
9118
|
+
const bandTop = Math.min(detourY, lowBendY);
|
|
9119
|
+
const bandBottom = Math.max(detourY, lowBendY);
|
|
9120
|
+
const bandObstacles = obstacles.map(nodeRect).filter((rect) => rect.y + rect.h >= bandTop && rect.y <= bandBottom);
|
|
9121
|
+
let columnX = detourColumnFor([from, to], side);
|
|
9122
|
+
while (true) {
|
|
9123
|
+
const blockers = bandObstacles.filter(
|
|
9124
|
+
(rect) => rect.x - VERTICAL_DETOUR_GAP < columnX && columnX < rect.x + rect.w + VERTICAL_DETOUR_GAP
|
|
9125
|
+
);
|
|
9126
|
+
if (blockers.length === 0) break;
|
|
9127
|
+
columnX = side === "left" ? Math.min(...blockers.map((rect) => rect.x - VERTICAL_DETOUR_GAP)) : Math.max(...blockers.map((rect) => rect.x + rect.w + VERTICAL_DETOUR_GAP));
|
|
9128
|
+
}
|
|
9129
|
+
const bendAY = lowIsA ? lowBendY : detourY;
|
|
9130
|
+
const bendBY = lowIsA ? detourY : lowBendY;
|
|
9131
|
+
const vertices = [
|
|
9132
|
+
A,
|
|
9133
|
+
{ x: A.x, y: bendAY },
|
|
9134
|
+
{ x: columnX, y: bendAY },
|
|
9135
|
+
{ x: columnX, y: bendBY },
|
|
9136
|
+
{ x: B.x, y: bendBY },
|
|
9137
|
+
B
|
|
9138
|
+
];
|
|
9139
|
+
const d = verticesToPath(vertices);
|
|
9140
|
+
const high = lowIsA ? B : A;
|
|
9141
|
+
return {
|
|
9142
|
+
d,
|
|
9143
|
+
labelX: (high.x + columnX) / 2,
|
|
9144
|
+
crossings: countPathObstacleCrossings(d, obstacles),
|
|
9145
|
+
length: vertices.slice(1).reduce((sum, vertex, index) => {
|
|
9146
|
+
const previous = vertices[index];
|
|
9147
|
+
return sum + Math.hypot(vertex.x - previous.x, vertex.y - previous.y);
|
|
9148
|
+
}, 0)
|
|
9149
|
+
};
|
|
9150
|
+
}
|
|
9151
|
+
function chooseBackDetourCandidate(A, B, from, to, obstacles, detourY) {
|
|
9152
|
+
const left = makeBackDetourCandidate(A, B, from, to, obstacles, detourY, "left");
|
|
9153
|
+
const right = makeBackDetourCandidate(A, B, from, to, obstacles, detourY, "right");
|
|
9154
|
+
if (left.crossings !== right.crossings) return left.crossings < right.crossings ? left : right;
|
|
9155
|
+
if (Math.abs(left.length - right.length) >= 0.5) return left.length < right.length ? left : right;
|
|
9156
|
+
const preferred = Math.abs(A.x - B.x) < 0.5 ? "right" : A.x < B.x ? "left" : "right";
|
|
9157
|
+
return preferred === "left" ? left : right;
|
|
9158
|
+
}
|
|
9110
9159
|
function rectGap(a, b) {
|
|
9111
9160
|
const dx = Math.max(0, a.x - (b.x + b.w), b.x - (a.x + a.w));
|
|
9112
9161
|
const dy = Math.max(0, a.y - (b.y + b.h), b.y - (a.y + a.h));
|
|
@@ -9557,7 +9606,7 @@ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _from
|
|
|
9557
9606
|
const detourY = Math.min(A.y, B.y) - 100;
|
|
9558
9607
|
const corner = 14;
|
|
9559
9608
|
const xDir = B.x > A.x ? 1 : -1;
|
|
9560
|
-
|
|
9609
|
+
const existing = {
|
|
9561
9610
|
d: `M ${A.x} ${A.y}
|
|
9562
9611
|
L ${A.x} ${detourY + corner}
|
|
9563
9612
|
Q ${A.x} ${detourY}, ${A.x + xDir * corner} ${detourY}
|
|
@@ -9571,6 +9620,16 @@ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _from
|
|
|
9571
9620
|
labelY: detourY - labelInit,
|
|
9572
9621
|
labelAnchor: "middle"
|
|
9573
9622
|
};
|
|
9623
|
+
const existingCrossings = countPathObstacleCrossings(existing.d, obstacles);
|
|
9624
|
+
if (existingCrossings === 0) return existing;
|
|
9625
|
+
const candidate = chooseBackDetourCandidate(A, B, from, to, obstacles, detourY);
|
|
9626
|
+
if (candidate.crossings >= existingCrossings) return existing;
|
|
9627
|
+
return {
|
|
9628
|
+
d: candidate.d,
|
|
9629
|
+
labelX: candidate.labelX,
|
|
9630
|
+
labelY: detourY - labelInit,
|
|
9631
|
+
labelAnchor: "middle"
|
|
9632
|
+
};
|
|
9574
9633
|
}
|
|
9575
9634
|
const midX = fromSide === "left" || fromSide === "right" ? B.x : A.x;
|
|
9576
9635
|
const midY = fromSide === "top" || fromSide === "bottom" ? B.y : A.y;
|