@cardenelabs/cdl 0.35.0 → 0.37.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.
@@ -423,6 +423,32 @@ type CdlNode = {
423
423
  * `previous` (cdl#680) が効くのは `ring` だけ。 他の形は内側の輪を描かない。
424
424
  */
425
425
  chartPieForm?: ChartPieForm;
426
+ /**
427
+ * chart-slope の見せ方 (cdl#702 / cdl#707)。
428
+ *
429
+ * | 値 | 縦の位置 | 左の列 | 右の列 |
430
+ * |---|---|---|---|
431
+ * | `values` | 値 | 前の値 | 今の値 |
432
+ * | `delta` | 値 | 前の値 | 増減 (`+40` / `-90`) |
433
+ * | `rank` | 順位の段 (等間隔) | 前の値 | 今の値 |
434
+ *
435
+ * `values` と `delta` は縦の位置が同じで、右の列の字だけが違う。
436
+ * `前 + 増減 = 今` なので、 `delta` でも今の値は足せば戻る。
437
+ * 3 つ目の数を足さないので、 名札の高さも線を引く幅も変わらない。
438
+ *
439
+ * `rank` は **縦の位置** を変える (cdl#707)。 段を等間隔に置くので、線の交差が
440
+ * 順位の入れ替わりと 1 対 1 になり、水平線が「順位が動かなかった」 を意味する。
441
+ * 字は値のままにして、量が図から消えないようにしている。
442
+ *
443
+ * `rank` では「線の傾きが動いた量」 という読み方が成立しない (`+40` と `+30` が
444
+ * どちらも水平線になる)。 書いた図だけに効く割り切りで、量は字を読む。
445
+ *
446
+ * 型の外の値は `values` として描く = 見せ方が決まらないより、既定の形が出る方がよい。
447
+ *
448
+ * 前の時点を持たない図 (`previous` が 1 件も無い) は軸が 1 本で並べ替える相手が
449
+ * いないため、 この欄を書いても絵は変わらない。
450
+ */
451
+ chartSlopeForm?: ChartSlopeForm;
426
452
  /**
427
453
  * gantt-timeline 専用の task payload。 task 全件を 1 node に格納し、
428
454
  * kinds/gantt.tsx が縦軸 task lane + 横軸日付 rect bar で SVG 描画する。
@@ -478,6 +504,8 @@ type BoundEnum<T extends string> = T | (string & {});
478
504
  /** Chart 系 kind の 1 datum payload。 label + value + optional tone (color) */
479
505
  /** chart-pie の見せ方 (cdl#684)。 SSOT は `kinds/chart-pie.tsx` */
480
506
  type ChartPieForm = "ring" | "arcs" | "table";
507
+ /** chart-slope の見せ方 (cdl#702 / cdl#707)。 SSOT は `kinds/chart-slope.tsx` */
508
+ type ChartSlopeForm = "values" | "delta" | "rank";
481
509
  type ChartDatumPayload = {
482
510
  label: string;
483
511
  /** 棒 / 折れ線 / 扇の大きさ。 `{signal}` で状態に追随する */
@@ -2883,4 +2911,4 @@ type CdlDiagramViewProps = {
2883
2911
  };
2884
2912
  declare function CdlDiagramView({ diagram, laid: laidProp, hideHeader, hideMiniPhaseIndicator, focusPhaseId, debug, emitGeometryWarn, headingLevel, interactiveHandlers }: CdlDiagramViewProps): JSX.Element;
2885
2913
 
2886
- export { createScrollProgressSignals as $, EDGE_REVEALS as A, type BBox as B, type CdlDiagram as C, EDGE_REVEAL_DEFAULT as D, type EdgeStyle as E, EDGE_STYLES as F, type EdgeReveal as G, type InteractiveSignalsAccessor as H, type InteractiveHandlerMap as I, type JourneyEmotion as J, type LaidLane as K, type LaidDiagram as L, NODE_KINDS as M, type NodeKind as N, type ScrollProgressHandle as O, TONES as P, type QuadrantKey as Q, type RowMark as R, type Signal as S, type Tone as T, computeEventBindingKey as U, computeFormulaKey as V, computeInputSignalKey as W, computeScrollTriggerKey as X, computed as Y, createInteractiveSignalsAccessor as Z, createScrollProgressHandle as _, type CdlInput as a, hasInteractivePrimitives as a0, sequenceBoardMetrics as a1, sequenceStepId as a2, signal as a3, 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 CdlState as h, type CdlEventTarget as i, type Computed as j, type CdlDerivedValue as k, type CdlScrollTrigger as l, type CdlDiagramViewProps as m, type LaidEdge as n, type LaidNode as o, type CdlEdge as p, CdlDiagramView as q, type CdlEventBinding as r, type CdlEventKind as s, type CdlFormula as t, type CdlPhase as u, type ChartPieForm as v, EDGE_HEADS as w, EDGE_HEAD_DEFAULT as x, EDGE_HEAD_FILLS as y, EDGE_HEAD_FILL_DEFAULT as z };
2914
+ export { createScrollProgressHandle as $, EDGE_HEAD_FILL_DEFAULT as A, type BBox as B, type CdlDiagram as C, EDGE_REVEALS as D, type EdgeStyle as E, EDGE_REVEAL_DEFAULT as F, EDGE_STYLES as G, type EdgeReveal as H, type InteractiveHandlerMap as I, type JourneyEmotion as J, type InteractiveSignalsAccessor as K, type LaidDiagram as L, type LaidLane as M, type NodeKind as N, NODE_KINDS as O, type ScrollProgressHandle as P, type QuadrantKey as Q, type RowMark as R, type Signal as S, type Tone as T, TONES as U, computeEventBindingKey as V, computeFormulaKey as W, computeInputSignalKey as X, computeScrollTriggerKey as Y, computed as Z, createInteractiveSignalsAccessor as _, type CdlInput as a, createScrollProgressSignals as a0, hasInteractivePrimitives as a1, sequenceBoardMetrics as a2, sequenceStepId as a3, signal as a4, 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 CdlState as h, type CdlEventTarget as i, type Computed as j, type CdlDerivedValue as k, type CdlScrollTrigger as l, type CdlDiagramViewProps as m, type LaidEdge as n, type LaidNode as o, type CdlEdge as p, CdlDiagramView as q, type CdlEventBinding as r, type CdlEventKind as s, type CdlFormula as t, type CdlPhase as u, type ChartPieForm as v, type ChartSlopeForm as w, EDGE_HEADS as x, EDGE_HEAD_DEFAULT as y, EDGE_HEAD_FILLS as z };
@@ -423,6 +423,32 @@ type CdlNode = {
423
423
  * `previous` (cdl#680) が効くのは `ring` だけ。 他の形は内側の輪を描かない。
424
424
  */
425
425
  chartPieForm?: ChartPieForm;
426
+ /**
427
+ * chart-slope の見せ方 (cdl#702 / cdl#707)。
428
+ *
429
+ * | 値 | 縦の位置 | 左の列 | 右の列 |
430
+ * |---|---|---|---|
431
+ * | `values` | 値 | 前の値 | 今の値 |
432
+ * | `delta` | 値 | 前の値 | 増減 (`+40` / `-90`) |
433
+ * | `rank` | 順位の段 (等間隔) | 前の値 | 今の値 |
434
+ *
435
+ * `values` と `delta` は縦の位置が同じで、右の列の字だけが違う。
436
+ * `前 + 増減 = 今` なので、 `delta` でも今の値は足せば戻る。
437
+ * 3 つ目の数を足さないので、 名札の高さも線を引く幅も変わらない。
438
+ *
439
+ * `rank` は **縦の位置** を変える (cdl#707)。 段を等間隔に置くので、線の交差が
440
+ * 順位の入れ替わりと 1 対 1 になり、水平線が「順位が動かなかった」 を意味する。
441
+ * 字は値のままにして、量が図から消えないようにしている。
442
+ *
443
+ * `rank` では「線の傾きが動いた量」 という読み方が成立しない (`+40` と `+30` が
444
+ * どちらも水平線になる)。 書いた図だけに効く割り切りで、量は字を読む。
445
+ *
446
+ * 型の外の値は `values` として描く = 見せ方が決まらないより、既定の形が出る方がよい。
447
+ *
448
+ * 前の時点を持たない図 (`previous` が 1 件も無い) は軸が 1 本で並べ替える相手が
449
+ * いないため、 この欄を書いても絵は変わらない。
450
+ */
451
+ chartSlopeForm?: ChartSlopeForm;
426
452
  /**
427
453
  * gantt-timeline 専用の task payload。 task 全件を 1 node に格納し、
428
454
  * kinds/gantt.tsx が縦軸 task lane + 横軸日付 rect bar で SVG 描画する。
@@ -478,6 +504,8 @@ type BoundEnum<T extends string> = T | (string & {});
478
504
  /** Chart 系 kind の 1 datum payload。 label + value + optional tone (color) */
479
505
  /** chart-pie の見せ方 (cdl#684)。 SSOT は `kinds/chart-pie.tsx` */
480
506
  type ChartPieForm = "ring" | "arcs" | "table";
507
+ /** chart-slope の見せ方 (cdl#702 / cdl#707)。 SSOT は `kinds/chart-slope.tsx` */
508
+ type ChartSlopeForm = "values" | "delta" | "rank";
481
509
  type ChartDatumPayload = {
482
510
  label: string;
483
511
  /** 棒 / 折れ線 / 扇の大きさ。 `{signal}` で状態に追随する */
@@ -2883,4 +2911,4 @@ type CdlDiagramViewProps = {
2883
2911
  };
2884
2912
  declare function CdlDiagramView({ diagram, laid: laidProp, hideHeader, hideMiniPhaseIndicator, focusPhaseId, debug, emitGeometryWarn, headingLevel, interactiveHandlers }: CdlDiagramViewProps): JSX.Element;
2885
2913
 
2886
- export { createScrollProgressSignals as $, EDGE_REVEALS as A, type BBox as B, type CdlDiagram as C, EDGE_REVEAL_DEFAULT as D, type EdgeStyle as E, EDGE_STYLES as F, type EdgeReveal as G, type InteractiveSignalsAccessor as H, type InteractiveHandlerMap as I, type JourneyEmotion as J, type LaidLane as K, type LaidDiagram as L, NODE_KINDS as M, type NodeKind as N, type ScrollProgressHandle as O, TONES as P, type QuadrantKey as Q, type RowMark as R, type Signal as S, type Tone as T, computeEventBindingKey as U, computeFormulaKey as V, computeInputSignalKey as W, computeScrollTriggerKey as X, computed as Y, createInteractiveSignalsAccessor as Z, createScrollProgressHandle as _, type CdlInput as a, hasInteractivePrimitives as a0, sequenceBoardMetrics as a1, sequenceStepId as a2, signal as a3, 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 CdlState as h, type CdlEventTarget as i, type Computed as j, type CdlDerivedValue as k, type CdlScrollTrigger as l, type CdlDiagramViewProps as m, type LaidEdge as n, type LaidNode as o, type CdlEdge as p, CdlDiagramView as q, type CdlEventBinding as r, type CdlEventKind as s, type CdlFormula as t, type CdlPhase as u, type ChartPieForm as v, EDGE_HEADS as w, EDGE_HEAD_DEFAULT as x, EDGE_HEAD_FILLS as y, EDGE_HEAD_FILL_DEFAULT as z };
2914
+ export { createScrollProgressHandle as $, EDGE_HEAD_FILL_DEFAULT as A, type BBox as B, type CdlDiagram as C, EDGE_REVEALS as D, type EdgeStyle as E, EDGE_REVEAL_DEFAULT as F, EDGE_STYLES as G, type EdgeReveal as H, type InteractiveHandlerMap as I, type JourneyEmotion as J, type InteractiveSignalsAccessor as K, type LaidDiagram as L, type LaidLane as M, type NodeKind as N, NODE_KINDS as O, type ScrollProgressHandle as P, type QuadrantKey as Q, type RowMark as R, type Signal as S, type Tone as T, TONES as U, computeEventBindingKey as V, computeFormulaKey as W, computeInputSignalKey as X, computeScrollTriggerKey as Y, computed as Z, createInteractiveSignalsAccessor as _, type CdlInput as a, createScrollProgressSignals as a0, hasInteractivePrimitives as a1, sequenceBoardMetrics as a2, sequenceStepId as a3, signal as a4, 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 CdlState as h, type CdlEventTarget as i, type Computed as j, type CdlDerivedValue as k, type CdlScrollTrigger as l, type CdlDiagramViewProps as m, type LaidEdge as n, type LaidNode as o, type CdlEdge as p, CdlDiagramView as q, type CdlEventBinding as r, type CdlEventKind as s, type CdlFormula as t, type CdlPhase as u, type ChartPieForm as v, type ChartSlopeForm as w, EDGE_HEADS as x, EDGE_HEAD_DEFAULT as y, EDGE_HEAD_FILLS as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cardenelabs/cdl",
3
- "version": "0.35.0",
3
+ "version": "0.37.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",
package/src/index.ts CHANGED
@@ -284,6 +284,7 @@ export type {
284
284
  CdlDiagram,
285
285
  CdlEdge,
286
286
  ChartPieForm,
287
+ ChartSlopeForm,
287
288
  CdlLane,
288
289
  CdlNode,
289
290
  CdlPhase,
@@ -1,5 +1,5 @@
1
1
  import { type JSX } from "react";
2
- import type { LaidNode, Tone } from "../types";
2
+ import type { ChartSlopeForm, 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";
@@ -50,6 +50,24 @@ import { 進みを畳む, 伸ばすdash } from "./draw-progress";
50
50
  *
51
51
  * 色を持たせるのは **名前だけ**。 値は太字の濃い色のままにして、数の読み比べを保つ。
52
52
  * identity は色が、量は字が担う。
53
+ *
54
+ * ## 順位で見せる形は縦の位置を変える (cdl#707)
55
+ *
56
+ * この図は「線の交差が順位の入れ替わり」 を読ませるが、縦の位置は値なので **交差点の
57
+ * 位置が順位と噛み合わない**。 どの交差が本当に順位を変えた交差なのかは、値を読み比べ
58
+ * ないと決まらない。
59
+ *
60
+ * `rank` は段を等間隔に置く。 交差が入れ替わりと 1 対 1 になり、水平線が「順位が
61
+ * 動かなかった」 を意味する。
62
+ *
63
+ * **字は値のままにする**。 字も順位にすると `380 → 420` と `60 → 90` がどちらも
64
+ * 同じ水平線になり、量が図から完全に消える。 位置が順位を、字が量を担う。
65
+ *
66
+ * 順位と値を **両方** 出す案は落とした = 3 つ目の数を足す形で、実物に当てると値の列が
67
+ * 伸びて名前と重なった (`delta` で落としたのと同じ形、cdl#702)。
68
+ *
69
+ * **この形では「線の傾きが動いた量」 が成立しない**。 `+40` と `+30` がどちらも水平線に
70
+ * なる。 書いた図だけに効く割り切りで、量は字を読む。
53
71
  */
54
72
 
55
73
  /** 線を引くのに最低限要る横幅。 名札が長い図でもこれだけは残す */
@@ -112,8 +130,57 @@ export function ChartSlopeNode({
112
130
  const yを取る = (v: number): number =>
113
131
  尺の幅 > 0 ? 下端 - ((v - 最小) / 尺の幅) * (下端 - 上端) : (上端 + 下端) / 2;
114
132
 
133
+ /**
134
+ * 見せ方 (cdl#702 / cdl#707)。 **型の外の値は `values` に落とす** = 見せ方が
135
+ * 決まらないより、既定の形が出る方がよい (円グラフと同じ判断)。
136
+ *
137
+ * **前の時点を持たない図では `values` に落とす**。 `delta` は引く相手がいないので、
138
+ * 増減を出すと「0 から増えた」 という書いていない主張になる (前を持たない件を 0 から
139
+ * 立ち上げるのは線を引くための扱いで、前が 0 だったという意味ではない)。
140
+ * `rank` は軸が 1 本で並べ替える相手がいない。
141
+ */
142
+ const 書いた形 = node.chartSlopeForm;
143
+ const 形: ChartSlopeForm =
144
+ 前あり && (書いた形 === "delta" || 書いた形 === "rank") ? 書いた形 : "values";
145
+
146
+ /**
147
+ * 順位。 **自分より大きい値の件数 + 1** で決める。
148
+ *
149
+ * 同じ値なら同じ順位になり、段も重なる。 無理に 1 つずつずらすと、書いていない差を
150
+ * 絵が主張することになる。
151
+ */
152
+ const 順位を取る = (v: number, 全部: number[]): number =>
153
+ 全部.filter((x) => x > v).length + 1;
154
+
155
+ const 前の順位 = 系列たち.map((s) => 順位を取る(s.前, 系列たち.map((x) => x.前)));
156
+ const 今の順位 = 系列たち.map((s) => 順位を取る(s.今, 系列たち.map((x) => x.今)));
157
+
158
+ /**
159
+ * 段の y。 1 位を上端、系列の数を下端にして等間隔に置く。
160
+ *
161
+ * **系列が 1 本の図では割り算ができない**ので縦の中央に置く (尺の幅が 0 の時と同じ扱い)。
162
+ */
163
+ const 段のyを取る = (順位: number): number =>
164
+ 系列たち.length > 1
165
+ ? 上端 + ((順位 - 1) / (系列たち.length - 1)) * (下端 - 上端)
166
+ : (上端 + 下端) / 2;
167
+
168
+ /**
169
+ * 増減の表記。 符号を前に付ける。
170
+ *
171
+ * `0` は `+0` にしない = 動いていないことを「増えた」 と読ませない。
172
+ * 負は `実値表記` が `-` を付けるのでそのまま。
173
+ */
174
+ const 増減表記 = (前: number, 今: number): string => {
175
+ const 差 = 今 - 前;
176
+ return 差 > 0 ? `+${実値表記(差)}` : 実値表記(差);
177
+ };
178
+
115
179
  const 左の字 = 系列たち.map((s) => 実値表記(s.前));
116
- const 右の字 = 系列たち.map((s) => 実値表記(s.今));
180
+ // `delta` は今の値の代わりに増減を出す。 3 つ目の数を足さないので列は 2 つのまま
181
+ const 右の字 = 系列たち.map((s) =>
182
+ 形 === "delta" ? 増減表記(s.前, s.今) : 実値表記(s.今),
183
+ );
117
184
  const 左値幅 = Math.max(0, ...左の字.map((t) => textWidth(t, 値の級)));
118
185
  const 右値幅 = Math.max(0, ...右の字.map((t) => textWidth(t, 値の級)));
119
186
 
@@ -209,8 +276,9 @@ export function ChartSlopeNode({
209
276
  )}
210
277
 
211
278
  {系列たち.map((s, i) => {
212
- const 左y = yを取る(s.前);
213
- const 右y = yを取る(s.今);
279
+ // `rank` は縦の位置を順位の段にする (cdl#707)。 値の尺は使わない
280
+ const 左y = 形 === "rank" ? 段のyを取る(前の順位[i]!) : yを取る(s.前);
281
+ const 右y = 形 === "rank" ? 段のyを取る(今の順位[i]!) : yを取る(s.今);
214
282
  const 未解決 = s.未解決 ? "true" : undefined;
215
283
  return (
216
284
  <g key={`slope-${i}`}>
@@ -288,7 +356,9 @@ export function ChartSlopeNode({
288
356
  {右を出す && (
289
357
  <>
290
358
  <text
291
- data-cdl-role="chart-slope-value"
359
+ // 増減は今の値と意味が違うので役割を分ける (cdl#702)。
360
+ // 消費側が増減だけに色を当てたくなる経路がある
361
+ data-cdl-role={形 === "delta" ? "chart-slope-delta" : "chart-slope-value"}
292
362
  x={右軸x + 軸から値まで}
293
363
  y={右y + 5}
294
364
  fontSize={値の級}
@@ -58,6 +58,8 @@ type 読まない欄 =
58
58
  | "chartTrace"
59
59
  // 円グラフの見せ方 (#684)。 決まった値のどれかで、字を差し込む先が無い
60
60
  | "chartPieForm"
61
+ // 傾き図の見せ方 (#702)。 同上
62
+ | "chartSlopeForm"
61
63
  | "ganttData"
62
64
  | "ganttAxisMax"
63
65
  | "mindData"
package/src/types.ts CHANGED
@@ -482,6 +482,32 @@ export type CdlNode = {
482
482
  * `previous` (cdl#680) が効くのは `ring` だけ。 他の形は内側の輪を描かない。
483
483
  */
484
484
  chartPieForm?: ChartPieForm;
485
+ /**
486
+ * chart-slope の見せ方 (cdl#702 / cdl#707)。
487
+ *
488
+ * | 値 | 縦の位置 | 左の列 | 右の列 |
489
+ * |---|---|---|---|
490
+ * | `values` | 値 | 前の値 | 今の値 |
491
+ * | `delta` | 値 | 前の値 | 増減 (`+40` / `-90`) |
492
+ * | `rank` | 順位の段 (等間隔) | 前の値 | 今の値 |
493
+ *
494
+ * `values` と `delta` は縦の位置が同じで、右の列の字だけが違う。
495
+ * `前 + 増減 = 今` なので、 `delta` でも今の値は足せば戻る。
496
+ * 3 つ目の数を足さないので、 名札の高さも線を引く幅も変わらない。
497
+ *
498
+ * `rank` は **縦の位置** を変える (cdl#707)。 段を等間隔に置くので、線の交差が
499
+ * 順位の入れ替わりと 1 対 1 になり、水平線が「順位が動かなかった」 を意味する。
500
+ * 字は値のままにして、量が図から消えないようにしている。
501
+ *
502
+ * `rank` では「線の傾きが動いた量」 という読み方が成立しない (`+40` と `+30` が
503
+ * どちらも水平線になる)。 書いた図だけに効く割り切りで、量は字を読む。
504
+ *
505
+ * 型の外の値は `values` として描く = 見せ方が決まらないより、既定の形が出る方がよい。
506
+ *
507
+ * 前の時点を持たない図 (`previous` が 1 件も無い) は軸が 1 本で並べ替える相手が
508
+ * いないため、 この欄を書いても絵は変わらない。
509
+ */
510
+ chartSlopeForm?: ChartSlopeForm;
485
511
  /**
486
512
  * gantt-timeline 専用の task payload。 task 全件を 1 node に格納し、
487
513
  * kinds/gantt.tsx が縦軸 task lane + 横軸日付 rect bar で SVG 描画する。
@@ -541,6 +567,9 @@ export type BoundEnum<T extends string> = T | (string & {});
541
567
  /** chart-pie の見せ方 (cdl#684)。 SSOT は `kinds/chart-pie.tsx` */
542
568
  export type ChartPieForm = "ring" | "arcs" | "table";
543
569
 
570
+ /** chart-slope の見せ方 (cdl#702 / cdl#707)。 SSOT は `kinds/chart-slope.tsx` */
571
+ export type ChartSlopeForm = "values" | "delta" | "rank";
572
+
544
573
  export type ChartDatumPayload = {
545
574
  label: string;
546
575
  /** 棒 / 折れ線 / 扇の大きさ。 `{signal}` で状態に追随する */