@cardenelabs/cdl 0.121.0 → 0.123.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 +51 -1
- package/README.md +137 -0
- package/SPEC.md +1 -1
- package/dist/index.cjs +1513 -667
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -33
- package/dist/index.d.ts +51 -33
- package/dist/index.js +1513 -668
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1271 -444
- 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 +1271 -444
- package/dist/react.js.map +1 -1
- package/dist/{render-A5AKjNuy.d.cts → render-CVczwfRb.d.cts} +40 -7
- package/dist/{render-A5AKjNuy.d.ts → render-CVczwfRb.d.ts} +40 -7
- package/package.json +9 -12
- package/src/builder.ts +8 -2
- package/src/index.ts +3 -0
- package/src/kinds/box-lines.ts +17 -4
- package/src/kinds/chart-bar.tsx +4 -0
- package/src/kinds/chart-gauge.tsx +20 -9
- package/src/kinds/chart-pie.tsx +67 -17
- package/src/kinds/chart-radial.tsx +7 -2
- package/src/kinds/chart-slope.tsx +26 -7
- package/src/kinds/chart-stacked-bar.tsx +8 -4
- package/src/kinds/chart-stat.tsx +19 -4
- package/src/kinds/chart-waffle.tsx +7 -2
- package/src/kinds/dyn-shape.tsx +22 -9
- package/src/kinds/funnel.tsx +9 -2
- package/src/kinds/generic.tsx +5 -2
- package/src/kinds/mind-map.tsx +26 -10
- package/src/kinds/quadrant.tsx +14 -4
- package/src/kinds/row-align.ts +19 -7
- package/src/kinds/sequence-board-metrics.ts +13 -3
- package/src/kinds/sequence-board.tsx +4 -2
- package/src/kinds/shape-basement.tsx +57 -32
- package/src/kinds/shape-blockchain.tsx +83 -34
- package/src/kinds/shape-commerce.tsx +65 -24
- package/src/kinds/shape-finance.tsx +90 -26
- package/src/kinds/shape-hardware.tsx +48 -17
- package/src/kinds/shape-region.tsx +16 -6
- package/src/kinds/shape-software.tsx +30 -8
- package/src/kinds/station.tsx +29 -0
- package/src/kinds/text-width.ts +17 -3
- package/src/kinds/tree.tsx +25 -7
- package/src/layout/collisions.ts +50 -28
- package/src/layout/curve-path.ts +126 -0
- package/src/layout/edges.ts +271 -58
- package/src/layout/head-label.ts +11 -5
- package/src/layout/lanes.ts +3 -2
- package/src/layout/metro-path.ts +185 -0
- package/src/layout/nodes.ts +14 -6
- package/src/layout/predict-bbox.ts +6 -3
- package/src/layout/self-loop.ts +10 -4
- package/src/layout/spec.ts +36 -7
- package/src/layout/text-width.ts +25 -8
- package/src/layout/tokens.ts +2 -0
- package/src/layout-with-validation.ts +10 -5
- package/src/layout.ts +55 -21
- package/src/presets.ts +69 -43
- package/src/render/edges.tsx +19 -3
- package/src/render/interactive-panel.tsx +34 -7
- package/src/render/nodes.tsx +100 -48
- package/src/render/stage.tsx +3 -0
- package/src/text-metrics.ts +9 -0
- package/src/types.ts +41 -4
- package/src/visual-validate.ts +91 -21
|
@@ -88,7 +88,7 @@ type SequenceBoardMetrics = {
|
|
|
88
88
|
* 幅は **語の桁 + 列 × 面の数**。 語を線の脇ではなく左の桁に置くので、線の長さが語の長さに
|
|
89
89
|
* 引きずられない = 面の数だけで横幅が決まる。
|
|
90
90
|
*/
|
|
91
|
-
declare function sequenceBoardMetrics(data: SequenceBoardData): SequenceBoardMetrics;
|
|
91
|
+
declare function sequenceBoardMetrics(data: SequenceBoardData, textMetrics?: CdlTextMetrics): SequenceBoardMetrics;
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* 描画側が書く固定の字の言語 (#847)。
|
|
@@ -117,8 +117,16 @@ declare function resolveLang(value: unknown): CdlLang;
|
|
|
117
117
|
/** 意味付きの色の名前。 検査・描画・test はこの 1 つの列を出所にする。 */
|
|
118
118
|
declare const TONES: readonly ["accent", "teal", "success", "error", "warning", "info"];
|
|
119
119
|
type Tone = (typeof TONES)[number];
|
|
120
|
+
/**
|
|
121
|
+
* 図の字幅をどの規則で測るか。`"proportional"` は現在の Inter 比例幅表、`"monospace"` は
|
|
122
|
+
* 等幅書体向けの幅を使う。既定は `"proportional"`。
|
|
123
|
+
*
|
|
124
|
+
* 消費側が図を等幅書体で描く場合、比例幅で配置すると英数字の描画幅と箱・札の計算幅が
|
|
125
|
+
* 食い違うため、図単位で測り方を揃えられるようにする。
|
|
126
|
+
*/
|
|
127
|
+
type CdlTextMetrics = "proportional" | "monospace";
|
|
120
128
|
/** 描画できる箱の種類。 検査・記法一覧・型はこの 1 つの列を出所にする。 */
|
|
121
|
-
declare const NODE_KINDS: readonly ["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon", "actor", "function", "storage", "event", "card", "person", "user-group", "admin", "developer", "external-user", "database", "cache", "queue", "message-bus", "cloud", "cdn", "service", "api", "frontend", "backend", "webhook", "microservice", "signer", "oracle", "merkle-tree", "decision", "chart-pie", "chart-line", "chart-bar", "chart-gauge", "chart-radial", "chart-stat", "chart-waffle", "chart-stacked-bar", "chart-slope", "gantt-timeline", "mind-map", "funnel-stages", "quadrant-matrix", "tree-hierarchy", "journey-map", "shape-file", "shape-folder", "shape-cloud", "shape-cylinder", "shape-hexagon", "shape-diamond", "shape-stack", "shape-person", "shape-window", "shape-terminal", "shape-code-block", "shape-kanban-card", "shape-message-bubble", "shape-gear", "shape-server-rack", "shape-network-node", "shape-mobile-device", "shape-iot-sensor", "shape-robot-arm", "shape-satellite", "shape-smart-contract", "shape-blockchain-block", "shape-rpc-node", "shape-wallet", "shape-nft", "shape-token", "shape-blockchain", "shape-bitcoin-chain", "shape-ethereum-chain", "shape-blockchain-node", "shape-bank", "shape-trust-bank", "shape-payment-provider", "shape-credit-card", "shape-brokerage", "shape-exchange", "shape-atm", "shape-website", "shape-storefront", "shape-warehouse", "shape-online-shop", "shape-cdn-edge", "shape-api-gateway", "shape-auditor", "shape-regulator", "shape-notary", "shape-lawyer", "shape-trader", "shape-customer-service", "mark-start", "mark-end", "sequence-board"];
|
|
129
|
+
declare const NODE_KINDS: readonly ["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon", "actor", "function", "storage", "event", "card", "person", "user-group", "admin", "developer", "external-user", "database", "cache", "queue", "message-bus", "cloud", "cdn", "service", "api", "frontend", "backend", "webhook", "microservice", "signer", "oracle", "merkle-tree", "decision", "chart-pie", "chart-line", "chart-bar", "chart-gauge", "chart-radial", "chart-stat", "chart-waffle", "chart-stacked-bar", "chart-slope", "gantt-timeline", "mind-map", "funnel-stages", "quadrant-matrix", "tree-hierarchy", "journey-map", "shape-file", "shape-folder", "shape-cloud", "shape-cylinder", "shape-hexagon", "shape-diamond", "shape-stack", "shape-person", "shape-window", "shape-terminal", "shape-code-block", "shape-kanban-card", "shape-message-bubble", "shape-gear", "shape-server-rack", "shape-network-node", "shape-mobile-device", "shape-iot-sensor", "shape-robot-arm", "shape-satellite", "shape-smart-contract", "shape-blockchain-block", "shape-rpc-node", "shape-wallet", "shape-nft", "shape-token", "shape-blockchain", "shape-bitcoin-chain", "shape-ethereum-chain", "shape-blockchain-node", "shape-bank", "shape-trust-bank", "shape-payment-provider", "shape-credit-card", "shape-brokerage", "shape-exchange", "shape-atm", "shape-website", "shape-storefront", "shape-warehouse", "shape-online-shop", "shape-cdn-edge", "shape-api-gateway", "shape-auditor", "shape-regulator", "shape-notary", "shape-lawyer", "shape-trader", "shape-customer-service", "mark-start", "mark-end", "station", "sequence-board"];
|
|
122
130
|
type NodeKind = (typeof NODE_KINDS)[number];
|
|
123
131
|
type Side = "top" | "right" | "bottom" | "left";
|
|
124
132
|
/**
|
|
@@ -133,6 +141,17 @@ type Side = "top" | "right" | "bottom" | "left";
|
|
|
133
141
|
* ER の「識別しない」 のように **刻みが意味を持つ関係** はこちらを使う。
|
|
134
142
|
*/
|
|
135
143
|
type EdgeStyle = "solid" | "dotted-flow" | "dashed";
|
|
144
|
+
/**
|
|
145
|
+
* 線の道筋。
|
|
146
|
+
*
|
|
147
|
+
* - `"default"` ... 自動。 箱を避け、角を丸めた直角の線を引く。 書かない時も同じ
|
|
148
|
+
* - `"back-detour"` ... 箱の上を回って前の箱へ戻る
|
|
149
|
+
* - `"curve"` ... 始点から水平に出て終点へ水平に入る 3 次曲線。 途中の箱は避けず、
|
|
150
|
+
* 2 点が同じ高さなら直線になる。 終点の矢印は水平を向く
|
|
151
|
+
* - `"metro"` ... 横線と傾き ±1 の斜線だけで結び、角を半径 r の円弧で丸める。
|
|
152
|
+
* 途中の箱は避けず、2 点が同じ高さなら横 1 本になる
|
|
153
|
+
*/
|
|
154
|
+
type EdgeRouting = "default" | "back-detour" | "curve" | "metro";
|
|
136
155
|
/** 辺の役目 (#618)。 `main` = 図の主となる道 */
|
|
137
156
|
type EdgeRole = "main";
|
|
138
157
|
/**
|
|
@@ -393,8 +412,8 @@ type CdlNode = {
|
|
|
393
412
|
* 変わるのは kind の既定色を使って描かれる部分で、 枠線 / eyebrow の文字色 / icon /
|
|
394
413
|
* 強調表示中の行の値。 本文の文字色と背景は変わらない。
|
|
395
414
|
*
|
|
396
|
-
* 効くのは `actor` / `function` / `storage` / `event` / `card
|
|
397
|
-
*
|
|
415
|
+
* 効くのは `actor` / `function` / `storage` / `event` / `card`、`person` 以降の汎用 kind、
|
|
416
|
+
* 流れの印、路線図の駅。 それ以外は自前の配色を持つため指定しても変わらず、検査も通す。
|
|
398
417
|
* 一覧は `test/node-styling.test.tsx` が実装から計算した集合と突き合わせている。
|
|
399
418
|
*
|
|
400
419
|
* 既定色と同じ名前を明示指定しても色が変わる kind がある (既定色の hex が `render/tone.ts`
|
|
@@ -746,8 +765,12 @@ type CdlEdge = {
|
|
|
746
765
|
labelOffsetX?: number;
|
|
747
766
|
/** label の y 方向 fine offset (default 0、 + で下、 - で上) */
|
|
748
767
|
labelOffsetY?: number;
|
|
749
|
-
/**
|
|
750
|
-
|
|
768
|
+
/**
|
|
769
|
+
* 線の道筋。 `default` は箱を避ける自動経路、 `back-detour` は箱の上を回る戻り線、
|
|
770
|
+
* `curve` は途中の箱を避けず、両端で水平になる 3 次曲線。 `metro` は途中の箱を避けず、
|
|
771
|
+
* 横線と傾き ±1 の斜線を半径 r の円弧で結ぶ。2 点が同じ高さなら横 1 本。書かなければ `default`。
|
|
772
|
+
*/
|
|
773
|
+
routing?: EdgeRouting;
|
|
751
774
|
/**
|
|
752
775
|
* CAR-549 SSOT ... label を edge path 上に「被せる」 か「離す」 かの制御 flag。
|
|
753
776
|
* default (false or undefined) = LABEL_INIT_CLEARANCE (34 world、 CAR-630 で 26 → 34 復帰) 離して配置。
|
|
@@ -2608,6 +2631,14 @@ type CdlDiagram = {
|
|
|
2608
2631
|
* 型の外の値は `layout` が既定に落とす (記法から文字列で届く場合の書き損じ)。
|
|
2609
2632
|
*/
|
|
2610
2633
|
lang?: CdlLang;
|
|
2634
|
+
/**
|
|
2635
|
+
* 図の字幅を測る規則。`"proportional"` または `"monospace"` を取り、既定は
|
|
2636
|
+
* `"proportional"`。
|
|
2637
|
+
*
|
|
2638
|
+
* 消費側が等幅書体で描く図では、比例幅の配置計算と実際の描画幅が食い違うため指定する。
|
|
2639
|
+
* 型の外の値は `layout` が既定へ落とす。
|
|
2640
|
+
*/
|
|
2641
|
+
textMetrics?: CdlTextMetrics;
|
|
2611
2642
|
/**
|
|
2612
2643
|
* この図がどの種類か (#645)。 書かない図は種類を持たない。
|
|
2613
2644
|
*
|
|
@@ -2833,6 +2864,8 @@ type LaidDiagram = {
|
|
|
2833
2864
|
* 無い時は `"en"` で描く。
|
|
2834
2865
|
*/
|
|
2835
2866
|
lang?: CdlLang;
|
|
2867
|
+
/** 等幅で測る図だけが持つ。無い時は `"proportional"` */
|
|
2868
|
+
textMetrics?: "monospace";
|
|
2836
2869
|
/** どの種類の図か (#645)。 `CdlDiagram.type` をそのまま持ち越す */
|
|
2837
2870
|
type?: string;
|
|
2838
2871
|
viewBox: {
|
|
@@ -3035,4 +3068,4 @@ type CdlDiagramViewProps = {
|
|
|
3035
3068
|
};
|
|
3036
3069
|
declare function CdlDiagramView({ diagram, laid: laidProp, hideHeader, hideMiniPhaseIndicator, focusPhaseId, debug, emitGeometryWarn, headingLevel, interactiveHandlers }: CdlDiagramViewProps): JSX.Element;
|
|
3037
3070
|
|
|
3038
|
-
export {
|
|
3071
|
+
export { type ScrollProgressHandle as $, type ChartPieForm as A, type BBox as B, type CdlDiagram as C, type ChartSlopeForm as D, type EdgeStyle as E, EDGE_HEADS as F, EDGE_HEAD_DEFAULT as G, EDGE_HEAD_FILLS as H, EDGE_HEAD_FILL_DEFAULT as I, type JourneyEmotion as J, EDGE_REVEALS as K, type LaidDiagram as L, EDGE_REVEAL_DEFAULT as M, type NodeKind as N, EDGE_STYLES as O, type EdgeReveal as P, type QuadrantKey as Q, type RowMark as R, type Signal as S, type Tone as T, type InteractiveHandlerMap as U, type InteractiveSignalsAccessor as V, type LaidLane as W, NODE_KINDS as X, RELATION_FOCUSES as Y, RELATION_FOCUS_DEFAULT as Z, type RelationFocus as _, type CdlInput as a, TONES as a0, computeEventBindingKey as a1, computeFormulaKey as a2, computeInputSignalKey as a3, computeScrollTriggerKey as a4, computed as a5, createInteractiveSignalsAccessor as a6, createScrollProgressHandle as a7, createScrollProgressSignals as a8, hasInteractivePrimitives as a9, resolveLang as aa, sequenceBoardMetrics as ab, sequenceStepId as ac, signal as ad, type CdlLane as b, type CdlNode as c, type Side as d, type EdgeRole as e, type EdgeHead as f, type EdgeHeadFill as g, type EdgeRouting as h, type CdlState as i, type CdlInputOption as j, type CdlEventTarget as k, type CdlLang as l, type CdlTextMetrics as m, type Computed as n, type CdlDerivedValue as o, type CdlScrollTrigger as p, type CdlDiagramViewProps as q, type LaidEdge as r, type LaidNode as s, type CdlEdge as t, type TreeNodePayload as u, CdlDiagramView as v, type CdlEventBinding as w, type CdlEventKind as x, type CdlFormula as y, type CdlPhase as z };
|
|
@@ -88,7 +88,7 @@ type SequenceBoardMetrics = {
|
|
|
88
88
|
* 幅は **語の桁 + 列 × 面の数**。 語を線の脇ではなく左の桁に置くので、線の長さが語の長さに
|
|
89
89
|
* 引きずられない = 面の数だけで横幅が決まる。
|
|
90
90
|
*/
|
|
91
|
-
declare function sequenceBoardMetrics(data: SequenceBoardData): SequenceBoardMetrics;
|
|
91
|
+
declare function sequenceBoardMetrics(data: SequenceBoardData, textMetrics?: CdlTextMetrics): SequenceBoardMetrics;
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* 描画側が書く固定の字の言語 (#847)。
|
|
@@ -117,8 +117,16 @@ declare function resolveLang(value: unknown): CdlLang;
|
|
|
117
117
|
/** 意味付きの色の名前。 検査・描画・test はこの 1 つの列を出所にする。 */
|
|
118
118
|
declare const TONES: readonly ["accent", "teal", "success", "error", "warning", "info"];
|
|
119
119
|
type Tone = (typeof TONES)[number];
|
|
120
|
+
/**
|
|
121
|
+
* 図の字幅をどの規則で測るか。`"proportional"` は現在の Inter 比例幅表、`"monospace"` は
|
|
122
|
+
* 等幅書体向けの幅を使う。既定は `"proportional"`。
|
|
123
|
+
*
|
|
124
|
+
* 消費側が図を等幅書体で描く場合、比例幅で配置すると英数字の描画幅と箱・札の計算幅が
|
|
125
|
+
* 食い違うため、図単位で測り方を揃えられるようにする。
|
|
126
|
+
*/
|
|
127
|
+
type CdlTextMetrics = "proportional" | "monospace";
|
|
120
128
|
/** 描画できる箱の種類。 検査・記法一覧・型はこの 1 つの列を出所にする。 */
|
|
121
|
-
declare const NODE_KINDS: readonly ["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon", "actor", "function", "storage", "event", "card", "person", "user-group", "admin", "developer", "external-user", "database", "cache", "queue", "message-bus", "cloud", "cdn", "service", "api", "frontend", "backend", "webhook", "microservice", "signer", "oracle", "merkle-tree", "decision", "chart-pie", "chart-line", "chart-bar", "chart-gauge", "chart-radial", "chart-stat", "chart-waffle", "chart-stacked-bar", "chart-slope", "gantt-timeline", "mind-map", "funnel-stages", "quadrant-matrix", "tree-hierarchy", "journey-map", "shape-file", "shape-folder", "shape-cloud", "shape-cylinder", "shape-hexagon", "shape-diamond", "shape-stack", "shape-person", "shape-window", "shape-terminal", "shape-code-block", "shape-kanban-card", "shape-message-bubble", "shape-gear", "shape-server-rack", "shape-network-node", "shape-mobile-device", "shape-iot-sensor", "shape-robot-arm", "shape-satellite", "shape-smart-contract", "shape-blockchain-block", "shape-rpc-node", "shape-wallet", "shape-nft", "shape-token", "shape-blockchain", "shape-bitcoin-chain", "shape-ethereum-chain", "shape-blockchain-node", "shape-bank", "shape-trust-bank", "shape-payment-provider", "shape-credit-card", "shape-brokerage", "shape-exchange", "shape-atm", "shape-website", "shape-storefront", "shape-warehouse", "shape-online-shop", "shape-cdn-edge", "shape-api-gateway", "shape-auditor", "shape-regulator", "shape-notary", "shape-lawyer", "shape-trader", "shape-customer-service", "mark-start", "mark-end", "sequence-board"];
|
|
129
|
+
declare const NODE_KINDS: readonly ["dyn-rect", "dyn-circle", "dyn-arc", "dyn-wave", "dyn-polygon", "actor", "function", "storage", "event", "card", "person", "user-group", "admin", "developer", "external-user", "database", "cache", "queue", "message-bus", "cloud", "cdn", "service", "api", "frontend", "backend", "webhook", "microservice", "signer", "oracle", "merkle-tree", "decision", "chart-pie", "chart-line", "chart-bar", "chart-gauge", "chart-radial", "chart-stat", "chart-waffle", "chart-stacked-bar", "chart-slope", "gantt-timeline", "mind-map", "funnel-stages", "quadrant-matrix", "tree-hierarchy", "journey-map", "shape-file", "shape-folder", "shape-cloud", "shape-cylinder", "shape-hexagon", "shape-diamond", "shape-stack", "shape-person", "shape-window", "shape-terminal", "shape-code-block", "shape-kanban-card", "shape-message-bubble", "shape-gear", "shape-server-rack", "shape-network-node", "shape-mobile-device", "shape-iot-sensor", "shape-robot-arm", "shape-satellite", "shape-smart-contract", "shape-blockchain-block", "shape-rpc-node", "shape-wallet", "shape-nft", "shape-token", "shape-blockchain", "shape-bitcoin-chain", "shape-ethereum-chain", "shape-blockchain-node", "shape-bank", "shape-trust-bank", "shape-payment-provider", "shape-credit-card", "shape-brokerage", "shape-exchange", "shape-atm", "shape-website", "shape-storefront", "shape-warehouse", "shape-online-shop", "shape-cdn-edge", "shape-api-gateway", "shape-auditor", "shape-regulator", "shape-notary", "shape-lawyer", "shape-trader", "shape-customer-service", "mark-start", "mark-end", "station", "sequence-board"];
|
|
122
130
|
type NodeKind = (typeof NODE_KINDS)[number];
|
|
123
131
|
type Side = "top" | "right" | "bottom" | "left";
|
|
124
132
|
/**
|
|
@@ -133,6 +141,17 @@ type Side = "top" | "right" | "bottom" | "left";
|
|
|
133
141
|
* ER の「識別しない」 のように **刻みが意味を持つ関係** はこちらを使う。
|
|
134
142
|
*/
|
|
135
143
|
type EdgeStyle = "solid" | "dotted-flow" | "dashed";
|
|
144
|
+
/**
|
|
145
|
+
* 線の道筋。
|
|
146
|
+
*
|
|
147
|
+
* - `"default"` ... 自動。 箱を避け、角を丸めた直角の線を引く。 書かない時も同じ
|
|
148
|
+
* - `"back-detour"` ... 箱の上を回って前の箱へ戻る
|
|
149
|
+
* - `"curve"` ... 始点から水平に出て終点へ水平に入る 3 次曲線。 途中の箱は避けず、
|
|
150
|
+
* 2 点が同じ高さなら直線になる。 終点の矢印は水平を向く
|
|
151
|
+
* - `"metro"` ... 横線と傾き ±1 の斜線だけで結び、角を半径 r の円弧で丸める。
|
|
152
|
+
* 途中の箱は避けず、2 点が同じ高さなら横 1 本になる
|
|
153
|
+
*/
|
|
154
|
+
type EdgeRouting = "default" | "back-detour" | "curve" | "metro";
|
|
136
155
|
/** 辺の役目 (#618)。 `main` = 図の主となる道 */
|
|
137
156
|
type EdgeRole = "main";
|
|
138
157
|
/**
|
|
@@ -393,8 +412,8 @@ type CdlNode = {
|
|
|
393
412
|
* 変わるのは kind の既定色を使って描かれる部分で、 枠線 / eyebrow の文字色 / icon /
|
|
394
413
|
* 強調表示中の行の値。 本文の文字色と背景は変わらない。
|
|
395
414
|
*
|
|
396
|
-
* 効くのは `actor` / `function` / `storage` / `event` / `card
|
|
397
|
-
*
|
|
415
|
+
* 効くのは `actor` / `function` / `storage` / `event` / `card`、`person` 以降の汎用 kind、
|
|
416
|
+
* 流れの印、路線図の駅。 それ以外は自前の配色を持つため指定しても変わらず、検査も通す。
|
|
398
417
|
* 一覧は `test/node-styling.test.tsx` が実装から計算した集合と突き合わせている。
|
|
399
418
|
*
|
|
400
419
|
* 既定色と同じ名前を明示指定しても色が変わる kind がある (既定色の hex が `render/tone.ts`
|
|
@@ -746,8 +765,12 @@ type CdlEdge = {
|
|
|
746
765
|
labelOffsetX?: number;
|
|
747
766
|
/** label の y 方向 fine offset (default 0、 + で下、 - で上) */
|
|
748
767
|
labelOffsetY?: number;
|
|
749
|
-
/**
|
|
750
|
-
|
|
768
|
+
/**
|
|
769
|
+
* 線の道筋。 `default` は箱を避ける自動経路、 `back-detour` は箱の上を回る戻り線、
|
|
770
|
+
* `curve` は途中の箱を避けず、両端で水平になる 3 次曲線。 `metro` は途中の箱を避けず、
|
|
771
|
+
* 横線と傾き ±1 の斜線を半径 r の円弧で結ぶ。2 点が同じ高さなら横 1 本。書かなければ `default`。
|
|
772
|
+
*/
|
|
773
|
+
routing?: EdgeRouting;
|
|
751
774
|
/**
|
|
752
775
|
* CAR-549 SSOT ... label を edge path 上に「被せる」 か「離す」 かの制御 flag。
|
|
753
776
|
* default (false or undefined) = LABEL_INIT_CLEARANCE (34 world、 CAR-630 で 26 → 34 復帰) 離して配置。
|
|
@@ -2608,6 +2631,14 @@ type CdlDiagram = {
|
|
|
2608
2631
|
* 型の外の値は `layout` が既定に落とす (記法から文字列で届く場合の書き損じ)。
|
|
2609
2632
|
*/
|
|
2610
2633
|
lang?: CdlLang;
|
|
2634
|
+
/**
|
|
2635
|
+
* 図の字幅を測る規則。`"proportional"` または `"monospace"` を取り、既定は
|
|
2636
|
+
* `"proportional"`。
|
|
2637
|
+
*
|
|
2638
|
+
* 消費側が等幅書体で描く図では、比例幅の配置計算と実際の描画幅が食い違うため指定する。
|
|
2639
|
+
* 型の外の値は `layout` が既定へ落とす。
|
|
2640
|
+
*/
|
|
2641
|
+
textMetrics?: CdlTextMetrics;
|
|
2611
2642
|
/**
|
|
2612
2643
|
* この図がどの種類か (#645)。 書かない図は種類を持たない。
|
|
2613
2644
|
*
|
|
@@ -2833,6 +2864,8 @@ type LaidDiagram = {
|
|
|
2833
2864
|
* 無い時は `"en"` で描く。
|
|
2834
2865
|
*/
|
|
2835
2866
|
lang?: CdlLang;
|
|
2867
|
+
/** 等幅で測る図だけが持つ。無い時は `"proportional"` */
|
|
2868
|
+
textMetrics?: "monospace";
|
|
2836
2869
|
/** どの種類の図か (#645)。 `CdlDiagram.type` をそのまま持ち越す */
|
|
2837
2870
|
type?: string;
|
|
2838
2871
|
viewBox: {
|
|
@@ -3035,4 +3068,4 @@ type CdlDiagramViewProps = {
|
|
|
3035
3068
|
};
|
|
3036
3069
|
declare function CdlDiagramView({ diagram, laid: laidProp, hideHeader, hideMiniPhaseIndicator, focusPhaseId, debug, emitGeometryWarn, headingLevel, interactiveHandlers }: CdlDiagramViewProps): JSX.Element;
|
|
3037
3070
|
|
|
3038
|
-
export {
|
|
3071
|
+
export { type ScrollProgressHandle as $, type ChartPieForm as A, type BBox as B, type CdlDiagram as C, type ChartSlopeForm as D, type EdgeStyle as E, EDGE_HEADS as F, EDGE_HEAD_DEFAULT as G, EDGE_HEAD_FILLS as H, EDGE_HEAD_FILL_DEFAULT as I, type JourneyEmotion as J, EDGE_REVEALS as K, type LaidDiagram as L, EDGE_REVEAL_DEFAULT as M, type NodeKind as N, EDGE_STYLES as O, type EdgeReveal as P, type QuadrantKey as Q, type RowMark as R, type Signal as S, type Tone as T, type InteractiveHandlerMap as U, type InteractiveSignalsAccessor as V, type LaidLane as W, NODE_KINDS as X, RELATION_FOCUSES as Y, RELATION_FOCUS_DEFAULT as Z, type RelationFocus as _, type CdlInput as a, TONES as a0, computeEventBindingKey as a1, computeFormulaKey as a2, computeInputSignalKey as a3, computeScrollTriggerKey as a4, computed as a5, createInteractiveSignalsAccessor as a6, createScrollProgressHandle as a7, createScrollProgressSignals as a8, hasInteractivePrimitives as a9, resolveLang as aa, sequenceBoardMetrics as ab, sequenceStepId as ac, signal as ad, type CdlLane as b, type CdlNode as c, type Side as d, type EdgeRole as e, type EdgeHead as f, type EdgeHeadFill as g, type EdgeRouting as h, type CdlState as i, type CdlInputOption as j, type CdlEventTarget as k, type CdlLang as l, type CdlTextMetrics as m, type Computed as n, type CdlDerivedValue as o, type CdlScrollTrigger as p, type CdlDiagramViewProps as q, type LaidEdge as r, type LaidNode as s, type CdlEdge as t, type TreeNodePayload as u, CdlDiagramView as v, type CdlEventBinding as w, type CdlEventKind as x, type CdlFormula as y, type CdlPhase as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/cdl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.123.0",
|
|
4
4
|
"description": "CDL (Chainome Diagram Language). Mermaid-like declarative DSL that compiles to animated SVG diagrams. Built for blockchain / Solidity flows, generic enough for sequence / flow / state / ER / topology diagrams.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "cardene777",
|
|
@@ -57,16 +57,6 @@
|
|
|
57
57
|
"node": ">=18"
|
|
58
58
|
},
|
|
59
59
|
"sideEffects": false,
|
|
60
|
-
"scripts": {
|
|
61
|
-
"build": "tsup",
|
|
62
|
-
"dev": "tsup --watch",
|
|
63
|
-
"typecheck": "tsc --noEmit",
|
|
64
|
-
"test": "cd ../.. && vitest run packages/cdl",
|
|
65
|
-
"lint": "tsc --noEmit",
|
|
66
|
-
"prepublishOnly": "pnpm run typecheck && pnpm run build",
|
|
67
|
-
"prepack": "node scripts/prepack-check.mjs",
|
|
68
|
-
"postpack": "node scripts/prepack-check.mjs"
|
|
69
|
-
},
|
|
70
60
|
"peerDependencies": {
|
|
71
61
|
"react": "^19.0.0",
|
|
72
62
|
"react-dom": "^19.0.0"
|
|
@@ -78,5 +68,12 @@
|
|
|
78
68
|
"typedoc": "^0.28.19",
|
|
79
69
|
"typedoc-plugin-markdown": "^4.12.0",
|
|
80
70
|
"typescript": "^5.8.0"
|
|
71
|
+
},
|
|
72
|
+
"scripts": {
|
|
73
|
+
"build": "tsup",
|
|
74
|
+
"dev": "tsup --watch",
|
|
75
|
+
"typecheck": "tsc --noEmit",
|
|
76
|
+
"test": "cd ../.. && vitest run packages/cdl",
|
|
77
|
+
"lint": "tsc --noEmit"
|
|
81
78
|
}
|
|
82
|
-
}
|
|
79
|
+
}
|
package/src/builder.ts
CHANGED
|
@@ -15,8 +15,10 @@ import type {
|
|
|
15
15
|
CdlReadout,
|
|
16
16
|
CdlScrollTrigger,
|
|
17
17
|
CdlState,
|
|
18
|
+
CdlTextMetrics,
|
|
18
19
|
EdgeHead,
|
|
19
20
|
EdgeHeadFill,
|
|
21
|
+
EdgeRouting,
|
|
20
22
|
EdgeStyle,
|
|
21
23
|
EdgeRole,
|
|
22
24
|
NodeKind,
|
|
@@ -1461,7 +1463,7 @@ export type DiagramBuilder = {
|
|
|
1461
1463
|
tailLabel?: string;
|
|
1462
1464
|
labelOffsetX?: number;
|
|
1463
1465
|
labelOffsetY?: number;
|
|
1464
|
-
routing?:
|
|
1466
|
+
routing?: EdgeRouting;
|
|
1465
1467
|
/** CAR-549 SSOT ... true で label を edge path 上に重ねる (flowchart condition label 用) */
|
|
1466
1468
|
overlay?: boolean;
|
|
1467
1469
|
/** signal binding: stroke-width template (CAR edge-signal-binding) */
|
|
@@ -1573,7 +1575,7 @@ export type DiagramBuilder = {
|
|
|
1573
1575
|
tailLabel?: string;
|
|
1574
1576
|
labelOffsetX?: number;
|
|
1575
1577
|
labelOffsetY?: number;
|
|
1576
|
-
routing?:
|
|
1578
|
+
routing?: EdgeRouting;
|
|
1577
1579
|
/** CAR-549 SSOT ... true で label を edge path 上に重ねる (flowchart condition label 用) */
|
|
1578
1580
|
overlay?: boolean;
|
|
1579
1581
|
}>,
|
|
@@ -1662,6 +1664,8 @@ export function diagram(
|
|
|
1662
1664
|
* 描画側が書く固定の字の言語 (#847)。 詳しくは `CdlDiagram.lang` の説明を参照。
|
|
1663
1665
|
*/
|
|
1664
1666
|
lang?: CdlLang;
|
|
1667
|
+
/** 図の字幅を測る規則。詳しくは `CdlDiagram.textMetrics` の説明を参照。 */
|
|
1668
|
+
textMetrics?: CdlTextMetrics;
|
|
1665
1669
|
/**
|
|
1666
1670
|
* この図がどの種類か (#645)。 詳しくは `CdlDiagram.type` の説明を参照。
|
|
1667
1671
|
*/
|
|
@@ -3817,6 +3821,8 @@ export function diagram(
|
|
|
3817
3821
|
...(options.palette !== undefined ? { palette: options.palette } : {}),
|
|
3818
3822
|
// 言語も素通しする。 型の外の値を既定に落とすのは `layout` の 1 箇所に置く
|
|
3819
3823
|
...(options.lang !== undefined ? { lang: options.lang } : {}),
|
|
3824
|
+
// 字幅の測り方も素通しする。型の外の値を既定に落とすのは `layout` の 1 箇所に置く
|
|
3825
|
+
...(options.textMetrics !== undefined ? { textMetrics: options.textMetrics } : {}),
|
|
3820
3826
|
// 種類の名前も同じ経路で渡し、空文字の扱いを `layout` の 1 箇所に揃える
|
|
3821
3827
|
...(options.type !== undefined ? { type: options.type } : {}),
|
|
3822
3828
|
// inputs / formulas / scrollTriggers / eventBindings は空なら省略 (static diagram の JSON 形状維持)
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type { CdlInput, CdlInputOption } from "./types";
|
|
|
15
15
|
// 字を直すたびに利用側が壊れる
|
|
16
16
|
export { resolveLang } from "./lang";
|
|
17
17
|
export type { CdlLang } from "./lang";
|
|
18
|
+
export { resolveTextMetrics } from "./text-metrics";
|
|
18
19
|
|
|
19
20
|
// formula primitive (CAR #244) — builder chain `.formula(id, "gasBase * 2")` で safe subset の
|
|
20
21
|
// algebraic expression を追加、 createFormulaComputeds(diagram, signals) で computed を得て
|
|
@@ -309,9 +310,11 @@ export type {
|
|
|
309
310
|
CdlNode,
|
|
310
311
|
CdlPhase,
|
|
311
312
|
CdlState,
|
|
313
|
+
CdlTextMetrics,
|
|
312
314
|
EdgeHead,
|
|
313
315
|
EdgeHeadFill,
|
|
314
316
|
EdgeReveal,
|
|
317
|
+
EdgeRouting,
|
|
315
318
|
RelationFocus,
|
|
316
319
|
RowMark,
|
|
317
320
|
EdgeStyle,
|
package/src/kinds/box-lines.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CdlTextMetrics } from "../types";
|
|
1
2
|
import { textWidth } from "./text-width";
|
|
2
3
|
import { MIN_TEXT_SIZE } from "./compact-title";
|
|
3
4
|
|
|
@@ -50,6 +51,13 @@ export type 積んだ行 = 積む行 & {
|
|
|
50
51
|
dy: number;
|
|
51
52
|
};
|
|
52
53
|
|
|
54
|
+
/** tree の箱を描画と検査で同じ字幅規則にそろえる。 */
|
|
55
|
+
export function 箱の字を測る(
|
|
56
|
+
textMetrics: CdlTextMetrics = "proportional",
|
|
57
|
+
): (text: string, fontSize: number) => number {
|
|
58
|
+
return (text, fontSize) => textWidth(text, fontSize, 0, textMetrics);
|
|
59
|
+
}
|
|
60
|
+
|
|
53
61
|
/**
|
|
54
62
|
* 幅に収まるところまでで切り、 切った時は末尾に `…` を付ける。
|
|
55
63
|
*
|
|
@@ -63,7 +71,7 @@ export function 幅で切る(
|
|
|
63
71
|
text: string,
|
|
64
72
|
fontSize: number,
|
|
65
73
|
使える幅: number,
|
|
66
|
-
測る: (s: string, size: number) => number
|
|
74
|
+
測る: (s: string, size: number) => number,
|
|
67
75
|
): string {
|
|
68
76
|
if (使える幅 <= 0) return "";
|
|
69
77
|
if (測る(text, fontSize) <= 使える幅) return text;
|
|
@@ -112,7 +120,7 @@ export function 幅に収める(
|
|
|
112
120
|
text: string,
|
|
113
121
|
fontSize: number,
|
|
114
122
|
使える幅: number,
|
|
115
|
-
測る: (s: string, size: number) => number
|
|
123
|
+
測る: (s: string, size: number) => number,
|
|
116
124
|
): { text: string; fontSize: number } {
|
|
117
125
|
let size = fontSize;
|
|
118
126
|
while (size > 縮めの下限 && 測る(text, size) > 使える幅) size -= 1;
|
|
@@ -143,7 +151,12 @@ function 書記素に分ける(text: string): string[] {
|
|
|
143
151
|
*
|
|
144
152
|
* 返す `dy` は箱の中心から見たずれで、 行の塊を上下の中央に置いた時の baseline になる。
|
|
145
153
|
*/
|
|
146
|
-
export function 箱に積む(
|
|
154
|
+
export function 箱に積む(
|
|
155
|
+
行: 積む行[],
|
|
156
|
+
箱の幅: number,
|
|
157
|
+
箱の高さ: number,
|
|
158
|
+
測る: (s: string, size: number) => number,
|
|
159
|
+
): 積んだ行[] {
|
|
147
160
|
const 候補 = 行.filter((r, i) => i === 0 || r.text.trim() !== "");
|
|
148
161
|
if (候補.length === 0) return [];
|
|
149
162
|
|
|
@@ -159,7 +172,7 @@ export function 箱に積む(行: 積む行[], 箱の幅: number, 箱の高さ:
|
|
|
159
172
|
const 幅 = 使える幅(箱の幅);
|
|
160
173
|
// **幅に収めるのを先に済ませる** (#534)。 縮めると行の高さも変わるため、後から縮めると
|
|
161
174
|
// `dy` が縮める前の大きさで出て、行の塊が箱の上下の中央からずれる
|
|
162
|
-
const 収めた = 残す.map((r) => ({ ...r, ...幅に収める(r.text, r.fontSize,
|
|
175
|
+
const 収めた = 残す.map((r) => ({ ...r, ...幅に収める(r.text, r.fontSize, 幅, 測る) }));
|
|
163
176
|
|
|
164
177
|
const 総高 = 高さ(収めた);
|
|
165
178
|
let 積み = -総高 / 2;
|
package/src/kinds/chart-bar.tsx
CHANGED
|
@@ -120,6 +120,9 @@ export function ChartBarNode({
|
|
|
120
120
|
* 4 本に 4 色を配ると「色に意味がある」 と誤読する余地が残る。
|
|
121
121
|
*/
|
|
122
122
|
const 濃さ = (v: number): number => (vMax > 0 ? (v >= vMax ? 1 : 0.45) : 0.9);
|
|
123
|
+
/** `data-cdl-emphasis` はいちばん大きい棒すべてに付ける。 `濃さ` が 1 の棒と同じ条件で、
|
|
124
|
+
* `chart-bar-look.test.tsx` の `(#1008)` が両方を同じ並びで見張る。 */
|
|
125
|
+
const 主役の棒か = (v: number): boolean => vMax > 0 && v >= vMax;
|
|
123
126
|
/** 角丸は棒の太さに合わせる。 太い棒に固定値を当てると直角に見える */
|
|
124
127
|
const 角丸 = Math.min(barW * 0.06, 8);
|
|
125
128
|
|
|
@@ -190,6 +193,7 @@ export function ChartBarNode({
|
|
|
190
193
|
<rect
|
|
191
194
|
data-cdl-role="chart-bar"
|
|
192
195
|
data-cdl-unresolved={d.unresolved ? "true" : undefined}
|
|
196
|
+
data-cdl-emphasis={主役の棒か(d.value) ? "primary" : undefined}
|
|
193
197
|
x={bx}
|
|
194
198
|
y={by}
|
|
195
199
|
width={barW}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useId, type JSX } from "react";
|
|
2
|
-
import type { LaidNode, Tone } from "../types";
|
|
2
|
+
import type { CdlTextMetrics, LaidNode, Tone } from "../types";
|
|
3
3
|
import { TONE, chartSeriesColor } from "../render/tone";
|
|
4
4
|
import { resolveChartData } from "../render/payload-binding";
|
|
5
5
|
import { textWidth } from "./text-width";
|
|
@@ -44,6 +44,7 @@ export function ChartGaugeNode({
|
|
|
44
44
|
stateValues = {},
|
|
45
45
|
drawing = false,
|
|
46
46
|
progress = 1,
|
|
47
|
+
textMetrics = "proportional",
|
|
47
48
|
}: {
|
|
48
49
|
node: LaidNode;
|
|
49
50
|
active: boolean;
|
|
@@ -52,6 +53,7 @@ export function ChartGaugeNode({
|
|
|
52
53
|
drawing?: boolean;
|
|
53
54
|
/** phase の進み (0→1)。 `drawing` が true の時だけ読む */
|
|
54
55
|
progress?: number;
|
|
56
|
+
textMetrics?: CdlTextMetrics;
|
|
55
57
|
}): JSX.Element {
|
|
56
58
|
const x0 = node.cx - node.w / 2;
|
|
57
59
|
const y0 = node.cy - node.h / 2;
|
|
@@ -99,7 +101,11 @@ export function ChartGaugeNode({
|
|
|
99
101
|
* 防ぐ下限として置いている。 万一この関係が崩れても印は区画に合わせて縮む (下の `Math.min`)。
|
|
100
102
|
*/
|
|
101
103
|
const 割り付ける = (件たち: typeof data): { 行の件数: number; 段数: number } => {
|
|
102
|
-
const 幅 =
|
|
104
|
+
const 幅 =
|
|
105
|
+
Math.max(
|
|
106
|
+
印の幅,
|
|
107
|
+
...件たち.map((d) => textWidth(数値の行(d), 数値の級, 0, textMetrics)),
|
|
108
|
+
) + 区画の間;
|
|
103
109
|
const 行の件数 = Math.min(
|
|
104
110
|
Math.max(1, Math.floor(使える幅 / Math.max(幅, 1))),
|
|
105
111
|
Math.max(件たち.length, 1),
|
|
@@ -256,7 +262,7 @@ export function ChartGaugeNode({
|
|
|
256
262
|
*/
|
|
257
263
|
const 合計の文字 = 実値表記(Math.round(total));
|
|
258
264
|
/** 級 1 あたりの字幅 */
|
|
259
|
-
const 単位幅 = Math.max(textWidth(合計の文字, 100), 1) / 100;
|
|
265
|
+
const 単位幅 = Math.max(textWidth(合計の文字, 100, 0, textMetrics), 1) / 100;
|
|
260
266
|
const 級の候補 = Math.min(
|
|
261
267
|
// 横 = 字の上の角が内側の円に入る大きさ
|
|
262
268
|
内半径 / Math.sqrt((単位幅 / 2) ** 2 + 1.25 ** 2),
|
|
@@ -395,7 +401,7 @@ export function ChartGaugeNode({
|
|
|
395
401
|
* 切れ目が値の途中に来た行だけ色が付かない形になる。
|
|
396
402
|
*/
|
|
397
403
|
const 数の行 = 内訳の数値[idx] ?? "";
|
|
398
|
-
const 切った数の行 = 切り詰める(数の行, 収まる幅,
|
|
404
|
+
const 切った数の行 = 切り詰める(数の行, 収まる幅, 数値の級, textMetrics);
|
|
399
405
|
return (
|
|
400
406
|
<g key={`legend-${idx}`} data-cdl-role="chart-gauge-item">
|
|
401
407
|
<rect
|
|
@@ -413,7 +419,7 @@ export function ChartGaugeNode({
|
|
|
413
419
|
fontWeight={700}
|
|
414
420
|
fill="var(--cdl-text, #1a1f2a)"
|
|
415
421
|
>
|
|
416
|
-
{切り詰める(d.label ?? "", 収まる幅,
|
|
422
|
+
{切り詰める(d.label ?? "", 収まる幅, 名前の級, textMetrics)}
|
|
417
423
|
</text>
|
|
418
424
|
{/* **数値も切り詰める** = 切らないと隣の区画の字とくっつく (cdl#731) */}
|
|
419
425
|
<text x={x} y={y + 46} fontSize={数値の級} fill="var(--cdl-text-dim, #5a6270)">
|
|
@@ -445,12 +451,17 @@ function 極(cx: number, cy: number, r: number, a: number): { x: number; y: numb
|
|
|
445
451
|
* 切らないと隣の区画の字に重なる = どちらの件の名前かが読めなくなる。 切ったことが分かるよう
|
|
446
452
|
* `…` を付ける。
|
|
447
453
|
*/
|
|
448
|
-
function 切り詰める(
|
|
449
|
-
|
|
450
|
-
|
|
454
|
+
function 切り詰める(
|
|
455
|
+
s: string,
|
|
456
|
+
上限: number,
|
|
457
|
+
級: number,
|
|
458
|
+
textMetrics: CdlTextMetrics = "proportional",
|
|
459
|
+
): string {
|
|
460
|
+
if (上限 <= 0 || textWidth(s, 級, 0, textMetrics) <= 上限) return s;
|
|
461
|
+
const 記号幅 = textWidth("…", 級, 0, textMetrics);
|
|
451
462
|
let out = "";
|
|
452
463
|
for (const c of s) {
|
|
453
|
-
if (textWidth(out + c,
|
|
464
|
+
if (textWidth(out + c, 級, 0, textMetrics) + 記号幅 > 上限) break;
|
|
454
465
|
out += c;
|
|
455
466
|
}
|
|
456
467
|
return `${out}…`;
|