@cardenelabs/cdl 0.29.0 → 0.30.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 +54 -1
- package/dist/index.cjs +132 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +132 -12
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +132 -12
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +132 -12
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/layout/edges.ts +167 -13
- package/src/layout.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -19673,16 +19673,112 @@ function separateSharedStraightRuns(edges, nodes) {
|
|
|
19673
19673
|
e.d = verticesToPath(verts.get(e.id));
|
|
19674
19674
|
}
|
|
19675
19675
|
}
|
|
19676
|
+
function pullOutgoingFirstCorner(edges, nodes) {
|
|
19677
|
+
if (edges.length < 2) return;
|
|
19678
|
+
const \u675F = /* @__PURE__ */ new Map();
|
|
19679
|
+
const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
|
|
19680
|
+
for (const e of edges) {
|
|
19681
|
+
const key = `${e.from}::${e.fromSide}`;
|
|
19682
|
+
const list = \u675F.get(key) ?? [];
|
|
19683
|
+
list.push(e);
|
|
19684
|
+
\u675F.set(key, list);
|
|
19685
|
+
const pair = `${e.from}->${e.to}`;
|
|
19686
|
+
\u540C\u3058\u7D44\u306E\u6570.set(pair, (\u540C\u3058\u7D44\u306E\u6570.get(pair) ?? 0) + 1);
|
|
19687
|
+
}
|
|
19688
|
+
let \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = false;
|
|
19689
|
+
for (const list of \u675F.values()) {
|
|
19690
|
+
if (list.length < 2) continue;
|
|
19691
|
+
const \u4E26\u3073 = list.flatMap((e) => {
|
|
19692
|
+
const pts = pathVertices(e.d);
|
|
19693
|
+
if (!pts || pts.length < 2) return [];
|
|
19694
|
+
return [{ e, pts, \u6700\u521D\u306E\u9577\u3055: Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y) }];
|
|
19695
|
+
}).sort((a, b) => b.\u6700\u521D\u306E\u9577\u3055 - a.\u6700\u521D\u306E\u9577\u3055);
|
|
19696
|
+
for (const { e, pts, \u6700\u521D\u306E\u9577\u3055 } of \u4E26\u3073.slice(1)) {
|
|
19697
|
+
if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
|
|
19698
|
+
if (pts.length < 3 || \u6700\u521D\u306E\u9577\u3055 <= EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER) continue;
|
|
19699
|
+
const \u6A2A = e.fromSide === "left" || e.fromSide === "right";
|
|
19700
|
+
if (!runIsAligned(pts, 0, \u6A2A ? 1 : 0)) continue;
|
|
19701
|
+
const \u79FB\u52D5\u91CF = \u6700\u521D\u306E\u9577\u3055 - (EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER);
|
|
19702
|
+
const ux = (pts[1].x - pts[0].x) / \u6700\u521D\u306E\u9577\u3055;
|
|
19703
|
+
const uy = (pts[1].y - pts[0].y) / \u6700\u521D\u306E\u9577\u3055;
|
|
19704
|
+
const \u8A66\u3057 = pts.map(
|
|
19705
|
+
(p, i) => i === 1 || i === 2 ? { x: p.x - ux * \u79FB\u52D5\u91CF, y: p.y - uy * \u79FB\u52D5\u91CF } : p
|
|
19706
|
+
);
|
|
19707
|
+
const \u8A66\u3057D = verticesToPath(\u8A66\u3057);
|
|
19708
|
+
const \u8A66\u3057\u533A\u9593 = flattenPathSegments(extractPathSegments(\u8A66\u3057D));
|
|
19709
|
+
if (nodes.some(
|
|
19710
|
+
(n) => n.id !== e.from && n.id !== e.to && segmentsCrossRect(\u8A66\u3057\u533A\u9593, nodeRect(n))
|
|
19711
|
+
)) {
|
|
19712
|
+
continue;
|
|
19713
|
+
}
|
|
19714
|
+
const \u524D = e.d;
|
|
19715
|
+
const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
|
|
19716
|
+
e.d = \u8A66\u3057D;
|
|
19717
|
+
if (countEdgeCrossings(edges).count > \u524D\u306E\u4EA4\u5DEE) {
|
|
19718
|
+
e.d = \u524D;
|
|
19719
|
+
continue;
|
|
19720
|
+
}
|
|
19721
|
+
e.d = \u524D;
|
|
19722
|
+
if (!\u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F) {
|
|
19723
|
+
slideLabelsAlongOwnPath(edges, nodes);
|
|
19724
|
+
\u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = true;
|
|
19725
|
+
}
|
|
19726
|
+
const labelBox = computeLabelBBoxWorld(e);
|
|
19727
|
+
const label = { x: labelBox.x + labelBox.w / 2, y: labelBox.y + labelBox.h / 2 };
|
|
19728
|
+
const \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22 = (a, b) => {
|
|
19729
|
+
const dx = b.x - a.x;
|
|
19730
|
+
const dy = b.y - a.y;
|
|
19731
|
+
const len2 = dx * dx + dy * dy;
|
|
19732
|
+
const t = len2 === 0 ? 0 : Math.max(0, Math.min(1, ((label.x - a.x) * dx + (label.y - a.y) * dy) / len2));
|
|
19733
|
+
return (label.x - (a.x + dx * t)) ** 2 + (label.y - (a.y + dy * t)) ** 2;
|
|
19734
|
+
};
|
|
19735
|
+
const \u52D5\u304F\u533A\u9593\u3078\u306E\u8DDD\u96E2 = \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22(pts[1], pts[2]);
|
|
19736
|
+
const label\u3082\u52D5\u304B\u3059 = pts.slice(0, -1).every((p, i) => \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22(p, pts[i + 1]) >= \u52D5\u304F\u533A\u9593\u3078\u306E\u8DDD\u96E2 - 1e-6);
|
|
19737
|
+
e.d = \u8A66\u3057D;
|
|
19738
|
+
if (label\u3082\u52D5\u304B\u3059) {
|
|
19739
|
+
e.labelX -= ux * \u79FB\u52D5\u91CF;
|
|
19740
|
+
e.labelY -= uy * \u79FB\u52D5\u91CF;
|
|
19741
|
+
}
|
|
19742
|
+
}
|
|
19743
|
+
}
|
|
19744
|
+
}
|
|
19676
19745
|
var ENDPOINT_FAN_STEP = 56;
|
|
19677
19746
|
var ENDPOINT_FAN_MIN = 20;
|
|
19678
19747
|
var ENDPOINT_FAN_RUNUP = 40;
|
|
19748
|
+
var MIXED_ROOT_OVERLAP_MIN = 24;
|
|
19679
19749
|
function fanIncomingEndpoints(edges, nodes) {
|
|
19680
19750
|
if (edges.length < 2) return;
|
|
19681
19751
|
const nmap = new Map(nodes.map((n) => [n.id, n]));
|
|
19752
|
+
const \u5E73\u5766\u306A\u533A\u9593 = new Map(edges.map((e) => [e.id, flattenPathSegments(extractPathSegments(e.d))]));
|
|
19753
|
+
const \u8EF8\u306B\u5E73\u884C\u306A\u91CD\u306A\u308A\u9577\u3055 = (\u4E00\u65B9, \u4ED6\u65B9) => {
|
|
19754
|
+
let \u5408\u8A08 = 0;
|
|
19755
|
+
for (const a of \u5E73\u5766\u306A\u533A\u9593.get(\u4E00\u65B9.id) ?? []) {
|
|
19756
|
+
const a\u306F\u6C34\u5E73 = Math.abs(a.y2 - a.y1) <= 1;
|
|
19757
|
+
const a\u306F\u5782\u76F4 = Math.abs(a.x2 - a.x1) <= 1;
|
|
19758
|
+
for (const b of \u5E73\u5766\u306A\u533A\u9593.get(\u4ED6\u65B9.id) ?? []) {
|
|
19759
|
+
const b\u306F\u6C34\u5E73 = Math.abs(b.y2 - b.y1) <= 1;
|
|
19760
|
+
const b\u306F\u5782\u76F4 = Math.abs(b.x2 - b.x1) <= 1;
|
|
19761
|
+
if (a\u306F\u6C34\u5E73 && b\u306F\u6C34\u5E73 && Math.abs(a.y1 - b.y1) <= 1) {
|
|
19762
|
+
\u5408\u8A08 += Math.max(0, Math.min(Math.max(a.x1, a.x2), Math.max(b.x1, b.x2)) - Math.max(Math.min(a.x1, a.x2), Math.min(b.x1, b.x2)));
|
|
19763
|
+
}
|
|
19764
|
+
if (a\u306F\u5782\u76F4 && b\u306F\u5782\u76F4 && Math.abs(a.x1 - b.x1) <= 1) {
|
|
19765
|
+
\u5408\u8A08 += Math.max(0, Math.min(Math.max(a.y1, a.y2), Math.max(b.y1, b.y2)) - Math.max(Math.min(a.y1, a.y2), Math.min(b.y1, b.y2)));
|
|
19766
|
+
}
|
|
19767
|
+
}
|
|
19768
|
+
}
|
|
19769
|
+
return \u5408\u8A08;
|
|
19770
|
+
};
|
|
19682
19771
|
const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
|
|
19683
19772
|
for (const e of edges) \u540C\u3058\u7D44\u306E\u6570.set(`${e.from}->${e.to}`, (\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) + 1);
|
|
19684
19773
|
const \u675F = /* @__PURE__ */ new Map();
|
|
19774
|
+
const \u51FA\u308B\u7DDA = /* @__PURE__ */ new Map();
|
|
19685
19775
|
for (const e of edges) {
|
|
19776
|
+
if (nmap.has(e.from)) {
|
|
19777
|
+
const key2 = `${e.from}::${e.fromSide}`;
|
|
19778
|
+
const list2 = \u51FA\u308B\u7DDA.get(key2) ?? [];
|
|
19779
|
+
list2.push(e);
|
|
19780
|
+
\u51FA\u308B\u7DDA.set(key2, list2);
|
|
19781
|
+
}
|
|
19686
19782
|
if (!nmap.has(e.to)) continue;
|
|
19687
19783
|
if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
|
|
19688
19784
|
const key = `${e.to}::${e.toSide}`;
|
|
@@ -19690,27 +19786,48 @@ function fanIncomingEndpoints(edges, nodes) {
|
|
|
19690
19786
|
list.push(e);
|
|
19691
19787
|
\u675F.set(key, list);
|
|
19692
19788
|
}
|
|
19693
|
-
for (const [, list] of \u675F) {
|
|
19694
|
-
|
|
19789
|
+
for (const [key, list] of \u675F) {
|
|
19790
|
+
const \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B = (\u51FA\u308B\u7DDA.get(key) ?? []).some(
|
|
19791
|
+
(\u51FA\u7DDA) => list.some(
|
|
19792
|
+
(\u5165\u7DDA) => !(\u5165\u7DDA.from === \u51FA\u7DDA.to && \u5165\u7DDA.to === \u51FA\u7DDA.from) && \u8EF8\u306B\u5E73\u884C\u306A\u91CD\u306A\u308A\u9577\u3055(\u5165\u7DDA, \u51FA\u7DDA) >= MIXED_ROOT_OVERLAP_MIN
|
|
19793
|
+
)
|
|
19794
|
+
);
|
|
19795
|
+
if (list.length < 2 && !\u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B) continue;
|
|
19695
19796
|
const n = nmap.get(list[0].to);
|
|
19696
19797
|
const \u6A2A = list[0].toSide === "left" || list[0].toSide === "right";
|
|
19697
19798
|
const \u8FBA\u306E\u9577\u3055 = \u6A2A ? n.h : n.w;
|
|
19698
19799
|
const \u4F7F\u3048\u308B\u5E452 = \u8FBA\u306E\u9577\u3055 - 2 * ARROW_ENDPOINT_CENTER_TOL;
|
|
19699
19800
|
if (\u4F7F\u3048\u308B\u5E452 <= 0) continue;
|
|
19700
|
-
const \u9593
|
|
19801
|
+
const \u5E2D\u306E\u9593 = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B ? list.length : list.length - 1;
|
|
19802
|
+
const \u9593\u9694 = Math.min(ENDPOINT_FAN_STEP, \u4F7F\u3048\u308B\u5E452 / \u5E2D\u306E\u9593);
|
|
19701
19803
|
if (\u9593\u9694 < ENDPOINT_FAN_MIN) continue;
|
|
19702
|
-
const \
|
|
19804
|
+
const \u8FBA\u306E\u4E2D\u5FC3 = \u6A2A ? n.cy : n.cx;
|
|
19805
|
+
const \u4E26\u3073 = list.map((e) => {
|
|
19806
|
+
const \u533A\u9593 = extractPathSegments(e.d);
|
|
19807
|
+
const last = \u533A\u9593[\u533A\u9593.length - 1];
|
|
19808
|
+
const \u9577\u3044\u52A9\u8D70 = last === void 0 ? 0 : Math.hypot(last.x2 - last.x1, last.y2 - last.y1);
|
|
19809
|
+
const \u4E2D\u5FC3\u3092\u88DC\u3046 = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B || list.length === 2;
|
|
19810
|
+
const \u6DF1\u3055 = \u8FBA\u304B\u3089\u96E2\u308C\u305F\u5074\u306E\u4F4D\u7F6E(e, \u6A2A) ?? (\u4E2D\u5FC3\u3092\u88DC\u3046 ? \u8FBA\u306E\u4E2D\u5FC3 : 0);
|
|
19811
|
+
return { e, \u9577\u3044\u52A9\u8D70, \u6DF1\u3055 };
|
|
19812
|
+
}).sort((a, b) => a.\u6DF1\u3055 - b.\u6DF1\u3055 || (a.e.id < b.e.id ? -1 : 1));
|
|
19703
19813
|
const \u4E2D\u5FC3 = (\u4E26\u3073.length - 1) * \u9593\u9694 / 2;
|
|
19814
|
+
let \u8CA0\u5074\u306E\u5E2D = 0;
|
|
19815
|
+
let \u6B63\u5074\u306E\u5E2D = 0;
|
|
19704
19816
|
for (let k = 0; k < \u4E26\u3073.length; k++) {
|
|
19705
|
-
const d = k * \u9593\u9694 - \u4E2D\u5FC3;
|
|
19817
|
+
const d = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B ? \u4E26\u3073[k].\u6DF1\u3055 < \u8FBA\u306E\u4E2D\u5FC3 ? -(++\u8CA0\u5074\u306E\u5E2D * \u9593\u9694) : ++\u6B63\u5074\u306E\u5E2D * \u9593\u9694 : k * \u9593\u9694 - \u4E2D\u5FC3;
|
|
19706
19818
|
if (Math.abs(d) < 1e-3) continue;
|
|
19707
19819
|
const e = \u4E26\u3073[k].e;
|
|
19708
|
-
const \u5DEE\u66FF = \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, nodes);
|
|
19709
|
-
if (\u5DEE\u66FF === null) continue;
|
|
19710
19820
|
const \u524D = e.d;
|
|
19711
19821
|
const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
|
|
19712
|
-
|
|
19713
|
-
|
|
19822
|
+
const \u9577\u3044\u52A9\u8D70 = \u4E26\u3073[k].\u9577\u3044\u52A9\u8D70;
|
|
19823
|
+
for (const \u52A9\u8D70 of [\u9577\u3044\u52A9\u8D70, ENDPOINT_FAN_RUNUP]) {
|
|
19824
|
+
e.d = \u524D;
|
|
19825
|
+
const \u5DEE\u66FF = \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, \u52A9\u8D70, nodes);
|
|
19826
|
+
if (\u5DEE\u66FF === null) continue;
|
|
19827
|
+
e.d = \u5DEE\u66FF;
|
|
19828
|
+
if (countEdgeCrossings(edges).count <= \u524D\u306E\u4EA4\u5DEE) break;
|
|
19829
|
+
e.d = \u524D;
|
|
19830
|
+
}
|
|
19714
19831
|
}
|
|
19715
19832
|
}
|
|
19716
19833
|
}
|
|
@@ -19723,7 +19840,7 @@ function \u8FBA\u304B\u3089\u96E2\u308C\u305F\u5074\u306E\u4F4D\u7F6E(e, \u6A2A)
|
|
|
19723
19840
|
}
|
|
19724
19841
|
return null;
|
|
19725
19842
|
}
|
|
19726
|
-
function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, nodes) {
|
|
19843
|
+
function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, \u52A9\u8D70, nodes) {
|
|
19727
19844
|
if ((e.d.match(/M/g) ?? []).length !== 1) return null;
|
|
19728
19845
|
const segs = extractPathSegments(e.d);
|
|
19729
19846
|
if (segs.length === 0) return null;
|
|
@@ -19736,7 +19853,8 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
|
|
|
19736
19853
|
if (\u9577\u3055 < ENDPOINT_FAN_RUNUP + 1) return null;
|
|
19737
19854
|
const ux = (last.x1 - last.x2) / \u9577\u3055;
|
|
19738
19855
|
const uy = (last.y1 - last.y2) / \u9577\u3055;
|
|
19739
|
-
const \
|
|
19856
|
+
const \u4E38\u3081\u305F\u52A9\u8D70 = Math.min(\u52A9\u8D70, \u9577\u3055);
|
|
19857
|
+
const \u6298\u308C1 = { x: last.x2 + ux * \u4E38\u3081\u305F\u52A9\u8D70, y: last.y2 + uy * \u4E38\u3081\u305F\u52A9\u8D70 };
|
|
19740
19858
|
const \u6298\u308C2 = \u6A2A ? { x: \u6298\u308C1.x, y: \u6298\u308C1.y + d } : { x: \u6298\u308C1.x + d, y: \u6298\u308C1.y };
|
|
19741
19859
|
const \u7D42\u70B9 = \u6A2A ? { x: last.x2, y: last.y2 + d } : { x: last.x2 + d, y: last.y2 };
|
|
19742
19860
|
const \u65B0\u533A\u9593 = [
|
|
@@ -19758,7 +19876,8 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
|
|
|
19758
19876
|
}
|
|
19759
19877
|
parts.push(`L ${s.x2} ${s.y2}`);
|
|
19760
19878
|
}
|
|
19761
|
-
|
|
19879
|
+
const \u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C = Math.abs(\u6298\u308C1.x - last.x1) <= 0.5 && Math.abs(\u6298\u308C1.y - last.y1) <= 0.5;
|
|
19880
|
+
if (!\u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C) parts.push(`L ${round1(\u6298\u308C1.x)} ${round1(\u6298\u308C1.y)}`);
|
|
19762
19881
|
parts.push(`L ${round1(\u6298\u308C2.x)} ${round1(\u6298\u308C2.y)}`);
|
|
19763
19882
|
parts.push(`L ${round1(\u7D42\u70B9.x)} ${round1(\u7D42\u70B9.y)}`);
|
|
19764
19883
|
return parts.join(" ");
|
|
@@ -20241,6 +20360,7 @@ function layout(diag) {
|
|
|
20241
20360
|
diag.edges.filter((e) => e.posX1 !== void 0 && e.posY1 !== void 0 && e.posX2 !== void 0 && e.posY2 !== void 0).map((e) => e.id)
|
|
20242
20361
|
);
|
|
20243
20362
|
bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds);
|
|
20363
|
+
pullOutgoingFirstCorner(edges, nodesFinal);
|
|
20244
20364
|
fanIncomingEndpoints(edges, nodesFinal);
|
|
20245
20365
|
separateSharedStraightRuns(edges, nodesFinal);
|
|
20246
20366
|
hopEdgeCrossings(edges);
|