@cardenelabs/cdl 0.37.0 → 0.39.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.
@@ -0,0 +1,42 @@
1
+ import { type JSX } from "react";
2
+
3
+ /**
4
+ * 弧で量を表す図を、起点から開いて見せるための切り抜き (cdl#516 / cdl#715)。
5
+ *
6
+ * 円グラフが持っていた私物の関数を、起点と回る量を引数に取る形へ広げた。 半円ゲージ (9 時から
7
+ * 半周) と放射 (12 時から 1 周) と円グラフ (12 時から 1 周) が同じ計算を使う。
8
+ *
9
+ * **形 (`d`) は触らず、切り抜きで隠す**。 弧の道を切り詰めると、形から量を測る利用側が進みの
10
+ * 途中で別の値を読む (`draw-progress.ts` が `path` について決めたのと同じ)。
11
+ *
12
+ * ここに置くのは切り抜きの形だけで、進みの畳み方は `draw-progress.ts` の `進みを畳む` が持つ。
13
+ * 2 つを 1 つの file に混ぜないのは、こちらが JSX を返すため = `.ts` のままにしておくと
14
+ * 進みの計算まで `.tsx` へ引きずられる。
15
+ */
16
+
17
+ /**
18
+ * `起点` から時計回りに `開き` ぶん開く扇形。 開いていなければ **何も返さない**。
19
+ *
20
+ * @param 開き 0..1。 1 で `全周` ぶん開き切る
21
+ * @param 起点 弧が始まる角度 (`-Math.PI / 2` = 12 時、`Math.PI` = 9 時)
22
+ * @param 全周 開き切った時に回る量 (`Math.PI * 2` = 1 周、`Math.PI` = 半周)
23
+ */
24
+ export function 扇形の切り抜き(
25
+ cx: number,
26
+ cy: number,
27
+ r: number,
28
+ 開き: number,
29
+ 起点: number = -Math.PI / 2,
30
+ 全周: number = Math.PI * 2,
31
+ ): JSX.Element | null {
32
+ if (開き <= 0) return null;
33
+ // 1 周ちょうどは扇形で表せない (始点と終点が同じ点になり、弧の向きが決まらない)。
34
+ // その時だけ円をそのまま返す = 進み 1 で図が消える形を避ける。
35
+ // **半周までの図はこの形にならない** = 両端が別の点なので、扇形のまま描ける。
36
+ if (開き >= 1 && 全周 >= Math.PI * 2) return <circle cx={cx} cy={cy} r={r} />;
37
+ const a0 = 起点;
38
+ const a1 = a0 + Math.min(1, 開き) * 全周;
39
+ const large = a1 - a0 > Math.PI ? 1 : 0;
40
+ const d = `M ${cx} ${cy} L ${cx + r * Math.cos(a0)} ${cy + r * Math.sin(a0)} A ${r} ${r} 0 ${large} 1 ${cx + r * Math.cos(a1)} ${cy + r * Math.sin(a1)} Z`;
41
+ return <path d={d} />;
42
+ }
@@ -194,11 +194,28 @@ export function CdlNodeView({
194
194
  />
195
195
  );
196
196
  case "chart-gauge":
197
- // 段の進みで弧が開く動きは持たない (cdl#549 で対象外にした)
198
- return <ChartGaugeNode node={resolvedNode} active={active} stateValues={stateValues} />;
197
+ // 段の進みでは 9 時から 3 時へ弧が伸びる (cdl#715)
198
+ return (
199
+ <ChartGaugeNode
200
+ node={resolvedNode}
201
+ active={active}
202
+ stateValues={stateValues}
203
+ drawing={drawing}
204
+ progress={progress}
205
+ />
206
+ );
199
207
  case "chart-stacked-bar":
200
- // 帯を割合で区切る。 前の時点を書けば 2 本になる (cdl#551)
201
- return <ChartStackedBarNode node={resolvedNode} active={active} stateValues={stateValues} />;
208
+ // 帯を割合で区切る。 前の時点を書けば 2 本になる (cdl#551)。
209
+ // 段の進みでは左から帯が伸びる (cdl#715)
210
+ return (
211
+ <ChartStackedBarNode
212
+ node={resolvedNode}
213
+ active={active}
214
+ stateValues={stateValues}
215
+ drawing={drawing}
216
+ progress={progress}
217
+ />
218
+ );
202
219
  case "chart-slope":
203
220
  // 2 時点を直線でつなぐ。 前の時点を書かない図は軸 1 本の点の並びになる (cdl#688)
204
221
  return (
@@ -217,8 +234,16 @@ export function CdlNodeView({
217
234
  // 数値が主役で、弧は輪郭だけの補助。 段の進みで数値が動く演出は既存の tween が担う
218
235
  return <ChartStatNode node={resolvedNode} active={active} stateValues={stateValues} />;
219
236
  case "chart-radial":
220
- // 段の進みで弧が伸びる動きは持たない (cdl#550 で対象外にした)
221
- return <ChartRadialNode node={resolvedNode} active={active} stateValues={stateValues} />;
237
+ // 段の進みでは各輪が 12 時から開く (cdl#715)
238
+ return (
239
+ <ChartRadialNode
240
+ node={resolvedNode}
241
+ active={active}
242
+ stateValues={stateValues}
243
+ drawing={drawing}
244
+ progress={progress}
245
+ />
246
+ );
222
247
  case "chart-bar":
223
248
  return (
224
249
  <ChartBarNode
@@ -28,6 +28,7 @@ export function CdlStage({
28
28
  laid,
29
29
  currentPhase,
30
30
  progress,
31
+ drawProgress,
31
32
  stateValues,
32
33
  debug,
33
34
  compact = false,
@@ -36,6 +37,13 @@ export function CdlStage({
36
37
  laid: LaidDiagram;
37
38
  currentPhase: CdlPhase | undefined;
38
39
  progress: number;
40
+ /**
41
+ * 描く動きが読む進み (cdl#711)。 曲線を通す前の値で、 経過時間そのものの割合。
42
+ *
43
+ * 書かない呼出は `progress` と同じ値になる = 曲線を通した進みで描く従来の形。
44
+ * 検査から直接呼ぶ経路が既に多数あり、 そこでは 2 つを分ける意味がない。
45
+ */
46
+ drawProgress?: number;
39
47
  stateValues: Record<string, string>;
40
48
  debug: boolean;
41
49
  compact?: boolean;
@@ -112,9 +120,15 @@ export function CdlStage({
112
120
  }
113
121
  return scales;
114
122
  }, [laid]);
115
- // 描く対象から見た進み (cdl#570)。 `drawRatio` を書かない phase では `progress` と同値で、
123
+ /**
124
+ * 描く動きの素の進み (cdl#711)。 渡されなければ従来どおり曲線を通した進みを使う。
125
+ *
126
+ * **`??` で受ける** = 0 は正しい進み (段の始まり) なので、 偽としては落とせない。
127
+ */
128
+ const 描く素の進み = drawProgress ?? progress;
129
+ // 描く対象から見た進み (cdl#570)。 `drawRatio` を書かない phase では `描く素の進み` と同値で、
116
130
  // 描く速さを phase の長さから切り離すためだけに使う
117
- const 描く進み = 描く進みに直す(progress, currentPhase?.drawRatio);
131
+ const 描く進み = 描く進みに直す(描く素の進み, currentPhase?.drawRatio);
118
132
  // 縦線の終点は全 lane で 1 つに揃える (等長保証)。 値の決め方と、 1 lane の異常が図全体から
119
133
  // 縦線を消していた形の対処は `uniformLifelineEndY` の説明。
120
134
  //
@@ -345,7 +359,7 @@ export function CdlStage({
345
359
  edge={edge}
346
360
  active={activeSet.has(edge.id)}
347
361
  drawing={矢印の出番.伸ばすか(edge.id)}
348
- progress={progress}
362
+ progress={矢印の出番.伸ばすか(edge.id) ? 描く進み : progress}
349
363
  stateValues={stateValues}
350
364
  />
351
365
  ))}
package/src/render.tsx CHANGED
@@ -133,6 +133,13 @@ export function CdlDiagramView({ diagram, laid: laidProp, hideHeader = false, hi
133
133
  : state.phaseIndex;
134
134
  const currentPhase = laid.phases[Math.max(0, phaseIdx)] ?? laid.phases[0];
135
135
  const progress = reduced ? 1 : state.phaseProgress;
136
+ /**
137
+ * 描く動きが読む進み (cdl#711)。 曲線を通さない = 経過時間そのものの割合。
138
+ *
139
+ * 線を引く動きに `easeOutQuint` を当てると前半に寄り、 折れ線の 5 点のうち 4 点が
140
+ * 292 ms の間に出る。 ペンの速さは一定であるほど「1 つずつ現れる」 が読める。
141
+ */
142
+ const drawProgress = reduced ? 1 : state.phaseLinearProgress;
136
143
 
137
144
  // state 値を計算 (現在 phase + これまでの phase の最終 tween 値を集約)
138
145
  const baseStateValues = computeStateValues(laid, phaseIdx, progress);
@@ -184,7 +191,7 @@ export function CdlDiagramView({ diagram, laid: laidProp, hideHeader = false, hi
184
191
  {/* interactive panel = input widget / formula readout / scroll readout (SVG の上に配置)、
185
192
  diagram に interactive primitive がなければ null (SSR / render 影響なし) */}
186
193
  {isInteractive && interactive.panel}
187
- <CdlStage laid={laid} currentPhase={currentPhase} progress={progress} stateValues={stateValues} debug={debug} compact={hideHeader} svgRef={isInteractive ? interactive.svgRef : undefined} />
194
+ <CdlStage laid={laid} currentPhase={currentPhase} progress={progress} drawProgress={drawProgress} stateValues={stateValues} debug={debug} compact={hideHeader} svgRef={isInteractive ? interactive.svgRef : undefined} />
188
195
  {/* hideHeader + multi-phase 時、 phase indicator が消えると動きが読めないため
189
196
  mini indicator (dot 列 + 現在 phase title + badge) を bottom に追加 */}
190
197
  {hideHeader && !hideMiniPhaseIndicator && currentPhase && laid.phases.length > 1 && (
package/src/types.ts CHANGED
@@ -2424,11 +2424,15 @@ export type CdlPhase = {
2424
2424
  * | `chart-line` | 左端 | 線が右へ伸びる | 点と数字は線の先が届いた時 |
2425
2425
  * | `chart-bar` | 横軸 | 棒が上へ伸びる | 数字は棒の頭に付いて動く |
2426
2426
  * | `chart-pie` | 12 時 | 扇が時計回りに開く | 凡例はその扇が開き始めた時 |
2427
+ * | `chart-slope` | 左の軸 | 線が右の軸へ伸びる | 右の値は線が右の軸に着いた時 |
2427
2428
  * | `journey-map` | 左端 | 気持ちの線が右へ伸びる | 段はその点に線の先が届いた時 |
2428
2429
  * | `mind-map` | 中心 | 枝が段ごとに外へ伸びる | 箱はその枝が届いた時 |
2429
2430
  * | `tree-hierarchy` | 根 | 枝が段ごとに下へ伸びる | 箱はその枝が届いた時 |
2430
2431
  * | `gantt-timeline` | 各帯の始端 | 帯が右へ伸びる | 依存の矢印は帯が出揃った時 |
2431
2432
  * | `funnel-stages` | 上端 | 段が上から順に積まれる | 件数と離脱率はその段が出切った時 |
2433
+ * | `chart-gauge` | 9 時 | 弧が上を通って 3 時へ伸びる | 合計と内訳は最初から出る |
2434
+ * | `chart-radial` | 12 時 | 各輪が時計回りに開く | 軌道と一覧は最初から出る |
2435
+ * | `chart-stacked-bar` | 左端 | 帯が右へ伸びる | 区画の字はその区画が広がった時 |
2432
2436
  *
2433
2437
  * 対象種別の一覧は `validate.ts` の `DRAW_KINDS` が持つ。
2434
2438
  *
package/src/validate.ts CHANGED
@@ -23,6 +23,9 @@ const TONES = new Set<string>(TONE_NAMES);
23
23
  * | `tree-hierarchy` | 根 | 枝が上の段から下の段へ伸びる |
24
24
  * | `gantt-timeline` | 各帯の始端 | 帯が右へ伸びる |
25
25
  * | `funnel-stages` | 上端 | 段が上から順に積まれる |
26
+ * | `chart-gauge` | 9 時 | 弧が上を通って 3 時へ伸びる |
27
+ * | `chart-radial` | 12 時 | 各輪が時計回りに開く |
28
+ * | `chart-stacked-bar` | 左端 | 帯が右へ伸びる |
26
29
  */
27
30
  export const DRAW_KINDS: ReadonlySet<string> = new Set([
28
31
  "chart-line",
@@ -34,6 +37,9 @@ export const DRAW_KINDS: ReadonlySet<string> = new Set([
34
37
  "tree-hierarchy",
35
38
  "gantt-timeline",
36
39
  "funnel-stages",
40
+ "chart-gauge",
41
+ "chart-radial",
42
+ "chart-stacked-bar",
37
43
  ]);
38
44
  const KINDS = new Set<string>(NODE_KINDS);
39
45
  const ENG_BANNED = /\b(FUNCTION|STORAGE|EVENT LOG|BALANCES MAPPING|READ|WRITE|EMIT|CALL)\b/;