@cardenelabs/cdl 0.29.0 → 0.30.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.
- package/CHANGELOG.md +82 -1
- package/dist/index.cjs +136 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +136 -13
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +136 -13
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +136 -13
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/layout/edges.ts +173 -14
- package/src/layout.ts +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,85 @@ CDL (Chainome Diagram Language) の主要変更履歴。
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.30.1] - 2026-09-05
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **折れを持たない線が起点で折れなくなった** (#655)
|
|
13
|
+
|
|
14
|
+
`0.30.0` で入れた助走の伸ばし方が、区間を 1 つしか持たない線では起点まで届いていた。
|
|
15
|
+
その線では最後の区間が最初の区間でもあるため、いっぱいまで伸ばすと折れが起点に生まれる。
|
|
16
|
+
|
|
17
|
+
起点から `EDGE_STUB_OUT` (40) の直進が要るところ 28 しか残らず、線がどちらへ向かうのかを
|
|
18
|
+
出だしで読めない形になっていた。
|
|
19
|
+
消費側の `dragon` の図で `edge-stubout-min` が 6 件落ちている。
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
0.29.0 M 961 181 L 1257 181
|
|
23
|
+
0.30.0 M 961 181 L 961 153 L 1257 153
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
末尾を辺に沿ってずらす助走に、**起点を含む区間だけ** へ掛かる上限を足した。
|
|
27
|
+
上限を掛けた後の助走が `ENDPOINT_FAN_RUNUP` (40) を割る線は、ずらさず元のままにする。
|
|
28
|
+
短い助走で無理にずらすと折れが密になるため。
|
|
29
|
+
|
|
30
|
+
**折れを持つ線の助走は変えない**。 最後の区間いっぱいまで伸ばす #649 の直しはそのまま残る。
|
|
31
|
+
折れの有無で検査の契約を分け、起点の直進と根元の重なりを両立させた。
|
|
32
|
+
|
|
33
|
+
`cdl` 自身の 255 file / 6108 件では出ず、消費側の図で初めて出た。
|
|
34
|
+
|
|
35
|
+
## [0.30.0] - 2026-09-05
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **出入りする線の根元が重ならなくなった** (#649)
|
|
40
|
+
|
|
41
|
+
同じ節の同じ辺に 1 本入って 1 本出る時、相手が違うと 2 本の根元が重なったまま残っていた。
|
|
42
|
+
色の違う線どうしでは後から描いた色が前の色を隠し、関係の群を色で読み分けられなかった。
|
|
43
|
+
|
|
44
|
+
同じ辺に 2 本以上が付く形は 4 通りあり、3 通りは既に担当がいた。
|
|
45
|
+
入る × 入るは `fanIncomingEndpoints` (#611)、出る × 出るは `fan-origin-single-point` 軸が担当し、後者は意図して重ねる。
|
|
46
|
+
同じ 2 節を往復する対は `SYMMETRIC_PAIR_SHIFT` (`CAR-541`) が担当していた。
|
|
47
|
+
相手の違う入る × 出るだけ担当がいなかった。
|
|
48
|
+
|
|
49
|
+
`fanIncomingEndpoints` が、同じ辺から出る線を数に入れるようにした。
|
|
50
|
+
出る線が中央を占め、入る線は来た向きの外側へ寄る。
|
|
51
|
+
|
|
52
|
+
**重なっている時だけ動かす**。
|
|
53
|
+
変更前も変更後も 24px 以上重なっていない線は触らない。
|
|
54
|
+
動かすとまっすぐな線に折れが増えるため。
|
|
55
|
+
|
|
56
|
+
終点をずらす助走を、最後の区間いっぱいまで伸ばせるようにした。
|
|
57
|
+
変更前の 40px しか戻らない形では重なりが 40px ぶんしか減らなかったが、変更後は最後の区間全体を使える。
|
|
58
|
+
|
|
59
|
+
助走は長い方から順に試す。
|
|
60
|
+
長い助走で交差が増えるなら 40px で試し、どちらも増えるなら元のままにする。
|
|
61
|
+
|
|
62
|
+
消費側の `dragon` の見本帳 12 クラス、14 関係では、色の違う線の重なりが変更前の 5 件から変更後の 2 件に減った。
|
|
63
|
+
残る 2 件は `fan-origin-single-point` が意図して重ねている出る × 出る。
|
|
64
|
+
|
|
65
|
+
- **同じ辺から出る線が長く重ならなくなった** (#651)
|
|
66
|
+
|
|
67
|
+
同じ節の同じ辺から 2 本以上が出る時、起点が 1 点に収束するため出だしが重なる。
|
|
68
|
+
折れる位置が遠いと、その手前まで完全に重なったままになる。
|
|
69
|
+
|
|
70
|
+
消費側の `dragon` の見本帳では 137px 重なっていた。
|
|
71
|
+
色の違う線どうしでは後から描いた色が前の色を隠す。
|
|
72
|
+
|
|
73
|
+
折れる位置は `detourStub` が「端点と、進行方向で最初に当たる箱の中間」に置いている (#418)。
|
|
74
|
+
1 本しか出ない辺ではこの規則が正しく、2 本以上出る辺でだけ共有区間を長くしていた。
|
|
75
|
+
|
|
76
|
+
経路が確定した後に、**一番長い 1 本を残して残りの最初の折れを手前へ引く** ようにした。
|
|
77
|
+
引く先は `EDGE_STUB_OUT` と角の丸め半径の和で、まっすぐ走る部分がちょうど `EDGE_STUB_OUT` になる。
|
|
78
|
+
|
|
79
|
+
引いた結果、箱に当たる線と、交差が増える線は元のままにする。
|
|
80
|
+
|
|
81
|
+
重なりは変更前の 137px から変更後の 40px になった。
|
|
82
|
+
この 40px は 2 つの規約が要求している分で、これ以上は縮められない。
|
|
83
|
+
`fan-origin-single-point` 軸が起点を 1 点に収束させ、`EDGE_STUB_OUT` が起点から 40px 以上の直進を求めるため。
|
|
84
|
+
|
|
85
|
+
1 本しか出ない辺の折れる位置は変えていない。
|
|
86
|
+
|
|
8
87
|
## [0.29.0] - 2026-09-04
|
|
9
88
|
|
|
10
89
|
### Added
|
|
@@ -1440,7 +1519,9 @@ Initial OSS release.
|
|
|
1440
1519
|
使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
|
|
1441
1520
|
行き止まりになる。
|
|
1442
1521
|
|
|
1443
|
-
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.
|
|
1522
|
+
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.30.1...HEAD
|
|
1523
|
+
[0.30.1]: https://github.com/cardene777/cdl/compare/v0.30.0...v0.30.1
|
|
1524
|
+
[0.30.0]: https://github.com/cardene777/cdl/compare/v0.29.0...v0.30.0
|
|
1444
1525
|
[0.29.0]: https://github.com/cardene777/cdl/compare/v0.28.0...v0.29.0
|
|
1445
1526
|
[0.28.0]: https://github.com/cardene777/cdl/compare/v0.27.0...v0.28.0
|
|
1446
1527
|
[0.27.0]: https://github.com/cardene777/cdl/compare/v0.26.0...v0.27.0
|
package/dist/index.cjs
CHANGED
|
@@ -19675,16 +19675,112 @@ function separateSharedStraightRuns(edges, nodes) {
|
|
|
19675
19675
|
e.d = verticesToPath(verts.get(e.id));
|
|
19676
19676
|
}
|
|
19677
19677
|
}
|
|
19678
|
+
function pullOutgoingFirstCorner(edges, nodes) {
|
|
19679
|
+
if (edges.length < 2) return;
|
|
19680
|
+
const \u675F = /* @__PURE__ */ new Map();
|
|
19681
|
+
const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
|
|
19682
|
+
for (const e of edges) {
|
|
19683
|
+
const key = `${e.from}::${e.fromSide}`;
|
|
19684
|
+
const list = \u675F.get(key) ?? [];
|
|
19685
|
+
list.push(e);
|
|
19686
|
+
\u675F.set(key, list);
|
|
19687
|
+
const pair = `${e.from}->${e.to}`;
|
|
19688
|
+
\u540C\u3058\u7D44\u306E\u6570.set(pair, (\u540C\u3058\u7D44\u306E\u6570.get(pair) ?? 0) + 1);
|
|
19689
|
+
}
|
|
19690
|
+
let \u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = false;
|
|
19691
|
+
for (const list of \u675F.values()) {
|
|
19692
|
+
if (list.length < 2) continue;
|
|
19693
|
+
const \u4E26\u3073 = list.flatMap((e) => {
|
|
19694
|
+
const pts = pathVertices(e.d);
|
|
19695
|
+
if (!pts || pts.length < 2) return [];
|
|
19696
|
+
return [{ e, pts, \u6700\u521D\u306E\u9577\u3055: Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y) }];
|
|
19697
|
+
}).sort((a, b) => b.\u6700\u521D\u306E\u9577\u3055 - a.\u6700\u521D\u306E\u9577\u3055);
|
|
19698
|
+
for (const { e, pts, \u6700\u521D\u306E\u9577\u3055 } of \u4E26\u3073.slice(1)) {
|
|
19699
|
+
if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
|
|
19700
|
+
if (pts.length < 3 || \u6700\u521D\u306E\u9577\u3055 <= EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER) continue;
|
|
19701
|
+
const \u6A2A = e.fromSide === "left" || e.fromSide === "right";
|
|
19702
|
+
if (!runIsAligned(pts, 0, \u6A2A ? 1 : 0)) continue;
|
|
19703
|
+
const \u79FB\u52D5\u91CF = \u6700\u521D\u306E\u9577\u3055 - (EDGE_STUB_OUT + VERTICAL_DETOUR_CORNER);
|
|
19704
|
+
const ux = (pts[1].x - pts[0].x) / \u6700\u521D\u306E\u9577\u3055;
|
|
19705
|
+
const uy = (pts[1].y - pts[0].y) / \u6700\u521D\u306E\u9577\u3055;
|
|
19706
|
+
const \u8A66\u3057 = pts.map(
|
|
19707
|
+
(p, i) => i === 1 || i === 2 ? { x: p.x - ux * \u79FB\u52D5\u91CF, y: p.y - uy * \u79FB\u52D5\u91CF } : p
|
|
19708
|
+
);
|
|
19709
|
+
const \u8A66\u3057D = verticesToPath(\u8A66\u3057);
|
|
19710
|
+
const \u8A66\u3057\u533A\u9593 = flattenPathSegments(extractPathSegments(\u8A66\u3057D));
|
|
19711
|
+
if (nodes.some(
|
|
19712
|
+
(n) => n.id !== e.from && n.id !== e.to && segmentsCrossRect(\u8A66\u3057\u533A\u9593, nodeRect(n))
|
|
19713
|
+
)) {
|
|
19714
|
+
continue;
|
|
19715
|
+
}
|
|
19716
|
+
const \u524D = e.d;
|
|
19717
|
+
const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
|
|
19718
|
+
e.d = \u8A66\u3057D;
|
|
19719
|
+
if (countEdgeCrossings(edges).count > \u524D\u306E\u4EA4\u5DEE) {
|
|
19720
|
+
e.d = \u524D;
|
|
19721
|
+
continue;
|
|
19722
|
+
}
|
|
19723
|
+
e.d = \u524D;
|
|
19724
|
+
if (!\u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F) {
|
|
19725
|
+
slideLabelsAlongOwnPath(edges, nodes);
|
|
19726
|
+
\u672D\u3092\u65E7\u7D4C\u8DEF\u3078\u8FFD\u5F93\u6E08\u307F = true;
|
|
19727
|
+
}
|
|
19728
|
+
const labelBox = computeLabelBBoxWorld(e);
|
|
19729
|
+
const label = { x: labelBox.x + labelBox.w / 2, y: labelBox.y + labelBox.h / 2 };
|
|
19730
|
+
const \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22 = (a, b) => {
|
|
19731
|
+
const dx = b.x - a.x;
|
|
19732
|
+
const dy = b.y - a.y;
|
|
19733
|
+
const len2 = dx * dx + dy * dy;
|
|
19734
|
+
const t = len2 === 0 ? 0 : Math.max(0, Math.min(1, ((label.x - a.x) * dx + (label.y - a.y) * dy) / len2));
|
|
19735
|
+
return (label.x - (a.x + dx * t)) ** 2 + (label.y - (a.y + dy * t)) ** 2;
|
|
19736
|
+
};
|
|
19737
|
+
const \u52D5\u304F\u533A\u9593\u3078\u306E\u8DDD\u96E2 = \u7DDA\u5206\u307E\u3067\u306E\u8DDD\u96E22(pts[1], pts[2]);
|
|
19738
|
+
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);
|
|
19739
|
+
e.d = \u8A66\u3057D;
|
|
19740
|
+
if (label\u3082\u52D5\u304B\u3059) {
|
|
19741
|
+
e.labelX -= ux * \u79FB\u52D5\u91CF;
|
|
19742
|
+
e.labelY -= uy * \u79FB\u52D5\u91CF;
|
|
19743
|
+
}
|
|
19744
|
+
}
|
|
19745
|
+
}
|
|
19746
|
+
}
|
|
19678
19747
|
var ENDPOINT_FAN_STEP = 56;
|
|
19679
19748
|
var ENDPOINT_FAN_MIN = 20;
|
|
19680
19749
|
var ENDPOINT_FAN_RUNUP = 40;
|
|
19750
|
+
var MIXED_ROOT_OVERLAP_MIN = 24;
|
|
19681
19751
|
function fanIncomingEndpoints(edges, nodes) {
|
|
19682
19752
|
if (edges.length < 2) return;
|
|
19683
19753
|
const nmap = new Map(nodes.map((n) => [n.id, n]));
|
|
19754
|
+
const \u5E73\u5766\u306A\u533A\u9593 = new Map(edges.map((e) => [e.id, flattenPathSegments(extractPathSegments(e.d))]));
|
|
19755
|
+
const \u8EF8\u306B\u5E73\u884C\u306A\u91CD\u306A\u308A\u9577\u3055 = (\u4E00\u65B9, \u4ED6\u65B9) => {
|
|
19756
|
+
let \u5408\u8A08 = 0;
|
|
19757
|
+
for (const a of \u5E73\u5766\u306A\u533A\u9593.get(\u4E00\u65B9.id) ?? []) {
|
|
19758
|
+
const a\u306F\u6C34\u5E73 = Math.abs(a.y2 - a.y1) <= 1;
|
|
19759
|
+
const a\u306F\u5782\u76F4 = Math.abs(a.x2 - a.x1) <= 1;
|
|
19760
|
+
for (const b of \u5E73\u5766\u306A\u533A\u9593.get(\u4ED6\u65B9.id) ?? []) {
|
|
19761
|
+
const b\u306F\u6C34\u5E73 = Math.abs(b.y2 - b.y1) <= 1;
|
|
19762
|
+
const b\u306F\u5782\u76F4 = Math.abs(b.x2 - b.x1) <= 1;
|
|
19763
|
+
if (a\u306F\u6C34\u5E73 && b\u306F\u6C34\u5E73 && Math.abs(a.y1 - b.y1) <= 1) {
|
|
19764
|
+
\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)));
|
|
19765
|
+
}
|
|
19766
|
+
if (a\u306F\u5782\u76F4 && b\u306F\u5782\u76F4 && Math.abs(a.x1 - b.x1) <= 1) {
|
|
19767
|
+
\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)));
|
|
19768
|
+
}
|
|
19769
|
+
}
|
|
19770
|
+
}
|
|
19771
|
+
return \u5408\u8A08;
|
|
19772
|
+
};
|
|
19684
19773
|
const \u540C\u3058\u7D44\u306E\u6570 = /* @__PURE__ */ new Map();
|
|
19685
19774
|
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);
|
|
19686
19775
|
const \u675F = /* @__PURE__ */ new Map();
|
|
19776
|
+
const \u51FA\u308B\u7DDA = /* @__PURE__ */ new Map();
|
|
19687
19777
|
for (const e of edges) {
|
|
19778
|
+
if (nmap.has(e.from)) {
|
|
19779
|
+
const key2 = `${e.from}::${e.fromSide}`;
|
|
19780
|
+
const list2 = \u51FA\u308B\u7DDA.get(key2) ?? [];
|
|
19781
|
+
list2.push(e);
|
|
19782
|
+
\u51FA\u308B\u7DDA.set(key2, list2);
|
|
19783
|
+
}
|
|
19688
19784
|
if (!nmap.has(e.to)) continue;
|
|
19689
19785
|
if ((\u540C\u3058\u7D44\u306E\u6570.get(`${e.from}->${e.to}`) ?? 0) > 1) continue;
|
|
19690
19786
|
const key = `${e.to}::${e.toSide}`;
|
|
@@ -19692,27 +19788,48 @@ function fanIncomingEndpoints(edges, nodes) {
|
|
|
19692
19788
|
list.push(e);
|
|
19693
19789
|
\u675F.set(key, list);
|
|
19694
19790
|
}
|
|
19695
|
-
for (const [, list] of \u675F) {
|
|
19696
|
-
|
|
19791
|
+
for (const [key, list] of \u675F) {
|
|
19792
|
+
const \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B = (\u51FA\u308B\u7DDA.get(key) ?? []).some(
|
|
19793
|
+
(\u51FA\u7DDA) => list.some(
|
|
19794
|
+
(\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
|
|
19795
|
+
)
|
|
19796
|
+
);
|
|
19797
|
+
if (list.length < 2 && !\u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B) continue;
|
|
19697
19798
|
const n = nmap.get(list[0].to);
|
|
19698
19799
|
const \u6A2A = list[0].toSide === "left" || list[0].toSide === "right";
|
|
19699
19800
|
const \u8FBA\u306E\u9577\u3055 = \u6A2A ? n.h : n.w;
|
|
19700
19801
|
const \u4F7F\u3048\u308B\u5E452 = \u8FBA\u306E\u9577\u3055 - 2 * ARROW_ENDPOINT_CENTER_TOL;
|
|
19701
19802
|
if (\u4F7F\u3048\u308B\u5E452 <= 0) continue;
|
|
19702
|
-
const \u9593
|
|
19803
|
+
const \u5E2D\u306E\u9593 = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B ? list.length : list.length - 1;
|
|
19804
|
+
const \u9593\u9694 = Math.min(ENDPOINT_FAN_STEP, \u4F7F\u3048\u308B\u5E452 / \u5E2D\u306E\u9593);
|
|
19703
19805
|
if (\u9593\u9694 < ENDPOINT_FAN_MIN) continue;
|
|
19704
|
-
const \
|
|
19806
|
+
const \u8FBA\u306E\u4E2D\u5FC3 = \u6A2A ? n.cy : n.cx;
|
|
19807
|
+
const \u4E26\u3073 = list.map((e) => {
|
|
19808
|
+
const \u533A\u9593 = extractPathSegments(e.d);
|
|
19809
|
+
const last = \u533A\u9593[\u533A\u9593.length - 1];
|
|
19810
|
+
const \u9577\u3044\u52A9\u8D70 = last === void 0 ? 0 : Math.hypot(last.x2 - last.x1, last.y2 - last.y1);
|
|
19811
|
+
const \u4E2D\u5FC3\u3092\u88DC\u3046 = \u4E2D\u592E\u304C\u585E\u304C\u3063\u3066\u3044\u308B || list.length === 2;
|
|
19812
|
+
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);
|
|
19813
|
+
return { e, \u9577\u3044\u52A9\u8D70, \u6DF1\u3055 };
|
|
19814
|
+
}).sort((a, b) => a.\u6DF1\u3055 - b.\u6DF1\u3055 || (a.e.id < b.e.id ? -1 : 1));
|
|
19705
19815
|
const \u4E2D\u5FC3 = (\u4E26\u3073.length - 1) * \u9593\u9694 / 2;
|
|
19816
|
+
let \u8CA0\u5074\u306E\u5E2D = 0;
|
|
19817
|
+
let \u6B63\u5074\u306E\u5E2D = 0;
|
|
19706
19818
|
for (let k = 0; k < \u4E26\u3073.length; k++) {
|
|
19707
|
-
const d = k * \u9593\u9694 - \u4E2D\u5FC3;
|
|
19819
|
+
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;
|
|
19708
19820
|
if (Math.abs(d) < 1e-3) continue;
|
|
19709
19821
|
const e = \u4E26\u3073[k].e;
|
|
19710
|
-
const \u5DEE\u66FF = \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, nodes);
|
|
19711
|
-
if (\u5DEE\u66FF === null) continue;
|
|
19712
19822
|
const \u524D = e.d;
|
|
19713
19823
|
const \u524D\u306E\u4EA4\u5DEE = countEdgeCrossings(edges).count;
|
|
19714
|
-
|
|
19715
|
-
|
|
19824
|
+
const \u9577\u3044\u52A9\u8D70 = \u4E26\u3073[k].\u9577\u3044\u52A9\u8D70;
|
|
19825
|
+
for (const \u52A9\u8D70 of [\u9577\u3044\u52A9\u8D70, ENDPOINT_FAN_RUNUP]) {
|
|
19826
|
+
e.d = \u524D;
|
|
19827
|
+
const \u5DEE\u66FF = \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, \u52A9\u8D70, nodes);
|
|
19828
|
+
if (\u5DEE\u66FF === null) continue;
|
|
19829
|
+
e.d = \u5DEE\u66FF;
|
|
19830
|
+
if (countEdgeCrossings(edges).count <= \u524D\u306E\u4EA4\u5DEE) break;
|
|
19831
|
+
e.d = \u524D;
|
|
19832
|
+
}
|
|
19716
19833
|
}
|
|
19717
19834
|
}
|
|
19718
19835
|
}
|
|
@@ -19725,7 +19842,7 @@ function \u8FBA\u304B\u3089\u96E2\u308C\u305F\u5074\u306E\u4F4D\u7F6E(e, \u6A2A)
|
|
|
19725
19842
|
}
|
|
19726
19843
|
return null;
|
|
19727
19844
|
}
|
|
19728
|
-
function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, nodes) {
|
|
19845
|
+
function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \u6A2A, d, \u52A9\u8D70, nodes) {
|
|
19729
19846
|
if ((e.d.match(/M/g) ?? []).length !== 1) return null;
|
|
19730
19847
|
const segs = extractPathSegments(e.d);
|
|
19731
19848
|
if (segs.length === 0) return null;
|
|
@@ -19738,7 +19855,12 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
|
|
|
19738
19855
|
if (\u9577\u3055 < ENDPOINT_FAN_RUNUP + 1) return null;
|
|
19739
19856
|
const ux = (last.x1 - last.x2) / \u9577\u3055;
|
|
19740
19857
|
const uy = (last.y1 - last.y2) / \u9577\u3055;
|
|
19741
|
-
const
|
|
19858
|
+
const head = segs[0];
|
|
19859
|
+
const \u6700\u5F8C\u306E\u533A\u9593\u304C\u8D77\u70B9\u3092\u542B\u3080 = Math.abs(last.x1 - head.x1) <= 0.5 && Math.abs(last.y1 - head.y1) <= 0.5;
|
|
19860
|
+
const \u52A9\u8D70\u4E0A\u9650 = \u6700\u5F8C\u306E\u533A\u9593\u304C\u8D77\u70B9\u3092\u542B\u3080 ? \u9577\u3055 - EDGE_STUB_OUT : \u9577\u3055;
|
|
19861
|
+
const \u4E38\u3081\u305F\u52A9\u8D70 = Math.min(\u52A9\u8D70, \u52A9\u8D70\u4E0A\u9650);
|
|
19862
|
+
if (\u4E38\u3081\u305F\u52A9\u8D70 < ENDPOINT_FAN_RUNUP) return null;
|
|
19863
|
+
const \u6298\u308C1 = { x: last.x2 + ux * \u4E38\u3081\u305F\u52A9\u8D70, y: last.y2 + uy * \u4E38\u3081\u305F\u52A9\u8D70 };
|
|
19742
19864
|
const \u6298\u308C2 = \u6A2A ? { x: \u6298\u308C1.x, y: \u6298\u308C1.y + d } : { x: \u6298\u308C1.x + d, y: \u6298\u308C1.y };
|
|
19743
19865
|
const \u7D42\u70B9 = \u6A2A ? { x: last.x2, y: last.y2 + d } : { x: last.x2 + d, y: last.y2 };
|
|
19744
19866
|
const \u65B0\u533A\u9593 = [
|
|
@@ -19749,7 +19871,6 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
|
|
|
19749
19871
|
if (nodes.some((n) => n.id !== e.from && n.id !== e.to && segmentsCrossRect(\u65B0\u533A\u9593, nodeRect(n)))) {
|
|
19750
19872
|
return null;
|
|
19751
19873
|
}
|
|
19752
|
-
const head = segs[0];
|
|
19753
19874
|
const parts = [`M ${head.x1} ${head.y1}`];
|
|
19754
19875
|
for (let i = 0; i < segs.length - 1; i++) {
|
|
19755
19876
|
const s = segs[i];
|
|
@@ -19760,7 +19881,8 @@ function \u672B\u5C3E\u3092\u8FBA\u306B\u6CBF\u3063\u3066\u305A\u3089\u3059(e, \
|
|
|
19760
19881
|
}
|
|
19761
19882
|
parts.push(`L ${s.x2} ${s.y2}`);
|
|
19762
19883
|
}
|
|
19763
|
-
|
|
19884
|
+
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;
|
|
19885
|
+
if (!\u6298\u308C1\u306F\u76F4\u524D\u306E\u6298\u308C) parts.push(`L ${round1(\u6298\u308C1.x)} ${round1(\u6298\u308C1.y)}`);
|
|
19764
19886
|
parts.push(`L ${round1(\u6298\u308C2.x)} ${round1(\u6298\u308C2.y)}`);
|
|
19765
19887
|
parts.push(`L ${round1(\u7D42\u70B9.x)} ${round1(\u7D42\u70B9.y)}`);
|
|
19766
19888
|
return parts.join(" ");
|
|
@@ -20243,6 +20365,7 @@ function layout(diag) {
|
|
|
20243
20365
|
diag.edges.filter((e) => e.posX1 !== void 0 && e.posY1 !== void 0 && e.posX2 !== void 0 && e.posY2 !== void 0).map((e) => e.id)
|
|
20244
20366
|
);
|
|
20245
20367
|
bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds);
|
|
20368
|
+
pullOutgoingFirstCorner(edges, nodesFinal);
|
|
20246
20369
|
fanIncomingEndpoints(edges, nodesFinal);
|
|
20247
20370
|
separateSharedStraightRuns(edges, nodesFinal);
|
|
20248
20371
|
hopEdgeCrossings(edges);
|