@cardenelabs/cdl 0.17.0 → 0.18.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 +78 -1
- package/dist/index.cjs +42 -18
- 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 +41 -19
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +39 -18
- 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 +39 -18
- package/dist/react.js.map +1 -1
- package/dist/{render-Dc5Pdf7e.d.cts → render-Czv0tUon.d.cts} +25 -1
- package/dist/{render-Dc5Pdf7e.d.ts → render-Czv0tUon.d.ts} +25 -1
- package/package.json +1 -1
- package/src/index.ts +3 -0
- package/src/kinds/sequence-board.tsx +9 -1
- package/src/kinds/storage.tsx +5 -4
- package/src/layout/nodes.ts +8 -7
- package/src/layout/spec.ts +22 -4
- package/src/layout.ts +2 -0
- package/src/render/stage.tsx +38 -4
- package/src/types.ts +27 -0
- package/src/visual-validate.ts +24 -19
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,81 @@ CDL (Chainome Diagram Language) の主要変更履歴。
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.18.0] - 2026-08-29
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **段が来るまで矢印を描かないようにした** (#582)
|
|
13
|
+
|
|
14
|
+
段を進めるごとに関係が 1 本ずつ増える図で、**全ての矢印が 1 段目から見えていた**。
|
|
15
|
+
段が矢印を光らせるとその線だけ引き直されるが、既に見えているので「増えた」 とは読めず、
|
|
16
|
+
無関係な線がちらついたようにしか見えない (user 実機確認)。
|
|
17
|
+
|
|
18
|
+
判定は **段が矢印を名指ししているか** で行う。 段のどこかで `activate` に載る矢印は、
|
|
19
|
+
その段が来るまで描かない。 1 度出たら以降は出したままにする = 消える向きの動きは、
|
|
20
|
+
読み手が「戻った」 と読む。
|
|
21
|
+
|
|
22
|
+
**段が矢印を 1 度も名指ししない図では隠さない**。 そういう図では矢印が骨格そのもので、
|
|
23
|
+
隠すと図が読めなくなる = 既定を変えても既存の図は動かない。
|
|
24
|
+
|
|
25
|
+
著者が切り替えられるよう `CdlDiagram.edgeReveal` を足した。
|
|
26
|
+
|
|
27
|
+
| 値 | 何が起きるか |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `phase` (既定) | 段が名指しする矢印は、その段が来るまで描かない |
|
|
30
|
+
| `all` | 段に関わらず最初から全部描く |
|
|
31
|
+
|
|
32
|
+
書ける値の一覧 (`EDGE_REVEALS`) と既定 (`EDGE_REVEAL_DEFAULT`) を公開する。
|
|
33
|
+
利用側が手で並べると、値を足した時に書けないまま取り残される。
|
|
34
|
+
|
|
35
|
+
## [0.17.1] - 2026-08-29
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- **箱の題を行より大きくした** (#580)
|
|
40
|
+
|
|
41
|
+
題が 22、行の名前が 26 で **題の方が小さかった**。 呼び名も題と同じ 22 で、どちらが主か
|
|
42
|
+
字の大きさから読めない。 箱を見た人が「何の箱か」 を最初に読めない状態だった。
|
|
43
|
+
|
|
44
|
+
| 要素 | いままで | これから |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| 題 | 22 | 34 |
|
|
47
|
+
| 行の名前 | 26 | 26 (据え置き、ここが基準) |
|
|
48
|
+
| 行の型 | 24 | 22 |
|
|
49
|
+
| 呼び名 | 22 | 20 |
|
|
50
|
+
|
|
51
|
+
行の名前を基準に上下へ広げる。 題を上げたぶん、1 行目の位置 (130 → 152) と題の位置
|
|
52
|
+
(78 → 86) も取り直した。 値は `layout/spec.ts` が SSOT で、検査もそこから引く。
|
|
53
|
+
|
|
54
|
+
- **横に並ぶ箱を段の芯で揃えるようにした** (#580)
|
|
55
|
+
|
|
56
|
+
#578 では上端で揃えていたが、高さの違う箱が並ぶと背の低い箱ほど上に寄り、図全体が上へ
|
|
57
|
+
引っ張られて見えた。 芯で揃えると上端と下端は箱ごとに違うが、並びの重心が 1 本に通る。
|
|
58
|
+
|
|
59
|
+
見た目検査の `row-alignment` を厳しい側 (芯のみ) に戻した。 #578 で上端も認めていたのは
|
|
60
|
+
この揃え方に合わせたもので、前提が消えたので外す。
|
|
61
|
+
|
|
62
|
+
- **格子に置く箱では縦の間隔の均一を求めないようにした** (#580)
|
|
63
|
+
|
|
64
|
+
`column-gap-uniform` は「engine が縦の間隔を制御している」 ことを前提に、そのばらつきを
|
|
65
|
+
layout の破綻として見る軸。 行頭の印を持つ箱は前提が違う = 段の位置を著者が `col` / `row`
|
|
66
|
+
で決め、高さは中身から出る (`autoStorageHeight`)。 段ごとに背が違えば間隔は必ずばらつく
|
|
67
|
+
(実測 = クラス図の 2 列目で端 132/216)。
|
|
68
|
+
|
|
69
|
+
**近づき過ぎだけは見る**。 均一を外しても、箱どうしが接する形は通さない
|
|
70
|
+
(#202 が実測した形)。
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
|
|
74
|
+
- **「いまどこか」 の色を意味の色と分けた** (#580)
|
|
75
|
+
|
|
76
|
+
順序図の板が引く朱を `--cdl-now` から取り、書かれていなければ従来どおり
|
|
77
|
+
`--cdl-tone-accent` に落ちる。
|
|
78
|
+
|
|
79
|
+
意味の 6 色は図の中で「呼び」 のような種類を描き分けるもので、利用側が系統色から取ることが
|
|
80
|
+
ある (実測 = dragon は青)。 板が指すのは意味ではなく「いまどこか」 で、役割は強調した箱の枠と
|
|
81
|
+
同じ = 利用側の主役色に揃うべき。
|
|
82
|
+
|
|
8
83
|
## [0.17.0] - 2026-08-28
|
|
9
84
|
|
|
10
85
|
### Added
|
|
@@ -870,7 +945,9 @@ Initial OSS release.
|
|
|
870
945
|
使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
|
|
871
946
|
行き止まりになる。
|
|
872
947
|
|
|
873
|
-
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.
|
|
948
|
+
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.18.0...HEAD
|
|
949
|
+
[0.18.0]: https://github.com/cardene777/cdl/compare/v0.17.1...v0.18.0
|
|
950
|
+
[0.17.1]: https://github.com/cardene777/cdl/compare/v0.17.0...v0.17.1
|
|
874
951
|
[0.17.0]: https://github.com/cardene777/cdl/compare/v0.16.0...v0.17.0
|
|
875
952
|
[0.16.0]: https://github.com/cardene777/cdl/compare/v0.15.0...v0.16.0
|
|
876
953
|
[0.15.0]: https://github.com/cardene777/cdl/compare/v0.14.0...v0.15.0
|
package/dist/index.cjs
CHANGED
|
@@ -11803,7 +11803,7 @@ function genericTextCentered(kind, hasRows) {
|
|
|
11803
11803
|
function genericTitleBaselineY(kind, h, hasRows) {
|
|
11804
11804
|
return genericTextCentered(kind, hasRows) ? h / 2 + GENERIC_TITLE_CENTER_OFFSET : GENERIC_TITLE_TOP + genericTextShift(kind);
|
|
11805
11805
|
}
|
|
11806
|
-
var ROW_TOP_STORAGE =
|
|
11806
|
+
var ROW_TOP_STORAGE = 152;
|
|
11807
11807
|
var ROW_PITCH_STORAGE = 56;
|
|
11808
11808
|
var ROW_TOP_GENERIC = 100;
|
|
11809
11809
|
var ROW_PITCH_GENERIC = 28;
|
|
@@ -11814,7 +11814,8 @@ var GENERIC_TITLE_FONT = 20;
|
|
|
11814
11814
|
var GLYPH_CAP_RATIO = 0.72;
|
|
11815
11815
|
var ROW_FONT_STORAGE = 26;
|
|
11816
11816
|
var ROW_FONT_GENERIC = 21;
|
|
11817
|
-
var STORAGE_TITLE_BASELINE =
|
|
11817
|
+
var STORAGE_TITLE_BASELINE = 86;
|
|
11818
|
+
var STORAGE_TITLE_FONT = 34;
|
|
11818
11819
|
var SUBTITLE_ROW_SHIFT = 46;
|
|
11819
11820
|
var STORAGE_ROW_DIVIDER_Y = Math.round(
|
|
11820
11821
|
(STORAGE_TITLE_BASELINE + (ROW_TOP_STORAGE - ROW_FONT_STORAGE * GLYPH_CAP_RATIO)) / 2
|
|
@@ -15182,7 +15183,7 @@ function layoutNodes(diag, lanes) {
|
|
|
15182
15183
|
const \u6BB5\u306E\u9AD8\u3055 = rowH.get(n.stack);
|
|
15183
15184
|
const \u81EA\u524D\u306E\u9AD8\u3055 = n.rowMarks !== void 0;
|
|
15184
15185
|
const h = n.h ?? (\u81EA\u524D\u306E\u9AD8\u3055 ? autoStorageHeight(n, size.h) : \u6BB5\u306E\u9AD8\u3055);
|
|
15185
|
-
const cy = \
|
|
15186
|
+
const cy = \u6BB5\u306E\u82AF;
|
|
15186
15187
|
const w = autoRowsWidth(n, size.w);
|
|
15187
15188
|
out.push({
|
|
15188
15189
|
...n,
|
|
@@ -15372,6 +15373,8 @@ function layout(diag) {
|
|
|
15372
15373
|
states: diag.states,
|
|
15373
15374
|
phases: diag.phases,
|
|
15374
15375
|
...diag.derived ? { derived: diag.derived } : {},
|
|
15376
|
+
// 矢印をいつ出すか (#582)。 描き手が読む欄なので、そのまま持ち越す
|
|
15377
|
+
...diag.edgeReveal ? { edgeReveal: diag.edgeReveal } : {},
|
|
15375
15378
|
bboxes,
|
|
15376
15379
|
collisions,
|
|
15377
15380
|
nearCollisions,
|
|
@@ -15530,6 +15533,8 @@ var EDGE_HEADS = [
|
|
|
15530
15533
|
];
|
|
15531
15534
|
var EDGE_HEAD_FILL_DEFAULT = "solid";
|
|
15532
15535
|
var EDGE_HEAD_FILLS = ["solid", "hollow"];
|
|
15536
|
+
var EDGE_REVEALS = ["phase", "all"];
|
|
15537
|
+
var EDGE_REVEAL_DEFAULT = "phase";
|
|
15533
15538
|
|
|
15534
15539
|
// src/anim/core/easing.ts
|
|
15535
15540
|
function cubicBezier(x1, y1, x2, y2) {
|
|
@@ -18681,11 +18686,9 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes) {
|
|
|
18681
18686
|
for (const [stack, group] of byStack) {
|
|
18682
18687
|
if (group.length < 2) continue;
|
|
18683
18688
|
const cy0 = group[0].cy;
|
|
18684
|
-
const top0 = cy0 - (group[0].h ?? 0) / 2;
|
|
18685
18689
|
for (const n of group.slice(1)) {
|
|
18686
18690
|
const diff = Math.abs(n.cy - cy0);
|
|
18687
|
-
|
|
18688
|
-
if (diff > MIN_ROW_ALIGNMENT_TOLERANCE && topDiff > MIN_ROW_ALIGNMENT_TOLERANCE) {
|
|
18691
|
+
if (diff > MIN_ROW_ALIGNMENT_TOLERANCE) {
|
|
18689
18692
|
push(
|
|
18690
18693
|
"row-alignment",
|
|
18691
18694
|
`stack=${stack} row \u5185 node "${n.id}" cy=${n.cy.toFixed(1)} \u304C row \u57FA\u6E96 cy=${cy0.toFixed(1)} \u3068 ${diff.toFixed(1)} world \u5DEE (\u8A31\u5BB9 ${MIN_ROW_ALIGNMENT_TOLERANCE})`
|
|
@@ -19734,18 +19737,24 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes) {
|
|
|
19734
19737
|
if (group.length < 3) continue;
|
|
19735
19738
|
const sorted = [...group].sort((a, b) => a.cy - b.cy);
|
|
19736
19739
|
const gaps = [];
|
|
19737
|
-
const tops = [];
|
|
19738
19740
|
for (let i = 1; i < sorted.length; i++) {
|
|
19739
19741
|
const prev = sorted[i - 1];
|
|
19740
19742
|
const cur = sorted[i];
|
|
19741
19743
|
gaps.push(cur.cy - cur.h / 2 - (prev.cy + prev.h / 2));
|
|
19742
|
-
tops.push(cur.cy - cur.h / 2 - (prev.cy - prev.h / 2));
|
|
19743
19744
|
}
|
|
19744
19745
|
const maxGap = Math.max(...gaps);
|
|
19745
19746
|
const minGap = Math.min(...gaps);
|
|
19746
19747
|
const variance = maxGap - minGap;
|
|
19747
|
-
const
|
|
19748
|
-
|
|
19748
|
+
const \u683C\u5B50\u306B\u7F6E\u304F = group.every((n) => n.rowMarks !== void 0);
|
|
19749
|
+
const \u7AEF\u304C\u8DB3\u308A\u3066\u3044\u308B = minGap >= requiredNearClearance("node", "node");
|
|
19750
|
+
if (\u683C\u5B50\u306B\u7F6E\u304F) {
|
|
19751
|
+
if (!\u7AEF\u304C\u8DB3\u308A\u3066\u3044\u308B) {
|
|
19752
|
+
push(
|
|
19753
|
+
"column-gap-uniform",
|
|
19754
|
+
`lane "${laneId}" \u5185 node \u9593\u306E\u7AEF\u9593 gap ${minGap.toFixed(0)} world \u304C\u4E0B\u9650 ${requiredNearClearance("node", "node")} \u3092\u5272\u308B`
|
|
19755
|
+
);
|
|
19756
|
+
}
|
|
19757
|
+
} else if (variance > COLUMN_GAP_VARIANCE_TOL) {
|
|
19749
19758
|
push(
|
|
19750
19759
|
"column-gap-uniform",
|
|
19751
19760
|
`lane "${laneId}" \u5185 node \u9593\u306E\u7AEF\u9593 gap variance ${variance.toFixed(1)} world \u304C spec ${COLUMN_GAP_VARIANCE_TOL} \u8D85\u904E (min=${minGap.toFixed(0)} max=${maxGap.toFixed(0)})`
|
|
@@ -21689,7 +21698,7 @@ function SequenceBoardNode({
|
|
|
21689
21698
|
const v = Number.parseInt(interpolate(node.sequenceStep, stateValues ?? {}).trim(), 10);
|
|
21690
21699
|
return Number.isFinite(v) ? v : null;
|
|
21691
21700
|
})();
|
|
21692
|
-
const \u6731 = "var(--cdl-tone-accent, #2d6a8f)";
|
|
21701
|
+
const \u6731 = "var(--cdl-now, var(--cdl-tone-accent, #2d6a8f))";
|
|
21693
21702
|
const \u58A8 = "var(--cdl-text-2, #4a5162)";
|
|
21694
21703
|
const \u898B\u305F\u76EE = (i) => {
|
|
21695
21704
|
if (\u73FE\u5728 === null) return { opacity: 1, color: \u6731 };
|
|
@@ -21983,9 +21992,9 @@ function FunctionNode({ node, active }) {
|
|
|
21983
21992
|
var ROW_GLYPH_HALF = 7;
|
|
21984
21993
|
var ROW_GLYPH_CX = ROW_PAD_X_PX + ROW_GLYPH_HALF + 1;
|
|
21985
21994
|
var ROW_GLYPH_LEAD = 40;
|
|
21986
|
-
var ROW_TYPE_FONT =
|
|
21987
|
-
var SUBTITLE_BASELINE =
|
|
21988
|
-
var SUBTITLE_FONT =
|
|
21995
|
+
var ROW_TYPE_FONT = 22;
|
|
21996
|
+
var SUBTITLE_BASELINE = 118;
|
|
21997
|
+
var SUBTITLE_FONT = 20;
|
|
21989
21998
|
var UNDERLINE_DROP = 7;
|
|
21990
21999
|
function RowGlyph({ mark, x, y, color }) {
|
|
21991
22000
|
const \u534A = ROW_GLYPH_HALF;
|
|
@@ -22012,7 +22021,7 @@ function StorageNode({
|
|
|
22012
22021
|
const accent = nodeAccent(node, "var(--cdl-tone-accent, #2d6a8f)");
|
|
22013
22022
|
const x = node.cx - node.w / 2;
|
|
22014
22023
|
const y = node.cy - node.h / 2;
|
|
22015
|
-
const \u540D\u524D = titlePlacement(node, { x: 26, y: STORAGE_TITLE_BASELINE, size:
|
|
22024
|
+
const \u540D\u524D = titlePlacement(node, { x: 26, y: STORAGE_TITLE_BASELINE, size: STORAGE_TITLE_FONT }, { hasEyebrow: Boolean(node.eyebrow) });
|
|
22016
22025
|
const splits = rows.map((r) => splitRow(r));
|
|
22017
22026
|
const leftMaxWidth = splits.reduce((m, s) => Math.max(m, displayWidth(s.left)), 0);
|
|
22018
22027
|
const rightColX = ROW_PAD_X_PX + leftMaxWidth * STORAGE_CHAR_ADVANCE_PX + STORAGE_COL_GAP_PX;
|
|
@@ -28798,6 +28807,19 @@ function CdlStage({
|
|
|
28798
28807
|
svgRef
|
|
28799
28808
|
}) {
|
|
28800
28809
|
const activeSet = new Set(currentPhase?.activate ?? []);
|
|
28810
|
+
const \u51FA\u756A\u306E\u6765\u305F\u77E2\u5370 = react.useMemo(() => {
|
|
28811
|
+
if ((laid.edgeReveal ?? EDGE_REVEAL_DEFAULT) === "all") return () => true;
|
|
28812
|
+
const \u521D\u51FA = /* @__PURE__ */ new Map();
|
|
28813
|
+
laid.phases.forEach((p, i) => {
|
|
28814
|
+
for (const id of p.activate ?? []) if (!\u521D\u51FA.has(id)) \u521D\u51FA.set(id, i);
|
|
28815
|
+
});
|
|
28816
|
+
const \u4ECA = currentPhase === void 0 ? -1 : laid.phases.findIndex((p) => p.id === currentPhase.id);
|
|
28817
|
+
return (edgeId) => {
|
|
28818
|
+
const first = \u521D\u51FA.get(edgeId);
|
|
28819
|
+
if (first === void 0) return true;
|
|
28820
|
+
return \u4ECA < 0 || \u4ECA >= first;
|
|
28821
|
+
};
|
|
28822
|
+
}, [laid.phases, currentPhase]);
|
|
28801
28823
|
const drawSet = new Set(currentPhase?.draw ?? []);
|
|
28802
28824
|
const \u63CF\u304F\u9032\u307F = \u63CF\u304F\u9032\u307F\u306B\u76F4\u3059(progress, currentPhase?.drawRatio);
|
|
28803
28825
|
const { lifelineStarts, uniformFooterTop } = react.useMemo(() => {
|
|
@@ -28957,7 +28979,7 @@ function CdlStage({
|
|
|
28957
28979
|
},
|
|
28958
28980
|
lane.id
|
|
28959
28981
|
)),
|
|
28960
|
-
laid.edges.map((edge) => /* @__PURE__ */ jsxRuntime.jsx(CdlEdgeView, { edge, active: activeSet.has(edge.id), progress, stateValues }, edge.id)),
|
|
28982
|
+
laid.edges.filter((edge) => \u51FA\u756A\u306E\u6765\u305F\u77E2\u5370(edge.id)).map((edge) => /* @__PURE__ */ jsxRuntime.jsx(CdlEdgeView, { edge, active: activeSet.has(edge.id), progress, stateValues }, edge.id)),
|
|
28961
28983
|
laid.nodes.map((node) => {
|
|
28962
28984
|
const \u63CF\u304F = drawSet.has(node.id);
|
|
28963
28985
|
const view = /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -28973,8 +28995,8 @@ function CdlStage({
|
|
|
28973
28995
|
);
|
|
28974
28996
|
return /* @__PURE__ */ jsxRuntime.jsx("g", { children: view }, node.id);
|
|
28975
28997
|
}),
|
|
28976
|
-
laid.edges.filter((edge) => Boolean(edge.dThrough)).map((edge) => /* @__PURE__ */ jsxRuntime.jsx(CdlEdgeGlowView, { edge, active: activeSet.has(edge.id) }, `glow-${edge.id}`)),
|
|
28977
|
-
laid.edges.map((edge) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
28998
|
+
laid.edges.filter((edge) => Boolean(edge.dThrough) && \u51FA\u756A\u306E\u6765\u305F\u77E2\u5370(edge.id)).map((edge) => /* @__PURE__ */ jsxRuntime.jsx(CdlEdgeGlowView, { edge, active: activeSet.has(edge.id) }, `glow-${edge.id}`)),
|
|
28999
|
+
laid.edges.filter((edge) => \u51FA\u756A\u306E\u6765\u305F\u77E2\u5370(edge.id)).map((edge) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
28978
29000
|
CdlEdgeLabelView,
|
|
28979
29001
|
{
|
|
28980
29002
|
edge,
|
|
@@ -30560,6 +30582,8 @@ exports.EDGE_HEAD_DEFAULT = EDGE_HEAD_DEFAULT;
|
|
|
30560
30582
|
exports.EDGE_HEAD_FILLS = EDGE_HEAD_FILLS;
|
|
30561
30583
|
exports.EDGE_HEAD_FILL_DEFAULT = EDGE_HEAD_FILL_DEFAULT;
|
|
30562
30584
|
exports.EDGE_LABEL_TEXT = EDGE_LABEL_TEXT;
|
|
30585
|
+
exports.EDGE_REVEALS = EDGE_REVEALS;
|
|
30586
|
+
exports.EDGE_REVEAL_DEFAULT = EDGE_REVEAL_DEFAULT;
|
|
30563
30587
|
exports.EDGE_STUB_OUT = EDGE_STUB_OUT;
|
|
30564
30588
|
exports.EDGE_STYLES = EDGE_STYLES;
|
|
30565
30589
|
exports.ER_CARDINALITY_HEAD = ER_CARDINALITY_HEAD;
|