@cardenelabs/cdl 0.40.2 → 0.40.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cardenelabs/cdl",
3
- "version": "0.40.2",
3
+ "version": "0.40.3",
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",
@@ -65,10 +65,43 @@ export function ChartGaugeNode({
65
65
 
66
66
  const 名前の級 = 14;
67
67
  const 数値の級 = 13;
68
- /** 内訳の 1 件が縦に使う高さ (印 + 名前 + 数値) */
69
- const 内訳の高さ = 56;
68
+ /** 内訳の 1 段が縦に使う高さ (印 + 名前 + 数値) */
69
+ const 段の高さ = 56;
70
70
  /** 弧と内訳の間 */
71
71
  const 弧と内訳の間 = 16;
72
+ /** 色の印の幅と、区画どうしの間 */
73
+ const 印の幅 = 30;
74
+ const 区画の間 = 12;
75
+
76
+ /**
77
+ * 内訳の割付 (cdl#731)。
78
+ *
79
+ * **件数で等分するだけでは足りない**。 名前は区画に収まるまで切り詰めていたが数値は
80
+ * そのままだったので、件数が増えると数字が隣へはみ出してくっついた
81
+ * (実測で件数 10 から重なり始め、12 で 10 組)。
82
+ *
83
+ * 区画の幅を **中身から決めて**、1 行に置ける件数を出す。 余りは次の段へ送る。
84
+ * 段が増えたぶん弧は低くなる = 弧の高さは残りから決めているので自動で縮む。
85
+ *
86
+ * 級を下げて 1 行に収める案は採らない = 件数 12 では級 7.7 が要り、この repo が
87
+ * 他の図で使っている下限の 9 を下回る。
88
+ */
89
+ const 内訳の数値 = data.map((d) => `${実値表記(d.value)} ${割合表記(d.value / total)}`);
90
+
91
+ /**
92
+ * 内訳 1 件が横に要る幅。 数値の行と色の印の広い方に、区画どうしの間を足す。
93
+ *
94
+ * **印の幅が広い方になる入力は組めない** = 数値の行は最も短い形 (`1 50%`) でも級 13 で
95
+ * 幅 56.7 あり、印の 30 を必ず上回る。 件数 0 の図で `Math.max` の引数が空になるのを
96
+ * 防ぐ下限として置いている。 万一この関係が崩れても印は区画に合わせて縮む (下の `Math.min`)。
97
+ */
98
+ const 件に要る幅 = Math.max(印の幅, ...内訳の数値.map((t) => textWidth(t, 数値の級))) + 区画の間;
99
+ const 行の件数 = Math.min(
100
+ Math.max(1, Math.floor(使える幅 / Math.max(件に要る幅, 1))),
101
+ Math.max(data.length, 1),
102
+ );
103
+ const 内訳の段数 = Math.ceil(Math.max(data.length, 1) / 行の件数);
104
+ const 内訳の高さ = 段の高さ * 内訳の段数;
72
105
 
73
106
  /**
74
107
  * 弧の外半径。
@@ -123,8 +156,8 @@ export function ChartGaugeNode({
123
156
  const 合計の級 = Math.max(11, Math.round(級の候補));
124
157
  const 見出しの級 = Math.max(9, Math.round(合計の級 * 0.38));
125
158
 
126
- /** 内訳 1 件あたりの幅。 等分して左から並べる */
127
- const 内訳の幅 = 使える幅 / Math.max(data.length, 1);
159
+ /** 内訳 1 件あたりの幅。 1 行に置く件数で等分する */
160
+ const 内訳の幅 = 使える幅 / 行の件数;
128
161
  const 内訳のy = cy + 弧と内訳の間;
129
162
 
130
163
  /** 弧がどこまで伸びたか (0..1、 cdl#715)。 畳み方は `draw-progress.ts` が持つ */
@@ -207,22 +240,34 @@ export function ChartGaugeNode({
207
240
  字は区画の左端に揃える。 中央揃えにすると名前の長さで位置が動き、 縦の列が揃わない。
208
241
  */}
209
242
  {data.map((d, idx) => {
210
- const x = PAD_SIDE + 内訳の幅 * idx;
211
- const 数値 = `${実値表記(d.value)} ${割合表記(d.value / total)}`;
243
+ const 列 = idx % 行の件数;
244
+ const 段 = Math.floor(idx / 行の件数);
245
+ const x = PAD_SIDE + 内訳の幅 * 列;
246
+ const y = 内訳のy + 段の高さ * 段;
247
+ /** 区画に収まる字幅。 名前も数値も同じ幅で切る */
248
+ const 収まる幅 = 内訳の幅 - 区画の間;
212
249
  return (
213
250
  <g key={`legend-${idx}`} data-cdl-role="chart-gauge-item">
214
- <rect x={x} y={内訳のy} width={30} height={4} rx={2} fill={arcColor(d.tone, idx)} />
251
+ <rect
252
+ x={x}
253
+ y={y}
254
+ width={Math.max(4, Math.min(印の幅, 収まる幅))}
255
+ height={4}
256
+ rx={2}
257
+ fill={arcColor(d.tone, idx)}
258
+ />
215
259
  <text
216
260
  x={x}
217
- y={内訳のy + 26}
261
+ y={y + 26}
218
262
  fontSize={名前の級}
219
263
  fontWeight={700}
220
264
  fill="var(--cdl-text, #1a1f2a)"
221
265
  >
222
- {切り詰める(d.label ?? "", 内訳の幅 - 12, 名前の級)}
266
+ {切り詰める(d.label ?? "", 収まる幅, 名前の級)}
223
267
  </text>
224
- <text x={x} y={内訳のy + 46} fontSize={数値の級} fill="var(--cdl-text-dim, #5a6270)">
225
- {数値}
268
+ {/* **数値も切り詰める** = 切らないと隣の区画の字とくっつく (cdl#731) */}
269
+ <text x={x} y={y + 46} fontSize={数値の級} fill="var(--cdl-text-dim, #5a6270)">
270
+ {切り詰める(内訳の数値[idx] ?? "", 収まる幅, 数値の級)}
226
271
  </text>
227
272
  </g>
228
273
  );