@cardenelabs/cdl 0.40.3 → 0.40.5

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
@@ -5,6 +5,46 @@ CDL (Chainome Diagram Language) の主要変更履歴。
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.40.5] - 2026-09-07
9
+
10
+ ### Fixed
11
+
12
+ - **内訳が多い半円ゲージで合計が主役でなくなるのを直した** (#735)
13
+
14
+ 段を折り返すようにした (#732) 結果、件数が増えると弧に残る高さが尽き、**合計の字が
15
+ 内訳の名前より小さくなっていた**。 実測で件数 22 から合計 13 に対し名前 14、
16
+ 件数 30 では合計が弧の内側の穴から 4.9 はみ出し、件数 40 では 10.2 はみ出した。
17
+ この種別は合計を大きく見せるために作ったので、主役が入れ替わると図の意味が変わる。
18
+
19
+ 弧に残す高さ (48) を先に確保し、そこから置ける段数を逆算する。 入り切らない件は
20
+ 末尾 1 件に「その他」 として畳み、**合計の値は変えない** = 畳んだ件の値を足して持たせる。
21
+ 弧も同じ並びで描くので、扇と内訳が食い違わない。
22
+
23
+ 合計の級の決め方も直した。 中心の高さの横幅で測っていたため、字が中心より上に置かれる
24
+ ぶんだけ穴からはみ出していた。 字の上の角が穴の円に入る大きさを解いて決める。
25
+
26
+ 件数 12 以下の図は段の数も弧の半径も今までと同じ (実測で 1 段が半径 128.96、
27
+ 2 段が 94.24 で前後一致)。
28
+
29
+ ## [0.40.4] - 2026-09-07
30
+
31
+ ### Fixed
32
+
33
+ - **値の動きが始まった瞬間に終わって見えるのを直した** (#736)
34
+
35
+ 段 (phase) の値を動かす動き (`tween`) は既定の曲線 `easeOutQuint` を通っており、
36
+ **動きが前半に寄りすぎていた**。 段の長さ 1.2 秒の折れ線で測ると、動きの 9 割が
37
+ 最初の 0.449 秒で終わり、残りの 0.75 秒はほとんど止まって見える (半分に達するのが
38
+ 段の 13.1% の時点)。 段を長くしても形は変わらず、止まって見える時間だけが伸びた。
39
+
40
+ 既定を `easeOut` (`cubic-bezier(0, 0, 0.58, 1)`) にゆるめた。 半分に達するのが
41
+ 34.2% の時点になり、段の終わりまで動き続ける。
42
+
43
+ 線を引く動き (`draw`) は今までどおり曲線を通らない (#711)。 ペンの速さは一定である
44
+ ほど「1 つずつ現れる」 が読めるため。
45
+
46
+ 曲線を差し替える口 (`TimelineOptions.easing`) は今までどおり開いている。
47
+
8
48
  ## [0.40.3] - 2026-09-07
9
49
 
10
50
  ### Fixed
@@ -1843,7 +1883,9 @@ Initial OSS release.
1843
1883
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
1844
1884
  行き止まりになる。
1845
1885
 
1846
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.40.3...HEAD
1886
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.40.5...HEAD
1887
+ [0.40.5]: https://github.com/cardene777/cdl/compare/v0.40.4...v0.40.5
1888
+ [0.40.4]: https://github.com/cardene777/cdl/compare/v0.40.3...v0.40.4
1847
1889
  [0.40.3]: https://github.com/cardene777/cdl/compare/v0.40.2...v0.40.3
1848
1890
  [0.40.2]: https://github.com/cardene777/cdl/compare/v0.40.1...v0.40.2
1849
1891
  [0.40.1]: https://github.com/cardene777/cdl/compare/v0.40.0...v0.40.1
package/dist/index.cjs CHANGED
@@ -14134,7 +14134,7 @@ function cubicBezier(x1, y1, x2, y2) {
14134
14134
  return sampleCurveY(solveCurveX(t));
14135
14135
  };
14136
14136
  }
14137
- var easeOutQuint = cubicBezier(0.22, 1, 0.36, 1);
14137
+ var easeOut = cubicBezier(0, 0, 0.58, 1);
14138
14138
  function clamp01(value) {
14139
14139
  if (value < 0) return 0;
14140
14140
  if (value > 1) return 1;
@@ -14179,7 +14179,7 @@ var Timeline = class {
14179
14179
  throw new Error("Timeline requires at least one phase");
14180
14180
  }
14181
14181
  this.phases = phases;
14182
- this.easing = options.easing ?? easeOutQuint;
14182
+ this.easing = options.easing ?? easeOut;
14183
14183
  this.loop = options.loop ?? false;
14184
14184
  this.autoAdvanceMsOverride = options.autoAdvanceMs;
14185
14185
  this.phaseHoldMs = options.phaseHoldMs ?? 0;
@@ -24892,13 +24892,46 @@ function ChartGaugeNode({
24892
24892
  const \u5F27\u3068\u5185\u8A33\u306E\u9593 = 16;
24893
24893
  const \u5370\u306E\u5E452 = 30;
24894
24894
  const \u533A\u753B\u306E\u9593 = 12;
24895
- const \u5185\u8A33\u306E\u6570\u5024 = data.map((d) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u5272\u5408\u8868\u8A18(d.value / total)}`);
24896
- const \u4EF6\u306B\u8981\u308B\u5E45 = Math.max(\u5370\u306E\u5E452, ...\u5185\u8A33\u306E\u6570\u5024.map((t) => textWidth(t, \u6570\u5024\u306E\u7D1A))) + \u533A\u753B\u306E\u9593;
24897
- const \u884C\u306E\u4EF6\u6570 = Math.min(
24898
- Math.max(1, Math.floor(\u4F7F\u3048\u308B\u5E452 / Math.max(\u4EF6\u306B\u8981\u308B\u5E45, 1))),
24899
- Math.max(data.length, 1)
24895
+ const \u6570\u5024\u306E\u884C = (d) => `${\u5B9F\u5024\u8868\u8A18(d.value)} ${\u5272\u5408\u8868\u8A18(d.value / total)}`;
24896
+ const \u5272\u308A\u4ED8\u3051\u308B = (\u4EF6\u305F\u3061) => {
24897
+ const \u5E45 = Math.max(\u5370\u306E\u5E452, ...\u4EF6\u305F\u3061.map((d) => textWidth(\u6570\u5024\u306E\u884C(d), \u6570\u5024\u306E\u7D1A))) + \u533A\u753B\u306E\u9593;
24898
+ const \u884C\u306E\u4EF6\u65702 = Math.min(
24899
+ Math.max(1, Math.floor(\u4F7F\u3048\u308B\u5E452 / Math.max(\u5E45, 1))),
24900
+ Math.max(\u4EF6\u305F\u3061.length, 1)
24901
+ );
24902
+ return { \u884C\u306E\u4EF6\u6570: \u884C\u306E\u4EF6\u65702, \u6BB5\u6570: Math.ceil(Math.max(\u4EF6\u305F\u3061.length, 1) / \u884C\u306E\u4EF6\u65702) };
24903
+ };
24904
+ const \u5F27\u306B\u6B8B\u3059\u9AD8\u3055 = 48;
24905
+ const \u7F6E\u3051\u308B\u6BB5\u6570 = Math.max(
24906
+ 1,
24907
+ Math.floor((\u4F7F\u3048\u308B\u9AD8\u3055 - \u5F27\u306B\u6B8B\u3059\u9AD8\u3055 - \u5F27\u3068\u5185\u8A33\u306E\u9593) / \u6BB5\u306E\u9AD8\u3055)
24900
24908
  );
24901
- const \u5185\u8A33\u306E\u6BB5\u6570 = Math.ceil(Math.max(data.length, 1) / \u884C\u306E\u4EF6\u6570);
24909
+ const \u7573\u3080 = (\u6B8B\u3059\u4EF6\u6570) => {
24910
+ if (\u6B8B\u3059\u4EF6\u6570 >= data.length) return data;
24911
+ const \u524D = data.slice(0, Math.max(0, \u6B8B\u3059\u4EF6\u6570 - 1));
24912
+ const \u6B8B\u308A = data.slice(Math.max(0, \u6B8B\u3059\u4EF6\u6570 - 1));
24913
+ const \u5024 = \u6B8B\u308A.reduce((acc, d) => acc + d.value, 0);
24914
+ const \u8AAD\u3081\u306A\u3044 = \u6B8B\u308A.some((d) => d.unresolved);
24915
+ const \u7573\u3093\u3060 = {
24916
+ ...\u6B8B\u308A[0],
24917
+ label: "\u305D\u306E\u4ED6",
24918
+ value: \u5024,
24919
+ previous: void 0,
24920
+ ...\u8AAD\u3081\u306A\u3044 ? { unresolved: true } : { unresolved: void 0 }
24921
+ };
24922
+ return [...\u524D, \u7573\u3093\u3060];
24923
+ };
24924
+ const \u51FA\u3059\u4EF6\u305F\u3061 = (() => {
24925
+ let \u4EF6\u305F\u3061 = data;
24926
+ for (let i = 0; i < 4; i++) {
24927
+ const { \u884C\u306E\u4EF6\u6570: \u884C\u306E\u4EF6\u65702, \u6BB5\u6570 } = \u5272\u308A\u4ED8\u3051\u308B(\u4EF6\u305F\u3061);
24928
+ if (\u6BB5\u6570 <= \u7F6E\u3051\u308B\u6BB5\u6570) return \u4EF6\u305F\u3061;
24929
+ \u4EF6\u305F\u3061 = \u7573\u3080(Math.max(1, \u7F6E\u3051\u308B\u6BB5\u6570 * \u884C\u306E\u4EF6\u65702));
24930
+ }
24931
+ return \u4EF6\u305F\u3061;
24932
+ })();
24933
+ const \u5185\u8A33\u306E\u6570\u5024 = \u51FA\u3059\u4EF6\u305F\u3061.map((d) => \u6570\u5024\u306E\u884C(d));
24934
+ const { \u884C\u306E\u4EF6\u6570, \u6BB5\u6570: \u5185\u8A33\u306E\u6BB5\u6570 } = \u5272\u308A\u4ED8\u3051\u308B(\u51FA\u3059\u4EF6\u305F\u3061);
24902
24935
  const \u5185\u8A33\u306E\u9AD8\u3055 = \u6BB5\u306E\u9AD8\u3055 * \u5185\u8A33\u306E\u6BB5\u6570;
24903
24936
  const \u5F27\u306B\u4F7F\u3048\u308B\u9AD8\u3055 = \u4F7F\u3048\u308B\u9AD8\u3055 - \u5185\u8A33\u306E\u9AD8\u3055 - \u5F27\u3068\u5185\u8A33\u306E\u9593;
24904
24937
  const radius = Math.max(24, Math.min(\u5F27\u306B\u4F7F\u3048\u308B\u9AD8\u3055, \u4F7F\u3048\u308B\u5E452 / 2));
@@ -24906,7 +24939,7 @@ function ChartGaugeNode({
24906
24939
  const cx = node.w / 2;
24907
24940
  const cy = PAD_TOP2 + radius;
24908
24941
  let cumFrac = 0;
24909
- const slices = data.map((d) => {
24942
+ const slices = \u51FA\u3059\u4EF6\u305F\u3061.map((d) => {
24910
24943
  const frac = d.value / total;
24911
24944
  const a0 = Math.PI + cumFrac * Math.PI;
24912
24945
  const a1 = a0 + frac * Math.PI;
@@ -24919,10 +24952,10 @@ function ChartGaugeNode({
24919
24952
  return { d, frac, path };
24920
24953
  });
24921
24954
  const \u5408\u8A08\u306E\u6587\u5B57 = \u5B9F\u5024\u8868\u8A18(Math.round(total));
24922
- const \u6A2A\u306E\u4E0A\u9650 = \u5185\u534A\u5F84 * 2 * 0.86;
24955
+ const \u5358\u4F4D\u5E45 = Math.max(textWidth(\u5408\u8A08\u306E\u6587\u5B57, 100), 1) / 100;
24923
24956
  const \u7D1A\u306E\u5019\u88DC = Math.min(
24924
- // 横 = 実際の字幅から逆算する
24925
- \u6A2A\u306E\u4E0A\u9650 / Math.max(textWidth(\u5408\u8A08\u306E\u6587\u5B57, 100), 1) * 100,
24957
+ // 横 = 字の上の角が内側の円に入る大きさ
24958
+ \u5185\u534A\u5F84 / Math.sqrt((\u5358\u4F4D\u5E45 / 2) ** 2 + 1.25 ** 2),
24926
24959
  // 縦 = 合計 1 行 + 見出し 1 行が内側の高さに収まる比
24927
24960
  \u5185\u534A\u5F84 * 0.52
24928
24961
  );
@@ -24985,7 +25018,7 @@ function ChartGaugeNode({
24985
25018
  children: "\u5408\u8A08"
24986
25019
  }
24987
25020
  ),
24988
- data.map((d, idx) => {
25021
+ \u51FA\u3059\u4EF6\u305F\u3061.map((d, idx) => {
24989
25022
  const \u5217 = idx % \u884C\u306E\u4EF6\u6570;
24990
25023
  const \u6BB5 = Math.floor(idx / \u884C\u306E\u4EF6\u6570);
24991
25024
  const x = PAD_SIDE + \u5185\u8A33\u306E\u5E45 * \u5217;