@cardenelabs/cdl 0.10.0 → 0.11.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 CHANGED
@@ -7,6 +7,24 @@ CDL (Chainome Diagram Language) の主要変更履歴。
7
7
 
8
8
  予定 ... feedback を反映した patch / minor。
9
9
 
10
+ ## [0.11.0] - 2026-08-21
11
+
12
+ ### Added
13
+
14
+ - **棒と扇も段の進みでそれぞれの起点から描けるようにした** (#517)
15
+
16
+ 段の `draw` は `0.10.0` で入ったが `chart-line` だけが対応していた。 対象を 3 種に広げ、
17
+ 棒は横軸から上へ伸び、扇は 12 時から時計回りに開くようにした。 数字は棒の頭に付いて動き、
18
+ 凡例はその扇が開き始めた時に出る。
19
+
20
+ **形を表す属性は触らない**。 折れ線が `points` を触らず dash で伸ばしたのと同じ制約で、
21
+ 棒は足元を動かさない点にした倍率で包み、円は扇形の切り抜きで見える範囲だけを変える。
22
+ `rect` の `height` / `y` と `path` の `d` は進みに関わらず実値のまま = 図形の寸法から値を
23
+ 測る利用側が、進みの途中で別の値を読まない。
24
+
25
+ 対応種別の一覧を `validate.ts` の `DRAW_KINDS` が持ち、書けない種別を指した時の知らせも
26
+ そこから組み立てる。
27
+
10
28
  ## [0.10.0] - 2026-08-21
11
29
 
12
30
  ### Added
@@ -436,7 +454,8 @@ Initial OSS release.
436
454
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
437
455
  行き止まりになる。
438
456
 
439
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.10.0...HEAD
457
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.11.0...HEAD
458
+ [0.11.0]: https://github.com/cardene777/cdl/compare/v0.10.0...v0.11.0
440
459
  [0.10.0]: https://github.com/cardene777/cdl/compare/v0.9.0...v0.10.0
441
460
  [0.9.0]: https://github.com/cardene777/cdl/compare/v0.8.0...v0.9.0
442
461
  [0.8.0]: https://github.com/cardene777/cdl/compare/v0.7.0...v0.8.0
package/SPEC.md CHANGED
@@ -133,9 +133,21 @@ diagram.phase(id, {
133
133
  ため、 連続する phase で光り続ける図が実在し、 光っているかを引き金にすると値が動くだけの
134
134
  phase でも線を引き直すことになる。
135
135
 
136
- 対象の node は phase の進み (0→1) に合わせて描かれる。 現在の対象種別は `chart-line` で、
137
- 折れ線が左端から右へ伸び、 点と値の数字は線の先が届いた時に現れる (軸 / 格子 / 横軸の名前は
138
- 最初から出る)。 `draw` を書かない図は従来どおり全長で描き、 DOM dash 属性も付かない。
136
+ 対象の node は phase の進み (0→1) に合わせて描かれる。 起点は種別ごとに違う。
137
+
138
+ | kind | 起点 | 動き | 添える値 |
139
+ |---|---|---|---|
140
+ | `chart-line` | 左端 | 線が右へ伸びる | 点と数字は線の先が届いた時 |
141
+ | `chart-bar` | 横軸 | 棒が上へ伸びる | 数字は棒の頭に付いて動く |
142
+ | `chart-pie` | 12 時 | 扇が時計回りに開く | 凡例はその扇が開き始めた時 |
143
+
144
+ 対応種別の一覧は `validate.ts` の `DRAW_KINDS` が持ち、 知らせの文面もそこから組み立てる。
145
+
146
+ **形を表す属性は触らない**。 折れ線は `points` を、 棒は `rect` の `height` / `y` を、
147
+ 円は `path` の `d` を進みに関わらず実値のまま保ち、 見える範囲だけを変える (dash / 倍率 /
148
+ 切り抜き)。 図形の寸法から値を測る利用側が、 進みの途中で別の値を読まないようにするため。
149
+
150
+ `draw` を書かない図は従来どおり全体を描き、 DOM に属性も要素も足さない。
139
151
 
140
152
  phase が定義されると自動的に。
141
153
  - 全 phase が timeline 化 (autoplay + loop)
package/dist/index.cjs CHANGED
@@ -15864,6 +15864,7 @@ function nodeTemplateTexts(node) {
15864
15864
 
15865
15865
  // src/validate.ts
15866
15866
  var TONES2 = new Set(TONES);
15867
+ var DRAW_KINDS = /* @__PURE__ */ new Set(["chart-line", "chart-bar", "chart-pie"]);
15867
15868
  var KINDS = new Set(NODE_KINDS);
15868
15869
  var ENG_BANNED = /\b(FUNCTION|STORAGE|EVENT LOG|BALANCES MAPPING|READ|WRITE|EMIT|CALL)\b/;
15869
15870
  function validate(diag) {
@@ -15981,8 +15982,10 @@ function validate(diag) {
15981
15982
  continue;
15982
15983
  }
15983
15984
  const kind = diag.nodes.find((n) => n.id === id)?.kind;
15984
- if (kind !== "chart-line") {
15985
- warnings.push(`phase "${p.id}" \u306E draw "${id}" \u306F kind "${kind}" \u3067\u3001 \u5DE6\u304B\u3089\u63CF\u304F\u52D5\u304D\u3092\u6301\u305F\u306A\u3044 (\u5BFE\u8C61\u306F chart-line)`);
15985
+ if (!DRAW_KINDS.has(String(kind))) {
15986
+ warnings.push(
15987
+ `phase "${p.id}" \u306E draw "${id}" \u306F kind "${kind}" \u3067\u3001 \u8D77\u70B9\u304B\u3089\u63CF\u304F\u52D5\u304D\u3092\u6301\u305F\u306A\u3044 (\u5BFE\u8C61\u306F ${[...DRAW_KINDS].join(" / ")})`
15988
+ );
15986
15989
  }
15987
15990
  }
15988
15991
  for (const t of p.tweens) {
@@ -21467,8 +21470,11 @@ function ChartLineNode({
21467
21470
  function ChartPieNode({
21468
21471
  node,
21469
21472
  active,
21470
- stateValues = {}
21473
+ stateValues = {},
21474
+ drawing = false,
21475
+ progress = 1
21471
21476
  }) {
21477
+ const instanceId = react.useId().replace(/[^A-Za-z0-9_-]/g, "");
21472
21478
  const x0 = node.cx - node.w / 2;
21473
21479
  const y0 = node.cy - node.h / 2;
21474
21480
  const data = resolveChartData(node.chartData ?? [], stateValues);
@@ -21481,20 +21487,26 @@ function ChartPieNode({
21481
21487
  const cx = pieAreaW / 2;
21482
21488
  const cy = PAD_TOP + chartAreaH / 2;
21483
21489
  let cumAngle = -Math.PI / 2;
21490
+ let cumFrac = 0;
21484
21491
  const slices = data.map((d) => {
21485
21492
  const frac = d.value / total;
21486
21493
  const angle = frac * Math.PI * 2;
21487
21494
  const a0 = cumAngle;
21488
21495
  const a1 = cumAngle + angle;
21489
21496
  cumAngle = a1;
21497
+ const startFrac = cumFrac;
21498
+ cumFrac += frac;
21490
21499
  const x1 = cx + radius * Math.cos(a0);
21491
21500
  const y1 = cy + radius * Math.sin(a0);
21492
21501
  const x2 = cx + radius * Math.cos(a1);
21493
21502
  const y2 = cy + radius * Math.sin(a1);
21494
21503
  const large = angle > Math.PI ? 1 : 0;
21495
21504
  const path = `M ${cx} ${cy} L ${x1} ${y1} A ${radius} ${radius} 0 ${large} 1 ${x2} ${y2} Z`;
21496
- return { d, frac, path };
21505
+ return { d, frac, path, startFrac };
21497
21506
  });
21507
+ const \u958B\u304D = drawing ? Math.min(1, Math.max(0, Number.isFinite(progress) ? progress : 1)) : 1;
21508
+ const \u5207\u308A\u629C\u304Did = `cdl-pie-draw-${instanceId}`;
21509
+ const \u958B\u304D\u59CB\u3081\u305F = (startFrac) => !drawing || \u958B\u304D > startFrac;
21498
21510
  const legendX = pieAreaW + 8;
21499
21511
  const legendGap = Math.min(28, chartAreaH / Math.max(data.length, 1));
21500
21512
  const legendStartY = PAD_TOP + (chartAreaH - legendGap * data.length) / 2 + legendGap / 2;
@@ -21513,7 +21525,8 @@ function ChartPieNode({
21513
21525
  strokeWidth: active ? 3 : 1.25
21514
21526
  }
21515
21527
  ),
21516
- slices.map((s, idx) => /* @__PURE__ */ jsxRuntime.jsx(
21528
+ drawing && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: \u5207\u308A\u629C\u304Did, children: \u6247\u5F62\u306E\u5207\u308A\u629C\u304D(cx, cy, radius + 2, \u958B\u304D) }) }),
21529
+ /* @__PURE__ */ jsxRuntime.jsx("g", { ...drawing ? { clipPath: `url(#${\u5207\u308A\u629C\u304Did})` } : {}, children: slices.map((s, idx) => /* @__PURE__ */ jsxRuntime.jsx(
21517
21530
  "path",
21518
21531
  {
21519
21532
  "data-cdl-role": "chart-pie-slice",
@@ -21525,8 +21538,8 @@ function ChartPieNode({
21525
21538
  strokeWidth: 1.5
21526
21539
  },
21527
21540
  `slice-${idx}`
21528
- )),
21529
- slices.map((s, idx) => /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${legendX} ${legendStartY + idx * legendGap})`, children: [
21541
+ )) }),
21542
+ slices.map((s, idx) => !\u958B\u304D\u59CB\u3081\u305F(s.startFrac) ? null : /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${legendX} ${legendStartY + idx * legendGap})`, children: [
21530
21543
  /* @__PURE__ */ jsxRuntime.jsx(
21531
21544
  "rect",
21532
21545
  {
@@ -21564,6 +21577,15 @@ function ChartPieNode({
21564
21577
  ] }, `legend-${idx}`))
21565
21578
  ] });
21566
21579
  }
21580
+ function \u6247\u5F62\u306E\u5207\u308A\u629C\u304D(cx, cy, r, \u958B\u304D) {
21581
+ if (\u958B\u304D <= 0) return null;
21582
+ if (\u958B\u304D >= 1) return /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r });
21583
+ const a0 = -Math.PI / 2;
21584
+ const a1 = a0 + \u958B\u304D * Math.PI * 2;
21585
+ const large = \u958B\u304D > 0.5 ? 1 : 0;
21586
+ 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`;
21587
+ return /* @__PURE__ */ jsxRuntime.jsx("path", { d });
21588
+ }
21567
21589
  var FALLBACK_ORDER = ["accent", "teal", "warning", "success", "info", "error"];
21568
21590
  function sliceColor(tone, idx) {
21569
21591
  if (tone) return TONE[tone];
@@ -21572,7 +21594,9 @@ function sliceColor(tone, idx) {
21572
21594
  function ChartBarNode({
21573
21595
  node,
21574
21596
  active,
21575
- stateValues = {}
21597
+ stateValues = {},
21598
+ drawing = false,
21599
+ progress = 1
21576
21600
  }) {
21577
21601
  const x0 = node.cx - node.w / 2;
21578
21602
  const y0 = node.cy - node.h / 2;
@@ -21595,6 +21619,8 @@ function ChartBarNode({
21595
21619
  const v = vMax * i / gridCount;
21596
21620
  return { y: yAt(v), value: v };
21597
21621
  });
21622
+ const \u4F38\u3073 = drawing ? Math.min(1, Math.max(0, Number.isFinite(progress) ? progress : 1)) : 1;
21623
+ const \u6A2A\u8EF8\u306Ey = PAD_TOP + canvasH;
21598
21624
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
21599
21625
  /* @__PURE__ */ jsxRuntime.jsx(
21600
21626
  "rect",
@@ -21651,26 +21677,28 @@ function ChartBarNode({
21651
21677
  const bx = xAt(idx);
21652
21678
  const by = yAt(d.value);
21653
21679
  const bh = PAD_TOP + canvasH - by;
21680
+ const \u898B\u3048\u3066\u3044\u308B\u982D = \u6A2A\u8EF8\u306Ey - (\u6A2A\u8EF8\u306Ey - by) * \u4F38\u3073;
21681
+ const \u68D2 = /* @__PURE__ */ jsxRuntime.jsx(
21682
+ "rect",
21683
+ {
21684
+ "data-cdl-role": "chart-bar",
21685
+ "data-cdl-unresolved": d.unresolved ? "true" : void 0,
21686
+ x: bx,
21687
+ y: by,
21688
+ width: barW,
21689
+ height: bh,
21690
+ rx: 2,
21691
+ fill: "var(--cdl-tone-accent, #2d6a8f)",
21692
+ fillOpacity: 0.9
21693
+ }
21694
+ );
21654
21695
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
21655
- /* @__PURE__ */ jsxRuntime.jsx(
21656
- "rect",
21657
- {
21658
- "data-cdl-role": "chart-bar",
21659
- "data-cdl-unresolved": d.unresolved ? "true" : void 0,
21660
- x: bx,
21661
- y: by,
21662
- width: barW,
21663
- height: bh,
21664
- rx: 2,
21665
- fill: "var(--cdl-tone-accent, #2d6a8f)",
21666
- fillOpacity: 0.9
21667
- }
21668
- ),
21696
+ drawing ? /* @__PURE__ */ jsxRuntime.jsx("g", { transform: `translate(0 ${\u6A2A\u8EF8\u306Ey}) scale(1 ${\u4F38\u3073}) translate(0 ${-\u6A2A\u8EF8\u306Ey})`, children: \u68D2 }) : \u68D2,
21669
21697
  /* @__PURE__ */ jsxRuntime.jsx(
21670
21698
  "text",
21671
21699
  {
21672
21700
  x: bx + barW / 2,
21673
- y: by - 6,
21701
+ y: \u898B\u3048\u3066\u3044\u308B\u982D - 6,
21674
21702
  fontSize: 11,
21675
21703
  textAnchor: "middle",
21676
21704
  fill: "var(--cdl-text, #1a1f2a)",
@@ -26804,9 +26832,27 @@ function CdlNodeView({
26804
26832
  }
26805
26833
  );
26806
26834
  case "chart-pie":
26807
- return /* @__PURE__ */ jsxRuntime.jsx(ChartPieNode, { node: resolvedNode, active, stateValues });
26835
+ return /* @__PURE__ */ jsxRuntime.jsx(
26836
+ ChartPieNode,
26837
+ {
26838
+ node: resolvedNode,
26839
+ active,
26840
+ stateValues,
26841
+ drawing,
26842
+ progress
26843
+ }
26844
+ );
26808
26845
  case "chart-bar":
26809
- return /* @__PURE__ */ jsxRuntime.jsx(ChartBarNode, { node: resolvedNode, active, stateValues });
26846
+ return /* @__PURE__ */ jsxRuntime.jsx(
26847
+ ChartBarNode,
26848
+ {
26849
+ node: resolvedNode,
26850
+ active,
26851
+ stateValues,
26852
+ drawing,
26853
+ progress
26854
+ }
26855
+ );
26810
26856
  case "gantt-timeline":
26811
26857
  return /* @__PURE__ */ jsxRuntime.jsx(GanttNode, { node: resolvedNode, active, stateValues });
26812
26858
  case "mind-map":