@cardenelabs/cdl 0.52.0 → 0.53.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 +16 -1
- package/dist/index.cjs +88 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +88 -78
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +88 -78
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +88 -78
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/layout/head-label.ts +24 -0
- package/src/layout/nodes.ts +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ CDL (Chainome Diagram Language) の主要変更履歴。
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.53.0] - 2026-09-11
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **短い縦の線で、両端の多重度が詰まって 1 つの札に見えるのを直した** (#829)
|
|
13
|
+
|
|
14
|
+
縦に隣り合う箱をつなぐ線は、箱の間隔 (100) がそのまま線の長さになる。 両端に多重度を書くと、
|
|
15
|
+
出どころの字と行き先の字が線の同じ側に縦に並び、間が 10 しか空かなかった。 2 行の札のように
|
|
16
|
+
読まれ、どちらの端の数かが分からなかった。
|
|
17
|
+
|
|
18
|
+
縦の間隔を決める計算に端の字を入れた。 両端に字がある線は、2 つの字の間が字と自分の端の間 (22) の
|
|
19
|
+
2 倍以上空く長さまで間隔を広げる。 間隔は図の中で全て同じ値に揃える規則のままなので、その図の
|
|
20
|
+
縦の間隔が全て広がる。 片方の端にだけ字がある線はいまの間隔で足り、見た目は変わらない。
|
|
21
|
+
|
|
8
22
|
## [0.52.0] - 2026-09-11
|
|
9
23
|
|
|
10
24
|
### Added
|
|
@@ -2448,7 +2462,8 @@ Initial OSS release.
|
|
|
2448
2462
|
使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
|
|
2449
2463
|
行き止まりになる。
|
|
2450
2464
|
|
|
2451
|
-
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.
|
|
2465
|
+
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.53.0...HEAD
|
|
2466
|
+
[0.53.0]: https://github.com/cardene777/cdl/compare/v0.52.0...v0.53.0
|
|
2452
2467
|
[0.52.0]: https://github.com/cardene777/cdl/compare/v0.51.0...v0.52.0
|
|
2453
2468
|
[0.51.0]: https://github.com/cardene777/cdl/compare/v0.50.0...v0.51.0
|
|
2454
2469
|
[0.50.0]: https://github.com/cardene777/cdl/compare/v0.49.0...v0.50.0
|
package/dist/index.cjs
CHANGED
|
@@ -20532,6 +20532,87 @@ function requiredRowsWidth(rows, kind) {
|
|
|
20532
20532
|
return Math.ceil(kind === "storage" ? storage : generic);
|
|
20533
20533
|
}
|
|
20534
20534
|
|
|
20535
|
+
// src/layout/head-label.ts
|
|
20536
|
+
var \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 = 22;
|
|
20537
|
+
var \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 = 8;
|
|
20538
|
+
var \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 = EDGE_LABEL_TEXT.sub.fontSize;
|
|
20539
|
+
var \u7BB1\u306E\u9AD8\u3055 = Math.round(\u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * 1.2);
|
|
20540
|
+
var BASELINE_RATIO = 0.8;
|
|
20541
|
+
var \u4E21\u7AEF\u306E\u5B57\u306E\u9593 = \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 * 2;
|
|
20542
|
+
function \u7AEF\u306E\u5B57\u306B\u8981\u308B\u7DDA\u306E\u9577\u3055(edge) {
|
|
20543
|
+
const \u4E00\u3064\u5206 = \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 + \u7BB1\u306E\u9AD8\u3055;
|
|
20544
|
+
const \u6570 = [edge.headLabel, edge.tailLabel].filter((t) => t?.trim()).length;
|
|
20545
|
+
if (\u6570 === 0) return 0;
|
|
20546
|
+
if (\u6570 === 1) return \u4E00\u3064\u5206;
|
|
20547
|
+
return \u4E00\u3064\u5206 * 2 + \u4E21\u7AEF\u306E\u5B57\u306E\u9593;
|
|
20548
|
+
}
|
|
20549
|
+
function \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC) {
|
|
20550
|
+
for (const p of \u5019\u88DC) {
|
|
20551
|
+
if (!p) continue;
|
|
20552
|
+
const dx = end.x - p.x;
|
|
20553
|
+
const dy = end.y - p.y;
|
|
20554
|
+
const len = Math.hypot(dx, dy);
|
|
20555
|
+
if (len > 1e-6) return { end, ux: dx / len, uy: dy / len };
|
|
20556
|
+
}
|
|
20557
|
+
return null;
|
|
20558
|
+
}
|
|
20559
|
+
function \u7AEF\u3067\u306E\u5411\u304D(d, \u7AEF) {
|
|
20560
|
+
const segs = extractPathSegments(d);
|
|
20561
|
+
if (segs.length === 0) return null;
|
|
20562
|
+
if (\u7AEF === "head") {
|
|
20563
|
+
const last = segs[segs.length - 1];
|
|
20564
|
+
const end2 = { x: last.x2, y: last.y2 };
|
|
20565
|
+
const \u5019\u88DC2 = segs.slice().reverse().flatMap((s) => [s.cmd === "Q" ? s.ctrl?.[0] : s.cmd === "C" ? s.ctrl?.[1] : void 0, { x: s.x1, y: s.y1 }]);
|
|
20566
|
+
return \u5411\u304D\u3092\u53D6\u308B(end2, \u5019\u88DC2);
|
|
20567
|
+
}
|
|
20568
|
+
const first = segs[0];
|
|
20569
|
+
const end = { x: first.x1, y: first.y1 };
|
|
20570
|
+
const \u5019\u88DC = segs.flatMap((s) => [...s.ctrl ?? [], { x: s.x2, y: s.y2 }]);
|
|
20571
|
+
return \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC);
|
|
20572
|
+
}
|
|
20573
|
+
function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head") {
|
|
20574
|
+
const text = (\u7AEF === "head" ? edge.headLabel : edge.tailLabel)?.trim();
|
|
20575
|
+
if (!text) return null;
|
|
20576
|
+
const \u5411\u304D = \u7AEF\u3067\u306E\u5411\u304D(edge.d, \u7AEF);
|
|
20577
|
+
if (!\u5411\u304D) return null;
|
|
20578
|
+
const { end, ux, uy } = \u5411\u304D;
|
|
20579
|
+
const bx = end.x - ux * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
20580
|
+
const by = end.y - uy * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
20581
|
+
const w = measureTextWidth(text, {
|
|
20582
|
+
fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
|
|
20583
|
+
fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
|
|
20584
|
+
fontFamily: "mono"
|
|
20585
|
+
});
|
|
20586
|
+
const h = \u7BB1\u306E\u9AD8\u3055;
|
|
20587
|
+
const \u672D = hasRenderedLabel(edge) && edge.labelX !== void 0 && edge.labelY !== void 0 ? { x: edge.labelX, y: edge.labelY } : null;
|
|
20588
|
+
let anchor;
|
|
20589
|
+
let box;
|
|
20590
|
+
if (Math.abs(ux) >= Math.abs(uy)) {
|
|
20591
|
+
const \u53F3\u3078\u9032\u3080 = ux > 0;
|
|
20592
|
+
const \u4E0A\u306B\u7F6E\u304F = \u672D !== null && \u672D.y > by;
|
|
20593
|
+
anchor = \u53F3\u3078\u9032\u3080 ? "end" : "start";
|
|
20594
|
+
box = {
|
|
20595
|
+
x: \u53F3\u3078\u9032\u3080 ? bx - w : bx,
|
|
20596
|
+
y: \u4E0A\u306B\u7F6E\u304F ? by - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - h : by + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593,
|
|
20597
|
+
w,
|
|
20598
|
+
h
|
|
20599
|
+
};
|
|
20600
|
+
} else {
|
|
20601
|
+
const \u4E0B\u3078\u9032\u3080 = uy > 0;
|
|
20602
|
+
const \u53F3\u306B\u7F6E\u304F = \u672D !== null && \u672D.x < bx;
|
|
20603
|
+
anchor = \u53F3\u306B\u7F6E\u304F ? "start" : "end";
|
|
20604
|
+
box = {
|
|
20605
|
+
x: \u53F3\u306B\u7F6E\u304F ? bx + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 : bx - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - w,
|
|
20606
|
+
y: \u4E0B\u3078\u9032\u3080 ? by - h : by,
|
|
20607
|
+
w,
|
|
20608
|
+
h
|
|
20609
|
+
};
|
|
20610
|
+
}
|
|
20611
|
+
const x = anchor === "start" ? box.x : box.x + box.w;
|
|
20612
|
+
const y = box.y + (h - \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055) / 2 + \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * BASELINE_RATIO;
|
|
20613
|
+
return { x, y, anchor, box };
|
|
20614
|
+
}
|
|
20615
|
+
|
|
20535
20616
|
// src/layout/nodes.ts
|
|
20536
20617
|
function autoStorageHeight(n, defaultH) {
|
|
20537
20618
|
if (n.kind !== "storage") return n.h ?? defaultH;
|
|
@@ -20553,7 +20634,7 @@ function autoRowsWidth(n, defaultW) {
|
|
|
20553
20634
|
const required = requiredRowsWidth(n.rows, n.kind);
|
|
20554
20635
|
return Math.max(defaultW, required);
|
|
20555
20636
|
}
|
|
20556
|
-
function \u7BB1\u306E\u9AD8\
|
|
20637
|
+
function \u7BB1\u306E\u9AD8\u30552(n, \u65E2\u5B9Ah) {
|
|
20557
20638
|
if (n.h != null) return n.h;
|
|
20558
20639
|
if (n.kind === "storage") return autoStorageHeight(n, \u65E2\u5B9Ah);
|
|
20559
20640
|
return \u4E2D\u8EAB\u304B\u3089\u51FA\u3059\u9AD8\u3055(n.kind, \u65E2\u5B9Ah, {
|
|
@@ -20567,8 +20648,8 @@ function requiredStackGapForEdgeLabels(diag, allStacks) {
|
|
|
20567
20648
|
const byId = new Map(diag.nodes.map((n) => [n.id, n]));
|
|
20568
20649
|
const rankOf = new Map(allStacks.map((stack, i) => [stack, i]));
|
|
20569
20650
|
const pillHsByGap = /* @__PURE__ */ new Map();
|
|
20651
|
+
let \u7AEF\u306E\u5B57\u306E\u8981\u6C42 = 0;
|
|
20570
20652
|
for (const e of diag.edges) {
|
|
20571
|
-
if (!hasRenderedLabel(e)) continue;
|
|
20572
20653
|
const from = byId.get(e.from);
|
|
20573
20654
|
const to = byId.get(e.to);
|
|
20574
20655
|
if (!from || !to) continue;
|
|
@@ -20577,10 +20658,12 @@ function requiredStackGapForEdgeLabels(diag, allStacks) {
|
|
|
20577
20658
|
const toRank = rankOf.get(to.stack);
|
|
20578
20659
|
if (fromRank === void 0 || toRank === void 0) continue;
|
|
20579
20660
|
if (Math.abs(fromRank - toRank) !== 1) continue;
|
|
20661
|
+
\u7AEF\u306E\u5B57\u306E\u8981\u6C42 = Math.max(\u7AEF\u306E\u5B57\u306E\u8981\u6C42, \u7AEF\u306E\u5B57\u306B\u8981\u308B\u7DDA\u306E\u9577\u3055(e));
|
|
20662
|
+
if (!hasRenderedLabel(e)) continue;
|
|
20580
20663
|
const key = `${from.lane}::${Math.min(fromRank, toRank)}`;
|
|
20581
20664
|
pillHsByGap.set(key, [...pillHsByGap.get(key) ?? [], labelPillH(e.sub)]);
|
|
20582
20665
|
}
|
|
20583
|
-
let required =
|
|
20666
|
+
let required = \u7AEF\u306E\u5B57\u306E\u8981\u6C42;
|
|
20584
20667
|
for (const pillHs of pillHsByGap.values()) {
|
|
20585
20668
|
required = Math.max(required, requiredVerticalLabelGap(pillHs));
|
|
20586
20669
|
}
|
|
@@ -20592,7 +20675,7 @@ function layoutNodes(diag, lanes) {
|
|
|
20592
20675
|
const rowH = /* @__PURE__ */ new Map();
|
|
20593
20676
|
for (const stack of allStacks) {
|
|
20594
20677
|
const nodesAtStack = diag.nodes.filter((n) => n.stack === stack);
|
|
20595
|
-
const h = Math.max(...nodesAtStack.map((n) => \u7BB1\u306E\u9AD8\
|
|
20678
|
+
const h = Math.max(...nodesAtStack.map((n) => \u7BB1\u306E\u9AD8\u30552(n, NODE_SIZE[n.kind].h)));
|
|
20596
20679
|
rowH.set(stack, h);
|
|
20597
20680
|
}
|
|
20598
20681
|
const rowCy = /* @__PURE__ */ new Map();
|
|
@@ -20646,7 +20729,7 @@ function layoutNodes(diag, lanes) {
|
|
|
20646
20729
|
const \u6BB5\u306E\u82AF = rowCy.get(n.stack);
|
|
20647
20730
|
const \u6BB5\u306E\u9AD8\u3055 = rowH.get(n.stack);
|
|
20648
20731
|
const \u81EA\u524D\u306E\u9AD8\u3055 = n.rowMarks !== void 0;
|
|
20649
|
-
const h = n.h ?? (\u81EA\u524D\u306E\u9AD8\u3055 ? \u7BB1\u306E\u9AD8\
|
|
20732
|
+
const h = n.h ?? (\u81EA\u524D\u306E\u9AD8\u3055 ? \u7BB1\u306E\u9AD8\u30552(n, size.h) : \u6BB5\u306E\u9AD8\u3055);
|
|
20650
20733
|
const cy = \u6BB5\u306E\u82AF;
|
|
20651
20734
|
const w = autoRowsWidth(n, size.w);
|
|
20652
20735
|
out.push({
|
|
@@ -22935,79 +23018,6 @@ function \u7B49\u5E45\u306E\u5B57(text, fontSize) {
|
|
|
22935
23018
|
});
|
|
22936
23019
|
return out;
|
|
22937
23020
|
}
|
|
22938
|
-
|
|
22939
|
-
// src/layout/head-label.ts
|
|
22940
|
-
var \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 = 22;
|
|
22941
|
-
var \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 = 8;
|
|
22942
|
-
var \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 = EDGE_LABEL_TEXT.sub.fontSize;
|
|
22943
|
-
var \u7BB1\u306E\u9AD8\u30552 = Math.round(\u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * 1.2);
|
|
22944
|
-
var BASELINE_RATIO = 0.8;
|
|
22945
|
-
function \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC) {
|
|
22946
|
-
for (const p of \u5019\u88DC) {
|
|
22947
|
-
if (!p) continue;
|
|
22948
|
-
const dx = end.x - p.x;
|
|
22949
|
-
const dy = end.y - p.y;
|
|
22950
|
-
const len = Math.hypot(dx, dy);
|
|
22951
|
-
if (len > 1e-6) return { end, ux: dx / len, uy: dy / len };
|
|
22952
|
-
}
|
|
22953
|
-
return null;
|
|
22954
|
-
}
|
|
22955
|
-
function \u7AEF\u3067\u306E\u5411\u304D(d, \u7AEF) {
|
|
22956
|
-
const segs = extractPathSegments(d);
|
|
22957
|
-
if (segs.length === 0) return null;
|
|
22958
|
-
if (\u7AEF === "head") {
|
|
22959
|
-
const last = segs[segs.length - 1];
|
|
22960
|
-
const end2 = { x: last.x2, y: last.y2 };
|
|
22961
|
-
const \u5019\u88DC2 = segs.slice().reverse().flatMap((s) => [s.cmd === "Q" ? s.ctrl?.[0] : s.cmd === "C" ? s.ctrl?.[1] : void 0, { x: s.x1, y: s.y1 }]);
|
|
22962
|
-
return \u5411\u304D\u3092\u53D6\u308B(end2, \u5019\u88DC2);
|
|
22963
|
-
}
|
|
22964
|
-
const first = segs[0];
|
|
22965
|
-
const end = { x: first.x1, y: first.y1 };
|
|
22966
|
-
const \u5019\u88DC = segs.flatMap((s) => [...s.ctrl ?? [], { x: s.x2, y: s.y2 }]);
|
|
22967
|
-
return \u5411\u304D\u3092\u53D6\u308B(end, \u5019\u88DC);
|
|
22968
|
-
}
|
|
22969
|
-
function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge, \u7AEF = "head") {
|
|
22970
|
-
const text = (\u7AEF === "head" ? edge.headLabel : edge.tailLabel)?.trim();
|
|
22971
|
-
if (!text) return null;
|
|
22972
|
-
const \u5411\u304D = \u7AEF\u3067\u306E\u5411\u304D(edge.d, \u7AEF);
|
|
22973
|
-
if (!\u5411\u304D) return null;
|
|
22974
|
-
const { end, ux, uy } = \u5411\u304D;
|
|
22975
|
-
const bx = end.x - ux * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
22976
|
-
const by = end.y - uy * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
|
|
22977
|
-
const w = measureTextWidth(text, {
|
|
22978
|
-
fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
|
|
22979
|
-
fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
|
|
22980
|
-
fontFamily: "mono"
|
|
22981
|
-
});
|
|
22982
|
-
const h = \u7BB1\u306E\u9AD8\u30552;
|
|
22983
|
-
const \u672D = hasRenderedLabel(edge) && edge.labelX !== void 0 && edge.labelY !== void 0 ? { x: edge.labelX, y: edge.labelY } : null;
|
|
22984
|
-
let anchor;
|
|
22985
|
-
let box;
|
|
22986
|
-
if (Math.abs(ux) >= Math.abs(uy)) {
|
|
22987
|
-
const \u53F3\u3078\u9032\u3080 = ux > 0;
|
|
22988
|
-
const \u4E0A\u306B\u7F6E\u304F = \u672D !== null && \u672D.y > by;
|
|
22989
|
-
anchor = \u53F3\u3078\u9032\u3080 ? "end" : "start";
|
|
22990
|
-
box = {
|
|
22991
|
-
x: \u53F3\u3078\u9032\u3080 ? bx - w : bx,
|
|
22992
|
-
y: \u4E0A\u306B\u7F6E\u304F ? by - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - h : by + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593,
|
|
22993
|
-
w,
|
|
22994
|
-
h
|
|
22995
|
-
};
|
|
22996
|
-
} else {
|
|
22997
|
-
const \u4E0B\u3078\u9032\u3080 = uy > 0;
|
|
22998
|
-
const \u53F3\u306B\u7F6E\u304F = \u672D !== null && \u672D.x < bx;
|
|
22999
|
-
anchor = \u53F3\u306B\u7F6E\u304F ? "start" : "end";
|
|
23000
|
-
box = {
|
|
23001
|
-
x: \u53F3\u306B\u7F6E\u304F ? bx + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 : bx - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - w,
|
|
23002
|
-
y: \u4E0B\u3078\u9032\u3080 ? by - h : by,
|
|
23003
|
-
w,
|
|
23004
|
-
h
|
|
23005
|
-
};
|
|
23006
|
-
}
|
|
23007
|
-
const x = anchor === "start" ? box.x : box.x + box.w;
|
|
23008
|
-
const y = box.y + (h - \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055) / 2 + \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * BASELINE_RATIO;
|
|
23009
|
-
return { x, y, anchor, box };
|
|
23010
|
-
}
|
|
23011
23021
|
function defaultEdgeWidth(active) {
|
|
23012
23022
|
return active ? 2.5 : 1.25;
|
|
23013
23023
|
}
|