@cardenelabs/cdl 0.40.8 → 0.40.10

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.8",
3
+ "version": "0.40.10",
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",
@@ -18,8 +18,13 @@ import { 実値表記, 割合表記 } from "./chart-number";
18
18
  *
19
19
  * ## 数値をいちばん大きく組む
20
20
  *
21
- * 件ごとに区画を割り、名前 / 数値 / 割合を縦に積む。 **数値の字を名前より大きくする** のが
22
- * この種別の中身で、大小が逆転したら別の図になる。
21
+ * 件ごとに区画を割り、名前 / 数値 / 前の時点 / 割合を縦に積む。 **数値の字を名前より大きくする**
22
+ * のがこの種別の中身で、大小が逆転したら別の図になる。
23
+ *
24
+ * ## 前の時点は書いた図にだけ足す (cdl#763)
25
+ *
26
+ * `previous` を書いた図では数値の下に前の値を 1 行添える。 書いていない図では 1 行も足さず、
27
+ * 縦の位置も変えない = 前の値と関係の無い図の見た目を動かさない。
23
28
  *
24
29
  * ## 弧は輪郭だけの細い線にする
25
30
  *
@@ -40,7 +45,27 @@ export function ChartStatNode({
40
45
  const data = resolveChartData(node.chartData ?? [], stateValues);
41
46
  const total = data.reduce((acc, d) => acc + d.value, 0) || 1;
42
47
 
43
- const 区画 = 区画の割付(node.w, node.h, data.length);
48
+ /**
49
+ * 前の時点を出すか (cdl#763)。
50
+ *
51
+ * **図の単位で決める**。 件ごとに決めると、一部だけ前を持つ図で行の位置が件ごとに
52
+ * ずれる。 縦の位置は件数に依らないという既存の割付の考えに揃える。
53
+ */
54
+ const 前を出す = data.some((d) => d.previous !== undefined);
55
+
56
+ const 区画 = 区画の割付(node.w, node.h, data.length, 前を出す);
57
+
58
+ /**
59
+ * 割合を出すか (cdl#759)。
60
+ *
61
+ * 割合は **この図に載っている全件の合計に対する取り分** なので、件が 1 つだと分母が
62
+ * 自分自身になり必ず `100%` になる。 値が動いても割合は動かない。 数値を主役にする
63
+ * 種別で、主役の隣に何も伝えない数と輪を常に出すことになる。
64
+ *
65
+ * **判定は件数で行う**。 `割合 === 1` で判定すると、件が 2 つ以上でも片方が 0 の図まで
66
+ * 消える。 その図の `100%` は「他が 0 で自分が全部」 という読みが成立する。
67
+ */
68
+ const 割合を出す = data.length > 1;
44
69
 
45
70
  return (
46
71
  <g transform={`translate(${x0} ${y0})`}>
@@ -64,7 +89,11 @@ export function ChartStatNode({
64
89
  // 数値は区画に収まるまで小さくする。 収まらないまま描くと隣の区画へはみ出す
65
90
  const 数値の級 = 収める級(数値, 枠.w - 区画.余白 * 2, 区画.数値の級, 区画.名前の級 + 1);
66
91
  return (
67
- <g key={`stat-${idx}`} data-cdl-role="chart-stat-item" transform={`translate(${枠.x} ${枠.y})`}>
92
+ <g
93
+ key={`stat-${idx}`}
94
+ data-cdl-role="chart-stat-item"
95
+ transform={`translate(${枠.x} ${枠.y})`}
96
+ >
68
97
  {/* 仕切り。 1 件だけの図では引かない (仕切る相手がいない) */}
69
98
  {idx > 0 && (
70
99
  <line
@@ -103,21 +132,46 @@ export function ChartStatNode({
103
132
  {数値}
104
133
  </text>
105
134
 
135
+ {/*
136
+ 前の時点の値 (cdl#763)。 **`0` は値なので描く** = `undefined` と区別しないと、
137
+ 前が 0 だった件だけ黙って消える。 呼び方は積み上げの帯と揃える
138
+ */}
139
+ {d.previous !== undefined && (
140
+ <text
141
+ data-cdl-role="chart-stat-previous"
142
+ data-cdl-unresolved={d.unresolved ? "true" : undefined}
143
+ x={枠.w / 2}
144
+ y={区画.前のy}
145
+ fontSize={収める級(
146
+ `前 ${実値表記(d.previous)}`,
147
+ 枠.w - 区画.余白 * 2,
148
+ 区画.前の級,
149
+ 8,
150
+ )}
151
+ textAnchor="middle"
152
+ fill="var(--cdl-text-dim, #5a6270)"
153
+ >
154
+ {`前 ${実値表記(d.previous)}`}
155
+ </text>
156
+ )}
157
+
106
158
  {/*
107
159
  比率の弧。 **輪郭だけの細い線** で描く = 面で塗ると数値より目立ち、
108
160
  「数値が主役」 というこの種別の中身が崩れる
109
161
  */}
110
- <circle
111
- data-cdl-role="chart-stat-track"
112
- cx={枠.w / 2}
113
- cy={区画.弧のy}
114
- r={区画.弧の半径}
115
- fill="none"
116
- stroke="var(--cdl-divider, #d4d4d8)"
117
- strokeWidth={区画.弧の太さ}
118
- strokeOpacity={0.5}
119
- />
120
- {frac > 0 && (
162
+ {割合を出す && (
163
+ <circle
164
+ data-cdl-role="chart-stat-track"
165
+ cx={枠.w / 2}
166
+ cy={区画.弧のy}
167
+ r={区画.弧の半径}
168
+ fill="none"
169
+ stroke="var(--cdl-divider, #d4d4d8)"
170
+ strokeWidth={区画.弧の太さ}
171
+ strokeOpacity={0.5}
172
+ />
173
+ )}
174
+ {割合を出す && frac > 0 && (
121
175
  <path
122
176
  data-cdl-role="chart-stat-arc"
123
177
  d={弧の道(枠.w / 2, 区画.弧のy, 区画.弧の半径, Math.min(frac, 0.9999))}
@@ -128,16 +182,18 @@ export function ChartStatNode({
128
182
  />
129
183
  )}
130
184
 
131
- <text
132
- data-cdl-role="chart-stat-share"
133
- x={枠.w / 2}
134
- y={区画.割合のy}
135
- fontSize={区画.割合の級}
136
- textAnchor="middle"
137
- fill="var(--cdl-text-dim, #5a6270)"
138
- >
139
- {割合表記(frac)}
140
- </text>
185
+ {割合を出す && (
186
+ <text
187
+ data-cdl-role="chart-stat-share"
188
+ x={枠.w / 2}
189
+ y={区画.割合のy}
190
+ fontSize={区画.割合の級}
191
+ textAnchor="middle"
192
+ fill="var(--cdl-text-dim, #5a6270)"
193
+ >
194
+ {割合表記(frac)}
195
+ </text>
196
+ )}
141
197
  </g>
142
198
  );
143
199
  })}
@@ -151,34 +207,47 @@ export function ChartStatNode({
151
207
  * 件数で横に等分する。 **縦の位置は件数に依らない** = 件数が変わると数値の高さが動く形に
152
208
  * すると、同じ図を並べた時に数値の行が揃わない。
153
209
  */
154
- function 区画の割付(w: number, h: number, 件数: number) {
210
+ function 区画の割付(w: number, h: number, 件数: number, 前を出す: boolean) {
155
211
  const 余白 = 20;
156
212
  const 幅 = 件数 > 0 ? w / 件数 : w;
157
213
  const 名前の級 = 14;
158
214
  /** 数値の級。 **名前より大きい** のがこの種別の中身 */
159
215
  const 数値の級 = 40;
216
+ /** 前の時点の級。 名前と同じにする = 数値より大きくすると主役が入れ替わる (cdl#763) */
217
+ const 前の級 = 名前の級;
160
218
  const 割合の級 = 12;
161
219
  const 弧の半径 = 20;
162
220
  const 弧の太さ = 4;
163
221
 
164
- // 上から 名前 / 数値 / 弧 / 割合 の順に積む。 中身の高さを出してから縦中央に寄せる
165
- const 中身の高さ = 名前の級 + 12 + 数値の級 + 16 + 弧の半径 * 2 + 8 + 割合の級;
222
+ /**
223
+ * 前の行が使う縦の量 (cdl#763)。
224
+ *
225
+ * **前を持たない図では 0 にする**。 足すと既存の図で数値の位置が上へずれる =
226
+ * 前の値と関係の無い図の見た目が変わる。
227
+ */
228
+ const 前の高さ = 前を出す ? 8 + 前の級 : 0;
229
+
230
+ // 上から 名前 / 数値 / 前 / 弧 / 割合 の順に積む。 中身の高さを出してから縦中央に寄せる
231
+ const 中身の高さ = 名前の級 + 12 + 数値の級 + 前の高さ + 16 + 弧の半径 * 2 + 8 + 割合の級;
166
232
  const 上端 = Math.max(余白, (h - 中身の高さ) / 2);
167
233
 
168
234
  const 名前のy = 上端 + 名前の級;
169
235
  const 数値のy = 名前のy + 12 + 数値の級 * 0.78;
170
- const 弧のy = 数値のy + 16 + 弧の半径;
236
+ const 前のy = 数値のy + 8 + 前の級;
237
+ const 弧のy = 数値のy + 前の高さ + 16 + 弧の半径;
171
238
  const 割合のy = 弧のy + 弧の半径 + 8 + 割合の級;
172
239
 
173
240
  return {
174
241
  余白,
175
242
  名前の級,
176
243
  数値の級,
244
+ 前の級,
177
245
  割合の級,
178
246
  弧の半径,
179
247
  弧の太さ,
180
248
  名前のy,
181
249
  数値のy,
250
+ 前のy,
182
251
  弧のy,
183
252
  割合のy,
184
253
  枠: (idx: number) => ({ x: 幅 * idx, y: 0, w: 幅, h }),