@cardenelabs/cdl 0.83.0 → 0.102.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +851 -1
  2. package/dist/index.cjs +878 -186
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +17 -3
  5. package/dist/index.d.ts +17 -3
  6. package/dist/index.js +878 -186
  7. package/dist/index.js.map +1 -1
  8. package/dist/react.cjs +869 -178
  9. package/dist/react.cjs.map +1 -1
  10. package/dist/react.d.cts +1 -1
  11. package/dist/react.d.ts +1 -1
  12. package/dist/react.js +869 -178
  13. package/dist/react.js.map +1 -1
  14. package/dist/{render-DfXCs3Eh.d.cts → render-oEmwYN-q.d.cts} +21 -3
  15. package/dist/{render-DfXCs3Eh.d.ts → render-oEmwYN-q.d.ts} +21 -3
  16. package/package.json +1 -1
  17. package/src/kinds/chart-gauge.tsx +20 -3
  18. package/src/kinds/chart-legend-number.tsx +33 -0
  19. package/src/kinds/chart-number.ts +33 -0
  20. package/src/kinds/chart-radial.tsx +24 -7
  21. package/src/kinds/chart-stat.tsx +35 -5
  22. package/src/kinds/chart-waffle.tsx +25 -7
  23. package/src/kinds/dyn-shape.tsx +72 -12
  24. package/src/kinds/funnel.tsx +50 -2
  25. package/src/kinds/mind-map.tsx +206 -64
  26. package/src/kinds/quadrant.tsx +318 -45
  27. package/src/kinds/shape-blockchain.tsx +50 -18
  28. package/src/kinds/shape-commerce.tsx +27 -4
  29. package/src/kinds/shape-region.tsx +42 -1
  30. package/src/kinds/shape-software.tsx +51 -12
  31. package/src/kinds/storage.tsx +16 -8
  32. package/src/kinds/tree.tsx +46 -10
  33. package/src/lang.ts +5 -5
  34. package/src/layout/nodes.ts +3 -1
  35. package/src/layout/spec.ts +154 -25
  36. package/src/layout/text-width.ts +25 -0
  37. package/src/layout/viewbox.ts +32 -0
  38. package/src/presets.ts +21 -7
  39. package/src/render/nodes.tsx +77 -0
  40. package/src/render/payload-binding.ts +108 -25
  41. package/src/render/stage.tsx +24 -2
  42. package/src/types.ts +117 -38
  43. package/src/visual-validate.ts +61 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,836 @@ CDL (Chainome Diagram Language) の主要変更履歴。
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.102.0] - 2026-09-30
9
+
10
+ ### Fixed
11
+
12
+ - **課題の札と連なりの塊が、肩書に書いた語を描いていなかった** (#941)
13
+
14
+ `shape-kanban-card` と `shape-blockchain-block` の 2 種が、肩書 (`eyebrow`) に書いた語を
15
+ 1 文字も描いていなかった。 見本帳の 606 枚で軸 `node-field-unsupported` (#933) が出す
16
+ 5 件の全部がこの 2 種だった。
17
+
18
+ **課題の札は控えの語を出していた**。 札の状態は辞書の固定語で、書き手の語ではなかった。
19
+
20
+ ```
21
+ lang.ts "kanbanCard.status": "進行中" (英語では "IN PROG")
22
+ 見本 eyebrow: "看板"
23
+ 画面 進行中 ← 書いた語が消え、控えが出ていた
24
+ ```
25
+
26
+ 読み手には、書いてもいない語が図の一部として見えていた。 題を見出しへ、説明を課題の
27
+ 1 行へ通した #927 と同じ形で、肩書を状態の札へ通した。 書かなければ今までどおり控えを出す。
28
+
29
+ 札は広げない。 札の自然幅が絵全体の縮尺を決めるため (#891)、広げると札の中の字だけでなく
30
+ 全部の字が小さくなる。 長い語は札の中で字を縮める。
31
+
32
+ **連なりの塊は見出しの帯の右が空いていた**。 帯 (高さ 32) は左に題、右上に丸を置くだけで、
33
+ その間に置き場があった。 丸の左に右揃えで描く。
34
+
35
+ ```
36
+ ┌────────────────────────┐
37
+ │ Block #4821 台帳 ● │ ← 肩書を丸の左へ
38
+ ├────────────────────────┤
39
+ │ prev 0x7f3a… │
40
+ ```
41
+
42
+ 題の使える幅から肩書の分を引く = 引かないと長い題と肩書が帯の中で重なる。 肩書の幅は
43
+ 帯の残りの半分を上限にし、超える語は **切らずに字を縮める** = 分類を表す語なので末尾を
44
+ 落とすと何の分類か読めなくなる。
45
+
46
+ 連なりの塊は控えを持たない。 肩書が「その塊が何か」 を言う語で、控えを置くと書いてもいない
47
+ 分類が図に出る。
48
+
49
+ **一覧を 2 つ直した**。 `rendersEyebrow` の除外 (`layout/spec.ts`) と、共有 plan が落としても
50
+ 固有 layout で描く種別の一覧 (`kinds/shape-region.tsx`)。 どちらも実際の描画との一致を
51
+ 全種別の検査が見ているため、片方だけ直すと落ちる。
52
+
53
+ ## [0.101.0] - 2026-09-30
54
+
55
+ ### Changed
56
+
57
+ - **図表の小見出しに記法の型の名前を焼き付けるのをやめた** (#939)
58
+
59
+ 図表を作る 7 つの組み立て器 (`tree` / `userJourney` / `mindMap` / `funnel` /
60
+ `quadrant` / `chart` / `gantt`) が、箱の小見出し (`eyebrow`) に型の名前を焼き付けて
61
+ いた。 書き換える口が無く、呼び出し側が別の語を渡す手段も無かった。
62
+
63
+ 0.99.0 (#935) で図表の小見出しを描くようにしたため、**この語が画面に出るようになった**。
64
+
65
+ ```
66
+ quadrant ← 焼き付けた型の名前が出ていた
67
+ どの作業から取るか ← 図の題
68
+ ┌──────────┐
69
+ │ 4 象限の図 │
70
+ └──────────┘
71
+ ```
72
+
73
+ 型の名前は書き手の都合で、読み手には何も伝えない。 しかも **図を見れば分かること** を
74
+ 字で繰り返していた (円グラフを見て `pie` と書いてある)。
75
+
76
+ 消すだけにせず、7 つの設定に `eyebrow?: string` を足して渡せる口にした。 書かなければ
77
+ 小見出しを持たない箱になり、書いた語がそのまま出る。
78
+
79
+ ```ts
80
+ chart({ id: "c", topic: "入り口ごとの内訳", type: "pie", eyebrow: "内訳" })
81
+ ```
82
+
83
+ **絵に出ていないことを伝える小見出しは残した**。 状態遷移の `初期` / `最終` / `状態` と
84
+ 網構成の機器の種類と区画、ER の `エンティティ` は、いずれも絵からは読み取れない。
85
+
86
+ ## [0.100.0] - 2026-09-30
87
+
88
+ ### Fixed
89
+
90
+ - **表の箱に書いた日本語の呼び名が出ていなかった** (#937)
91
+
92
+ `storage` の箱は題の下に呼び名 (`subtitle`) を置く場所を持つが、**行頭の印で群を分ける
93
+ 書き方の箱でだけ** 出していた。 判定は `node.rowMarks !== undefined` で、印を書かない
94
+ 従来の箱では呼び名を落としていた。
95
+
96
+ 見本 374 枚で **36 件** が消えていた。 ER の図は表の名前を識別子 (`users` /
97
+ `order_items`) で書くため、日本語の呼び名が唯一の読み口になる。
98
+
99
+ ```
100
+ users に 利用者
101
+ orders に 注文
102
+ order_items に 注文の明細
103
+ projects に 案件
104
+ ```
105
+
106
+ 置き場が無いのではなく **下げていなかった**。 印を書いた箱では既に行の塊を
107
+ `SUBTITLE_ROW_SHIFT` (46) 下げており、従来の箱は区切り線がその位置に残っていた。
108
+ 区切り線も同じ分だけ下げれば置き場ができる。
109
+
110
+ ```
111
+ 直す前 (従来の箱) 直した後
112
+ users ← 題 86 users ← 題 86
113
+ ───────── ← 線 110 利用者 ← 呼び名 118
114
+ id: uuid ← 行 152 ───────── ← 線 156
115
+ id: uuid ← 行 198
116
+ ```
117
+
118
+ 高さの計算 (`layout/nodes.ts` の `autoStorageHeight`) も同じ条件にした。
119
+ 片方だけ条件が違うと、下げた分が箱に入らず下端をまたぐ。
120
+
121
+ **呼び名を書かない箱は 1 mm も動かない**。 下げるのは呼び名を書いた箱だけで、
122
+ 焼き付けた見た目の検査は 1 件も落ちていない。
123
+
124
+ - **軸 70 が印を書いた表の箱で誤検知していた** (#937)
125
+
126
+ `rendersSubtitle` は種別だけで判定するため `storage` は一律「描かない」 を返すが、
127
+ 印を書いた箱は描いていた。 つまり **描いているのに軸が「出ない」 と言う** 状態だった。
128
+
129
+ [#933](https://github.com/cardene777/cdl/issues/933) は「描く欄に書いた語では発火しない (誤検知 0 件)」 と書いたが、
130
+ それは印を書かない箱で確かめた結果だった。
131
+
132
+ 条件が箱ごとに決まる形は種別ごとの述語では表せないため、どちらの書き方でも描くように
133
+ して述語を真にした。 見本 374 枚での発火は 43 件から 7 件に減った。
134
+
135
+ ## [0.99.0] - 2026-09-30
136
+
137
+ ### Fixed
138
+
139
+ - **図に書いた小見出しが画面に出ていなかった** (#935)
140
+
141
+ `dragon` の記法は図全体を 1 箱にする図種に対して図の小見出し (`eyebrow`) を書けるが、
142
+ 渡す先は図表を自前で描く 15 種別で、engine はその 15 種別に肩書を描いていなかった。
143
+ **書ける口だけが在って、出る先が無い** 状態だった。
144
+
145
+ 書ける側は `dragon` の `compile/subtitle.ts` の `図の小見出し` が担い、6 file
146
+ (`funnel` / `journey` / `gantt` / `value-chart` / `mind` / `tree` 等) が節へ渡している。
147
+
148
+ 題を箱の上に出すようにした (#929) ので、その上にもう 1 行置いた。
149
+
150
+ ```
151
+ 小見出し ← 足した行 (小さく、薄く、字間を空ける)
152
+ 図の名前 ← #929 で足した行
153
+ ┌──────────┐
154
+ │ 図表 │
155
+ └──────────┘
156
+ ```
157
+
158
+ 枠は伸びない。 余白は 60 で、題が使うのは 25 (字 15 + 間 10)、小見出しを足して 41。
159
+
160
+ 位置は **題の字の大きさから出す**。 素の大きさ (15) から出すと、長い題で題が縮んだ時に
161
+ 2 行の間が開く。
162
+
163
+ 題を書かず小見出しだけを書いた図では、小見出しを題の位置に置く。 題の有無に紐付けて
164
+ 消すと、題を書かない図で小見出しが出なくなる。
165
+
166
+ 見本 374 枚での発火は 51 件から 43 件に減った (肩書 13 件のうち 8 件が解消)。
167
+ 残る 5 件は課題の札 (`shape-kanban-card`) と連なりの塊 (`shape-blockchain-block`) で、
168
+ 絵の中の並びに置き場所を決める話になるため別に扱う。
169
+
170
+ 見つけた経路は #933 で足した軸で、手で探して見つけた前の 3 件とは違う。
171
+
172
+ ## [0.98.0] - 2026-09-30
173
+
174
+ ### Added
175
+
176
+ - **描かない欄に書いた語が黙って消えるのを知らせる軸を足した** (#933)
177
+
178
+ 節に書ける語の欄のうち、その種別が一度も描かない欄に書いても誰も知らせなかった。
179
+ `rows` には既に述語と検査と軸があり、残る 3 欄には 1 つも無かった。
180
+
181
+ | 欄 | 描くかの述語 | 描画と突き合わせる検査 | 知らせる軸 |
182
+ |---|---|---|---|
183
+ | `rows` | `rendersRows` | あり | `rows-not-rendered` |
184
+ | `title` | `rendersTitleText` | あり | 要らない (下記) |
185
+ | `eyebrow` | **新規** `rendersEyebrow` | **新規** | **新規** `node-field-unsupported` |
186
+ | `subtitle` | **新規** `rendersSubtitle` | **新規** | 同上 |
187
+ | `value` | **新規** `rendersValue` | **新規** | 同上 |
188
+
189
+ 98 種別すべてを 3 欄それぞれ書いた状態で描いて数えた内訳。
190
+
191
+ ```
192
+ eyebrow 描く 73 / 描かない 25
193
+ subtitle 描く 79 / 描かない 19
194
+ value 描く 22 / 描かない 76
195
+ ```
196
+
197
+ 実在の見本 374 枚に通したら **51 件** 出た。 `storage` の箱に書いた表の呼び名
198
+ (「利用者」「注文」「注文の明細」) や、図表の肩書に残った型の名前 (`tree` / `userJourney`)
199
+ がいずれも画面に出ていなかった。
200
+
201
+ `storage` の説明は `shape-` ではないため `shape-label-dropped` (軸 67) の判定
202
+ (`kind.startsWith("shape-")` が前提) にも掛からず、**どの経路も知らせない** 形だった。
203
+
204
+ 軸 67 との境界は **なぜ出ないか**。 あちらは箱が狭くて行が落ちた形で、箱を高くすれば出る。
205
+ こちらは種別が元からその欄を描かない形で、箱をどれだけ大きくしても出ない。
206
+ 軸 67 の説明自身が「種別が元から対応しない欄は別の検査範囲とする」 と書いている。
207
+
208
+ 題 (`title`) は対象に含めない。 呼び出し側が図全体の題を箱の題として渡すため、
209
+ 題が在ることは書き手がその箱について選んだ結果ではない。 知らせても直す先が無い。
210
+
211
+ 警告として出す。 図そのものは正しく描かれており、効かない語が書かれているだけなので、
212
+ 誤り扱いにすると既に書いている図が 1 枚も通らなくなる。
213
+
214
+ ### Changed
215
+
216
+ - **共通の箱の描き手に回る種別の一覧を 1 本にした** (#933)
217
+
218
+ 行 (`rows`) と値 (`value`) の採用側がどちらも同じ 21 種を含むため、`KINDS_DRAWN_BY_GENERIC`
219
+ として 1 箇所に持つ。 2 か所に書き写すと、種別を足した人が片方だけ直してずれる。
220
+
221
+ ただし **2 つの一覧は 1 種ずつ違う**。 `storage` は行を描いて値を描かず、`actor` は値を
222
+ 描いて行を描かない。 共通部分だけを畳み、採用側は別に持つ。
223
+
224
+ ## [0.97.0] - 2026-09-30
225
+
226
+ ### Fixed
227
+
228
+ - **じょうごと四象限の項目に書いた補足が画面に出ていなかった** (#931)
229
+
230
+ `funnel-stages` の段と `quadrant-matrix` の項目はどちらも補足 (`subtitle`) の欄を持ち、
231
+ 型の説明にも `optional subtitle` と書いてありながら、その補足を 1 文字も描かなかった。
232
+
233
+ 同じ形の補足を持つ他の 4 種別は描いている。
234
+
235
+ | 種別 | 補足の欄 | 直す前 |
236
+ |---|---|---|
237
+ | `tree-hierarchy` | `subtitle` | 描く |
238
+ | `mind-map` | `subtitle` / `rootSubtitle` | 描く |
239
+ | `journey-map` | `touchpoint` / `opportunity` | 描く |
240
+ | `gantt-timeline` | `owner` | 描く |
241
+ | `funnel-stages` | `subtitle` | 描かない |
242
+ | `quadrant-matrix` | `subtitle` | 描かない |
243
+
244
+ じょうごは段の中に名前の下へ置く。 収まる幅は **その段の下辺** で測る = 段は下へ
245
+ 向かって狭まるため、上辺で測ると下辺より広い補足が台形の外へ出る。
246
+ 2 行が段の高さに入らない時は名前と補足を同じ倍率で縮める。
247
+
248
+ 四象限は置き方が 2 通りあるので両方に足した。
249
+
250
+ | 置き方 | 足した形 |
251
+ |---|---|
252
+ | 象限に積む | 枠の中に 2 行目として置く。 枠の幅は名前と補足の広い方で決まる |
253
+ | 座標に置く | 名前の下に置く。 寄せ方と x を名前と揃えて 2 行を縦に並べる |
254
+
255
+ 補足に `{名前}` を書いた時に状態を解く側も同じ変更で足した。
256
+ 描く欄を増やして解決の側を増やさないと、図に波括弧がそのまま出る。
257
+
258
+ 書いた値が黙って消える形の 3 件目で、先の 2 件は #927 (形の絵の副題) と
259
+ #929 (図表の題) になる。
260
+
261
+ ### Changed
262
+
263
+ - **幅に収める倍率を出す口を 1 つ置いた** (#931)
264
+
265
+ じょうごと四象限がどちらも「与えた幅に収める倍率」 を要るため、
266
+ 1 文字ごとの実測表で測る `measureTextWidth` の隣に `収める倍率` を置いた。
267
+
268
+ 字間を受けないようにしてある。 `measureTextWidth` の戻りは字間を除けば字の大きさに
269
+ 比例する (最低幅も `字の大きさ × 1.2` なので同じく比例する) ので、比を 1 度取れば
270
+ 厳密に収まる。 字間は文字数ぶんの定数として足されるため比例が崩れ、縮めた後に
271
+ もう一度測らないと収まったか判らなくなる。
272
+
273
+ - **状態を解く層の冒頭の説明を直した** (#931)
274
+
275
+ `mind-map` と `tree-hierarchy` が「補足を描かない (実測で確認)」 と書いてあったが、
276
+ #471 で描くようになっている。 同じ file の中の関数の説明は正しく書いており、
277
+ 冒頭だけが古かった。
278
+
279
+ 描く欄を足す時は同じ変更で解決の側も足す、という規則として書き直した。
280
+
281
+ - **使っていない読み込みを 1 行消した** (#931)
282
+
283
+ `shape-blockchain.tsx` が #929 の変更で使わなくなった `textWidth` を読み込んだままで、
284
+ `pnpm lint` が既定 branch で落ちていた。
285
+
286
+ ## [0.96.0] - 2026-09-30
287
+
288
+ ### Fixed
289
+
290
+ - **グラフや工程表に書いた図の名前が画面に出ていなかった** (#929)
291
+
292
+ 図表を自前で描く 15 種別 (`chart-*` 9 種 / `gantt-timeline` / `mind-map` /
293
+ `funnel-stages` / `quadrant-matrix` / `tree-hierarchy` / `journey-map`) は、箱に書いた題を
294
+ 1 文字も描かなかった。
295
+
296
+ これらの種別は 1 つの箱が図を丸ごと描くため、組み立て器が図の主題を箱の題として渡す。
297
+ つまり **書いた題 = 図の名前** で、それが画面に出ていなかった。
298
+ 見本帳 486 枚で 27 件が消えており、図を書き出して単体で見ると何を表した図か分からない。
299
+
300
+ ```
301
+ chart-bar 「経路別の流入」
302
+ gantt-timeline 「公開までの段取り」
303
+ tree-hierarchy 「配布物の構成」
304
+ ```
305
+
306
+ 題を箱の上に描くようにした。 箱の中は図表の中身で埋まっており題の場所が無く、
307
+ 図表の題は元から図の上に置くものなので位置としても自然になる。
308
+ 枠の余白 (60) に収まるため、枠の大きさは変わらない。
309
+
310
+ 長い題は箱の幅に収まる倍率を掛ける。
311
+
312
+ ### Changed
313
+
314
+ - **種別の一覧を意味ごとに 1 本にした** (#929)
315
+
316
+ `KINDS_WITHOUT_TITLE_TEXT` は「図表を自前で描くから題を使わない」 種別と
317
+ 「題そのものが別の役割を持つ」 種別を 1 つに混ぜていた。
318
+ 前者が題を描くようになったので、意味ごとに分けた。
319
+
320
+ | 一覧 | 何を持つか |
321
+ |---|---|
322
+ | `KINDS_DRAWING_OWN_PAYLOAD` | 図表を自前で描く 15 種。 題は箱の上に描く |
323
+ | `KINDS_WITHOUT_TITLE_TEXT` | 題を描かない 3 種 (`sequence-board` / `mark-start` / `mark-end`) |
324
+
325
+ `KINDS_FITTING_OWN_TITLE` は前者を **書き写さず取り込む**。
326
+ 図表の種別を足した人が片方だけ直すと、幅の近似が当たらない軸が誤報する。
327
+
328
+ これにより文字を見る 3 軸 (読みやすさ / 全角の検出 / 折り返し) が 15 種別を素通りしなくなる。
329
+
330
+ ## [0.95.0] - 2026-09-30
331
+
332
+ ### Fixed
333
+
334
+ - **絵の中に文字を置く 3 種別が、書いた説明を捨てて見本の語を描いていた** (#927)
335
+
336
+ `shape-code-block` / `shape-terminal` / `shape-kanban-card` は、絵の中に文字の口を
337
+ 持ちながら、そこへ辞書の固定語を描いていた。 書いた `subtitle` はどこにも出ない。
338
+
339
+ | 種別 | 書いた値 (見本帳の実例) | 実際に描かれていた語 |
340
+ |---|---|---|
341
+ | `shape-code-block` | 「TypeScript」 「3行の抜粋」 「開発者が直す」 | 「共通.ts」 |
342
+ | `shape-terminal` | 「組み立てを実行」 「命令を打つ画面」 | 「→ 12 個を結合」 |
343
+ | `shape-kanban-card` | 「管理表に起票」 「作業中」 「形で見せる種別」 | 「形を実装」 |
344
+
345
+ 見本帳 486 枚で 8 件が消えていた (6 枚に分布)。
346
+ 結果として **同じ種別はどの図でも中身が 1 文字も変わらない**。 支援の窓口を描いた図の
347
+ 付箋も、作業の流れを描いた図の付箋も、どちらも同じ札の絵になっていた。
348
+
349
+ 書いた値を絵の中の口へ通し、固定語は書かない時の控えに下げた。
350
+ `shape-blockchain-block` が元から採っていた形に 3 種別を揃えている。
351
+
352
+ 字の大きさを決める計算にも書いた値を通した。 固定語のまま計算すると、長い値を渡した図で
353
+ 字が箱から出る。 札の幅は書いた値に合わせて広げ、本体の幅を上限に置いた。
354
+
355
+ `落としても描く種別` の `説明` に 3 種別を足した。 足さないと、描いている図を
356
+ 「説明が消えた」 と伝える軸 (#492) が誤報する。
357
+
358
+ ### Changed
359
+
360
+ - **`幅の倍率` を `shape-region.tsx` へ移した** (#927)
361
+
362
+ `shape-blockchain.tsx` の中にあった。 3 種別からも要るので共有の場所へ出した。
363
+ 中身は変えていない。
364
+
365
+ ## [0.94.0] - 2026-09-29
366
+
367
+ ### Fixed
368
+
369
+ - **形だけを描く種別で、書いた名前が画面に出ないまま捨てられていた** (#925)
370
+
371
+ 見本帳の 486 枚で、節に書いた名前が画面に出ないものを数えると 296 件あった。
372
+ うち 264 件が形だけを描く種別 (`dyn-rect` / `dyn-circle` / `dyn-arc` / `dyn-wave` /
373
+ `dyn-polygon`) に集まり、112 枚の図にまたがっていた。
374
+
375
+ これらの種別は形だけを描くと決めてあり (`KINDS_WITHOUT_TITLE_TEXT`)、書いた値は
376
+ 黙って捨てられていた。 書いた側には何も起きないので、消えていることに気付けない。
377
+
378
+ 困るのは **同じ種別の形が 2 つ以上並び、名前でしか見分けられない図** で、59 枚あった。
379
+ `parts-load-balancer` は無地の四角が 4 つ並ぶだけで、どれが入口でどれが出口かを読み取れない。
380
+ 得点表は 4 人の円が並ぶが、誰の円かが分からない。
381
+
382
+ `DynShapeNode` が 5 種別の入口を 1 つ持っているので、そこで名前と値を足した。
383
+ 種別ごとの描画には触れていない。
384
+
385
+ | 何を | どこへ | 揃え |
386
+ |---|---|---|
387
+ | `title` | 箱の上 | 箱いっぱいに描く種別 (`rect` / `wave`) は左、中心に描く種別 (`circle` / `arc` / `polygon`) は中央 |
388
+ | `subtitle` | 箱の下 | 常に中央 |
389
+
390
+ 揃えを 2 通りに分けるのは、形が箱をどう使うかが違うため。
391
+ `rect` は箱いっぱいに描くので左端が形の左端になるが、`circle` は箱の中心に描くので
392
+ 左端には何も無い = 左に揃えると名前だけが離れて浮く。
393
+
394
+ `dyn-rect` が既に持つ読み取り値 (`{値} / {上限}`) は箱の右上のままで、名前は左に並ぶ。
395
+
396
+ **どちらも書かれていない節では、包む `<g>` も足さない** = 書かない図の DOM は 1 要素も
397
+ 変わらない。
398
+
399
+ あわせて `KINDS_WITHOUT_TITLE_TEXT` から 5 種別を外した。
400
+ 外さないと、名前を描くようになったのに文字を見る検査 (`text-readability` /
401
+ `i18n-cjk-detection` / `bidi-hyphenation`) がこの 5 種別を素通りする。
402
+
403
+ 差し込み (`{名前}` の解決) はここで通していない。
404
+ `render/nodes.tsx` が解決済の節を渡してくるので、通しても結果が変わらない
405
+ (実測 = 通さない形に変えても検査が 1 件も落ちなかった)。
406
+ しかも向こうは値ごとの呼び名の表を持っており、ここには無い。
407
+
408
+ ## [0.93.0] - 2026-09-29
409
+
410
+ ### Fixed
411
+
412
+ - **描くものが無い図が、画面いっぱいの正方形を空けたまま出ていた** (#923)
413
+
414
+ 見本帳の 486 枚を 1 枚ずつ画面で測ったところ、17 枚は図の欄に見えるものが 1 つも無かった。
415
+ それでも欄は `874×874` の正方形として開いたままで、読む人は題を読んだあと何も無い面をたどることになる。
416
+
417
+ 17 枚はいずれも、常に隠れる節 1 つだけを持つ図だった。
418
+ 節が 1 つも無い図は書けないため置き石として `visibleIf: "0"` の `1×1` を置き、
419
+ 見せたいものは図の外の札 (`readout`) として出していた。
420
+ 枠は その置き石から決まり、四方の余白 60 が付いて `121×121` になり、
421
+ 正方形のまま幅いっぱいに引き伸ばされていた。
422
+
423
+ 2 つ直した。
424
+
425
+ **枠が常に隠れる節を見ないようにした**。 判定は `isRenderedNode` が既に持っているので、
426
+ 枠の側で書き直さずそれを引く。 節そのものと、`collectBBoxes` が出した矩形の両方を外す
427
+ (片方だけ外しても、もう片方が枠を作る)。 `{signal}` を含む条件は今までどおり枠に入れる =
428
+ 外すと段を進めるたびに枠が動く。
429
+
430
+ ```ts
431
+ const 常に隠れる節 = new Set(nodes.filter((n) => !isRenderedNode(n)).map((n) => n.id));
432
+ ```
433
+
434
+ **描くものが 1 つも無い時は `<svg>` を出さないようにした**。 この `<svg>` が出すのは
435
+ 帯と線と節の 3 つだけで、残りは `defs` の矢頭 (見えない) になる。 帯が絵を出すのは
436
+ `contain` / `lifeline` / `label` のいずれかを持つ時だけ。 3 つとも無い図は面だけを取る。
437
+
438
+ ```ts
439
+ function 描くものがある(laid: LaidDiagram): boolean {
440
+ if (laid.edges.length > 0) return true;
441
+ if (laid.nodes.some((n) => isRenderedNode(n))) return true;
442
+ return laid.lanes.some((l) => l.contain === true || l.lifeline === true || Boolean(l.label));
443
+ }
444
+ ```
445
+
446
+ `CdlStage` の返り値が `JSX.Element | null` になる。
447
+ 札 (`interactive-panel`) は `render.tsx` が別に出すので、題と札は残る。
448
+
449
+ 実測では、`parts` 群 112 枚のうち欄が出ない図が 0 枚から 17 枚になり、
450
+ 欄が出るのに見えるものが 0 件の図は 0 枚になった。
451
+ 他の 3 群 151 枚では欄が消えた図は 1 枚も無い。
452
+
453
+ [#919](https://github.com/cardene777/cdl/issues/919) で直した「見えない帯を枠に入れない」
454
+ と同じ原則を、節に当てたものになる。
455
+
456
+ ## [0.92.0] - 2026-09-29
457
+
458
+ ### Fixed
459
+
460
+ - **通販の絵記号の買い物かごが箱の中で左に寄っていた** (#921)
461
+
462
+ 絵は節の中心 `cx` を基準に組んであるが、左右へ出る量が違う。
463
+ ハンドルの握りは左へ 122 (丸の中心 118 + 半径 4) 出るのに、一番右まで来る影は 80 しか出ない。
464
+ `cx` をそのまま絵の中心に使うと、描いたものの中心が `(122 - 80) / 2 = 21` 単位ぶん左へずれる。
465
+
466
+ 実画面で測ると、節の箱は `x 90〜350` (中心 220) なのに描いたものは `x 129〜280` で
467
+ 中心が 205 だった。 ずれ 15 は倍率 `s ≒ 0.747` を掛けた `21 × 0.747` と一致する。
468
+
469
+ 絵を組む基準を、左右の広がりの差の半分だけ右へ寄せた。
470
+
471
+ ```ts
472
+ const 左へ出る = HANDLE_GRIP_X + HANDLE_GRIP_R;
473
+ const 右へ出る = CART_SHADOW_RX;
474
+ const cx = r.cx + ((左へ出る - 右へ出る) / 2) * s;
475
+ ```
476
+
477
+ 寄せる量は **絵が使っている値から導く**。 ハンドルや影の大きさを変えた時に、
478
+ 中心の計算だけが古くなるのを防ぐため、3 つの距離を定数にして絵の中と計算の両方が同じ値を読む。
479
+
480
+ 直した後の実測では、絵の中心が節の中心と一致し (ずれ 0)、枠から見た左右の余白も
481
+ 26% / 34% から 30% / 30% に揃った。
482
+
483
+ 枠の偏りを直した ([#919](https://github.com/cardene777/cdl/issues/919)) 後、
484
+ 見本帳の絵記号 117 枚で 1 ポイントを超える偏りが残っていたのはこの 1 枚だけだった。
485
+
486
+ ## [0.91.0] - 2026-09-29
487
+
488
+ ### Fixed
489
+
490
+ - **図の枠が右だけ広く、絵が左に寄っていた** (#919)
491
+
492
+ 見本帳 (`dragon` repo) の絵記号 117 枚を測ると、**117 枚すべてで右の余白が左より広かった**。
493
+ 反対向き (左が広い) は 1 枚も無い。 差の中央は枠の幅の 12 ポイントで、最大 27 ポイント。
494
+ 縦は差の中央が 0 ポイントで、横だけが偏っていた。
495
+
496
+ 枠は帯 (lane) と節 (node) の **遠い側の端しか見ていなかった**。
497
+
498
+ ```ts
499
+ for (const lane of lanes) {
500
+ maxX = Math.max(maxX, lane.x + lane.width); // 右端は渡す
501
+ maxY = Math.max(maxY, lane.y + lane.height); // 下端は渡す
502
+ } // 左端と上端は渡さない
503
+ ```
504
+
505
+ 左端を決めるのは `bboxes` の loop だけなので、帯が節より広い図では枠の右端だけが伸びる。
506
+ 雲の絵記号では帯が `x 0〜440`、節が `x 60〜380`、枠が `x 0〜500` で、
507
+ 節から見て左の余白 60 に対し右の余白が 120 になっていた。
508
+
509
+ しかも帯が描くのは見えない矩形だった。 `contain` を書いていない帯は当たりを取るための
510
+ `fill="none" stroke="none"` の矩形しか出さない。
511
+
512
+ 枠に入れる帯を **絵を持つ帯だけ** にして、入れる時は左右と上下の両方を渡す。
513
+ 節も同じく両端を渡す。
514
+
515
+ ```ts
516
+ function 箱いっぱいに描く(lane: LaidLane): boolean {
517
+ return lane.contain === true || lane.lifeline === true;
518
+ }
519
+ ```
520
+
521
+ 直した後の実測。
522
+
523
+ | 何を | 前 | 後 |
524
+ |---|---|---|
525
+ | 右の余白が左より広い図 | 117 枚 | 11 枚 |
526
+ | 左右の差 (中央) | 12.0 pt | 0.0 pt |
527
+ | 左右の差 (最大) | 27.3 pt | 8.3 pt |
528
+ | 絵が枠を占める割合 (中央) | 35% | 40% |
529
+ | 偏りが悪くなった図 | — | 0 枚 |
530
+
531
+ 節の上端を渡すようにしたことで、**それまで枠の外にあって切れていた絵が中に入る**。
532
+ 囲いを描く帯の図は囲いの上端が枠より 2% 上に出ており、配置の控え (`api-call`) は
533
+ 枠の上端 68 が節の上端 60 を 8 単位切っていた。 枠が広がるぶん絵が占める割合は下がるが、
534
+ 切れていたものが見えるほうを採った。
535
+
536
+ ## [0.90.0] - 2026-09-29
537
+
538
+ ### Added
539
+
540
+ - **書いてある省略の印に、書いたものだと分かる印を付けた** (#917)
541
+
542
+ 連鎖の箱はハッシュを省いた記法として `0x…` を文字のまま描いている。
543
+ engine が幅に入らず切った名前も末尾が `…` になるため、描いた結果を読む側からは
544
+ この 2 つが同じ形に見える。
545
+
546
+ ```tsx
547
+ <text data-cdl-ellipsis="written" data-cdl-counter-scaled="1" ...>
548
+ 0x…
549
+ </text>
550
+ ```
551
+
552
+ 読む側は末尾が `…` の文字のうち、この印を持たないものを engine が切ったものとして数える。
553
+
554
+ 印を付ける側を「書いてある方」 にしたのは、間違えた時の向きが安全な側に倒れるため。
555
+ 新しく書いた `…` に印を付け忘れると「切れた名前」 として報告され、調べれば分かる。
556
+ 逆に engine が切った側へ印を付ける形だと、印を付け忘れた切り方が永久に数えられない。
557
+ engine が切る経路は 5 つに分かれ、それを描く側は 30 か所を超える一方、
558
+ 書いてある省略の印は 1 か所しかない。
559
+
560
+ ## [0.89.0] - 2026-09-29
561
+
562
+ ### Fixed
563
+
564
+ - **四象限図が区画に入りきらない項目を黙って落としていた** (#915)
565
+
566
+ 1 つの区画に置ける段数を超えた項目を `slice` で捨てており、捨てたことも図に出なかった。
567
+
568
+ ```ts
569
+ const maxRows = Math.max(1, Math.floor(qHalfH / (rowH + gap)));
570
+ return items.slice(0, maxRows).map((it, idx) => {
571
+ ```
572
+
573
+ 書いた人からは「書いたのに図に無い」 としか見えない。 四象限図は区画ごとの厚みを
574
+ 読む図なので、厚みが実際より薄く出ることのほうが重い。
575
+
576
+ 入りきらない件を末尾 1 段に畳み、`ほか N 件` として出すようにした。 同じ engine の
577
+ 半円ゲージが「その他」 に畳むのと同じ形になる。
578
+
579
+ ```ts
580
+ const 畳む = items.length > maxRows;
581
+ const 名前を出す = 畳む ? items.slice(0, maxRows - 1) : items;
582
+ const 畳んだ件数 = items.length - 名前を出す.length;
583
+ ```
584
+
585
+ 名前を出すのは「置ける段数 - 1」 まで。 置ける段数が 1 の区画では名前を 1 件も出さず
586
+ 畳んだ段だけを出す = 名前 1 件と引き換えに残りが消えるより、件数が正しいほうを採る。
587
+
588
+ 畳んだ段は枠を持たせず、点線の下線と区画の色の字で描く。 名前の段と同じ見た目にすると
589
+ 「ほか 3 件」 という名前の項目が 1 つあるように読める。 引く時は名前の段が
590
+ `data-cdl-role="quadrant-item"`、畳んだ段が `data-cdl-role="quadrant-more"` で分かれる。
591
+
592
+ ## [0.88.0] - 2026-09-29
593
+
594
+ ### Changed
595
+
596
+ - **放射の図の中身をカードの中で釣り合わせた** (#913)
597
+
598
+ 見本帳の 486 枚を測ったところ、放射の図は文字がカードの 13% しか覆っていなかった。
599
+ 図表の中で最も低く、同じ見本帳の木の図 (28%) の半分以下になる。
600
+
601
+ 縦の帯の高さが、葉の数と決め打ちの箱の高さだけで決まっていた。
602
+
603
+ ```ts
604
+ const laneBandH = Math.min(canvasH * 0.9, sideLaneCount * (subBranchH + 14));
605
+ ```
606
+
607
+ 葉が 3 枚なら帯は 3 × 44 = 132 に固定され、カードの高さが 600 あっても中身は
608
+ 真ん中の 132 にしか広がらない。 カードを高くするほど上下の余りだけが増える。
609
+
610
+ 帯をカードから出すようにした。 一番高い箱のぶんを先に引く = 引かずにカードの 9 割を
611
+ 帯にすると、端の帯に置いた箱がカードから出て末尾の一様縮小が効き、横の枝まで縮む。
612
+
613
+ ```ts
614
+ const laneBandH = Math.max(0, canvasH - BRANCH_BOX_H_MAX);
615
+ const rowGap = sideLaneCount > 1 ? Math.min(laneBandH / (sideLaneCount - 1), ROW_GAP_MAX) : subBranchH + 14;
616
+ ```
617
+
618
+ 間隔に上限を置くのは、枝の少ない図で枝が細長く伸びるため。 箱の高さは間隔から出し、
619
+ 決め打ちの高さは上限としてだけ残す。
620
+
621
+ - **葉の少ない側を帯の中で中央へ置くようにした** (#913)
622
+
623
+ 0 番の帯から置いていたため、左の枝が 3 枚で右が 1 枚の図では右の 1 枚が帯の上端に付き、
624
+ 中心の箱と高さが揃わなかった。 置き始める帯の番号を、その側の葉の数だけずらす。
625
+
626
+ - **放射の図を横中央へ寄せるようにした** (#913)
627
+
628
+ 中心の箱はカードの真ん中に置いているが、左右で段数が違うと伸びた側に絵の重心が寄る。
629
+ 箱を置き終えた後に、塊ごと横へ動かす。
630
+
631
+ **寄せ幅は箱ではなく描く形から出す**。 末端は枠を持たず、名前を枠があった位置の
632
+ 内側の端から中心の反対側へ伸ばす。 箱の幅で測ると短い名前の末端が実際より外まで
633
+ 占めているように見え、寄せ幅がそのぶんずれる (実測 = 左の余り 21% / 右の余り 27%)。
634
+
635
+ ```ts
636
+ function 描く横の端(n) {
637
+ if (n.isRoot || !n.isLeaf) return [n.x - n.w / 2, n.x + n.w / 2];
638
+ const 起点 = n.x + (n.side === "right" ? -n.w / 2 : n.w / 2);
639
+ const 幅 = measureTextWidth(放射の行(n)[0].text, { fontSize: ..., fontWeight: 600 });
640
+ return n.side === "right" ? [起点, 起点 + 幅] : [起点 - 幅, 起点];
641
+ }
642
+ ```
643
+
644
+ 寄せ幅は整数に丸める。 端数を足すと、枝の長さが座標の差から出るぶん丸め誤差が乗る
645
+ (実測 = 24 であるべき枝が 23.999999999999943 になった)。
646
+
647
+ 見本帳の `mind-demo` で、左右の余りが 21% / 27% から 24% / 24% になった。
648
+ 上下の余りは 28% / 28% で揃っている。
649
+
650
+ ### Fixed
651
+
652
+ - **変更履歴の `[Unreleased]` の比較 link が 1 つ前の版を指していた** (#913)
653
+
654
+ 0.87.0 の節を足した時に比較 link を上げ忘れていた。 検査を変更履歴の編集より前に
655
+ 回したため、その回では通っていた。
656
+
657
+ ## [0.87.0] - 2026-09-29
658
+
659
+ ### Changed
660
+
661
+ - **数を描く 3 種で、中身をカードの中で釣り合わせた** (#911)
662
+
663
+ 見本帳の 15 枚を測ったところ、中身がカードの面積をどれだけ覆っているかが
664
+ 大きな数字 1% / 100 個の印 52% / 同心の弧 54% だった。
665
+
666
+ 大きな数字は、描かない弧と割合のぶんまで中身の高さに数えていた。
667
+
668
+ ```ts
669
+ const 中身の高さ = 名前の級 + 12 + 数値の級 + 前の高さ + 16 + 弧の半径 * 2 + 8 + 割合の級;
670
+ ```
671
+
672
+ 件が 1 つの図は弧も割合も描かないのに、その 76 を高さに入れたまま上下の中央を出すため、
673
+ 中身が上へずれる。 640 × 320 のカードに字の大きさ 40 の数字が 1 つ置かれるだけになっていた。
674
+
675
+ 描かない部品を高さから外し、空いた縦を数値の字に回す。 字は 40 を下限、112 を上限として
676
+ カードの高さから決める。 上限を置かないと、大きなカードで字だけが伸びる。
677
+
678
+ ```ts
679
+ const 弧と割合の高さ = 割合を出す ? 16 + 弧の半径 * 2 + 8 + 割合の級 : 0;
680
+ const 数値の級 = 割合を出す
681
+ ? 数値の級の下限
682
+ : Math.max(数値の級の下限, Math.min(数値の級の上限, Math.floor(h - 余白 * 2 - 名前の級 - 12 - 前の高さ)));
683
+ ```
684
+
685
+ 100 個の印と同心の弧は、一覧と絵をカードの左端から順に置いていた。
686
+ 絵の大きさは高さで決まるので、幅が余っても広がらず、右が 4 割近く空く。
687
+
688
+ 一覧と絵をまとめた塊の幅を先に出し、その塊をカードの横中央へ置く。
689
+ 塊の幅は今までどおり中身から決めるので、絵の大きさは変わらない。
690
+
691
+ ```ts
692
+ const 中身の幅 = 一覧の幅 + 一覧と格子の間 + 升 * WAFFLE_COLS;
693
+ const 一覧の左 = Math.max(PAD, (node.w - 中身の幅) / 2);
694
+ ```
695
+
696
+ 一覧と絵を別々に中央へ寄せると 2 つが重なるため、寄せるのは塊の単位で行う。
697
+
698
+ - **一覧の値と割合を色で分けた** (#911)
699
+
700
+ `78 78%` と `72 45.9%` のように空白 2 つで繋いでいたため、2 つの数が 1 つに見えていた。
701
+
702
+ 合計が 100 の図は値と割合が同じ数になるので、割合だけを出す。
703
+ そうでない図は値を濃く、割合を薄くして色で分ける。
704
+
705
+ 中黒のような区切りを字で足す形は採らない。 1 件の幅が増え、幅から置ける件数を決めている
706
+ 半円ゲージでは実測で件数 20 が 12 まで畳まれた。 `textWidth` が ASCII 以外の 1 文字を
707
+ 1.04em と数えるためで、これは字の種類を判定しないという engine の既定の判断による。
708
+ 色で分ければ空白 1 つで並べられるので、繋ぐ前の空白 2 つより狭くなる。
709
+
710
+ ```tsx
711
+ <tspan data-cdl-role="chart-legend-value" fill="var(--cdl-text, #1a1f2a)">{`${値} `}</tspan>
712
+ <tspan data-cdl-role="chart-legend-share">{割合}</tspan>
713
+ ```
714
+
715
+ 幅の見積りは `値と割合の文字` が 1 か所で持ち、100 個の印 / 同心の弧 / 半円ゲージの
716
+ 3 種から呼ぶ。 描く側と測る側で別の字を組むと、収まるはずの行が溢れる。
717
+
718
+ ## [0.86.0] - 2026-09-29
719
+
720
+ ### Changed
721
+
722
+ - **木の箱の幅を名前の長さから決めるようにした** (#909 / #910)
723
+
724
+ それまで全ての箱が同じ幅だった。
725
+
726
+ ```ts
727
+ const nodeW = Math.min(140, slotW * 0.85);
728
+ ```
729
+
730
+ 名前の長さを見ていないため、長い名前は縮められるか切られ、短い名前は間延びする。
731
+ 木は「何がどこに属するか」 を読む図なので、名前が読めないと図の役目が立たない。
732
+
733
+ 幅を名前から出すようにした。
734
+
735
+ **下限は今までの幅**。
736
+ 短い名前の箱を狭めると、既存の図の見た目が名前の長さで変わる。
737
+ 広がる向きだけを足した。
738
+
739
+ **頭打ちは区画の 92%**。
740
+ これを超えると隣の箱とぶつかる。
741
+ 超える名前は今までどおり縮めて収める。
742
+
743
+ 枝の太さを段で決めるようにした。
744
+
745
+ ```ts
746
+ export const 木の枝の太さ = (段: number): number => Math.max(1.1, 2.6 - 段 * 0.45);
747
+ ```
748
+
749
+ 木は根から葉へ辿る図なので、太さが一様だと流れが絵に出ない。
750
+ 下限を置く理由は放射 (#907) と同じで、段数に上限が無いため引き算だけだと深い図で線が消える。
751
+
752
+
753
+ ## [0.85.0] - 2026-09-29
754
+
755
+ ### Changed
756
+
757
+ - **放射の図の末端を枠なしで外へ伸ばすようにした** (#907 / #908)
758
+
759
+ それまでどの段の項目にも同じ形の枠を描いていた。
760
+ 枠があるために名前が枠の幅まで縮められるか切られる。
761
+ 枠の幅は段の深さで決まり (`effSubW`)、深い図では下限まで縮む。
762
+
763
+ 末端 (子を持たない項目) は枠を描かず、名前を **中心から外へ** 伸ばす。
764
+ 起点は枠があった位置の内側の端で、使える幅はそこから描画域の端まで。
765
+
766
+ 外向きなら隣の段とぶつからない。
767
+ 隣の段は中心側に在り、外側には描画域の端しか無いため。
768
+
769
+ 中心と、子を持つ項目には枠が残る。
770
+ 中心は図の起点、途中の段は子を束ねる位置なので、枠が無いと何から広がるのかが読めない。
771
+
772
+ 枝の太さを段で決めるようにした。
773
+
774
+ ```ts
775
+ export const 枝の太さ = (段: number): number => Math.max(1.2, 3.2 - 段 * 0.7);
776
+ ```
777
+
778
+ 放射の図は中心から外へ広がることを描く図なので、太さが一様だと構造が絵に出ない。
779
+ **下限を置く** = 段数に上限が無いため、引き算だけだと深い図で 0 を割って線が消える。
780
+ 消えた線は「繋がっていない」 と読まれる。
781
+
782
+
783
+ ## [0.84.0] - 2026-09-29
784
+
785
+ ### Fixed
786
+
787
+ - **版の比較 link が 1 つ抜けて検査が落ちていたのを直した** (#904 / #905)
788
+
789
+ 0.83.0 を出した PR (#902) が見出しを足したが、file の末尾にある比較 link の一覧に行を
790
+ 足さなかった。 `[Unreleased]` の起点も 0.82.0 のまま残っていた。
791
+
792
+ 併せて **0.83.0 の tag が無かったので打った**。
793
+ tag が無いと「版に入る commit が変更履歴から辿れる」 検査の範囲が 2 つの版にまたがり、
794
+ 前の版の commit が今の版の節から辿れないと判定される。
795
+ 同じ抜けは 0.64.1 でも起きている。
796
+
797
+ ### Added
798
+
799
+ - **四象限図の項目を値の位置に置けるようにした** (#903 / #906)
800
+
801
+ それまで項目は象限の左上から縦に積まれていた。
802
+
803
+ ```
804
+ qyStart = (isTop ? PAD_TOP : cy) + 44
805
+ py = qyStart + idx * (rowH + gap)
806
+ ```
807
+
808
+ この形だと同じ象限に居る 2 つの項目の違いが図に出ない。
809
+ 「右上のいちばん右上」 と「右上のぎりぎり」 は読み手にとって別の意味を持つのに、
810
+ どちらも同じ列に同じ間隔で並ぶ。
811
+ 四象限図は 2 つの軸で位置を決める図なので、位置が出ないと図の役目が立たない。
812
+
813
+ 項目に `at` を書けるようにした。
814
+
815
+ ```ts
816
+ { id: "a", title: "重複を消す", at: { x: 0.8, y: 0.7 } }
817
+ ```
818
+
819
+ 描画域の左下を (0, 0)、右上を (1, 1) とする。
820
+ **`y` は上向き**で、SVG の座標とは逆になる。
821
+ 図に出る軸の名前 (`↑ 大きい`) と同じ向きにしないと、書き手が値を反転して書くことになる。
822
+
823
+ `at` を書いた項目は点と名前で描き、書かなかった項目は今までどおり象限に積む。
824
+ `x` と `y` は `{signal}` を受けるので、段ごとに項目が動く。
825
+
826
+ **象限は座標から決まり、`quadrant` は読まない**。
827
+ 両方を読むと同じことが 2 か所に書かれ、食い違った時にどちらが正しいか決められない。
828
+ そのため `quadrant` を省略できるようにした。
829
+
830
+ 名前は点の右に置くが、`x` が 0.5 以上の項目は左に置く。
831
+ 右に置くと描画域の外へ出る。
832
+
833
+ 0 から 1 の外の値は描画域の中に丸める。
834
+ **丸めた項目に印は付けない** = 丸めは「読めなかった」 ではなく、値は在る。
835
+ 数として読めない値だけが `data-cdl-unresolved` を持つ。
836
+
837
+
8
838
  ## [0.83.0] - 2026-09-27
9
839
 
10
840
  ### Fixed
@@ -3349,7 +4179,27 @@ Initial OSS release.
3349
4179
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
3350
4180
  行き止まりになる。
3351
4181
 
3352
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.82.0...HEAD
4182
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.102.0...HEAD
4183
+ [0.102.0]: https://github.com/cardene777/cdl/compare/v0.101.0...v0.102.0
4184
+ [0.101.0]: https://github.com/cardene777/cdl/compare/v0.100.0...v0.101.0
4185
+ [0.100.0]: https://github.com/cardene777/cdl/compare/v0.99.0...v0.100.0
4186
+ [0.99.0]: https://github.com/cardene777/cdl/compare/v0.98.0...v0.99.0
4187
+ [0.98.0]: https://github.com/cardene777/cdl/compare/v0.97.0...v0.98.0
4188
+ [0.97.0]: https://github.com/cardene777/cdl/compare/v0.96.0...v0.97.0
4189
+ [0.96.0]: https://github.com/cardene777/cdl/compare/v0.95.0...v0.96.0
4190
+ [0.95.0]: https://github.com/cardene777/cdl/compare/v0.94.0...v0.95.0
4191
+ [0.94.0]: https://github.com/cardene777/cdl/compare/v0.93.0...v0.94.0
4192
+ [0.93.0]: https://github.com/cardene777/cdl/compare/v0.92.0...v0.93.0
4193
+ [0.92.0]: https://github.com/cardene777/cdl/compare/v0.91.0...v0.92.0
4194
+ [0.91.0]: https://github.com/cardene777/cdl/compare/v0.90.0...v0.91.0
4195
+ [0.90.0]: https://github.com/cardene777/cdl/compare/v0.89.0...v0.90.0
4196
+ [0.89.0]: https://github.com/cardene777/cdl/compare/v0.88.0...v0.89.0
4197
+ [0.88.0]: https://github.com/cardene777/cdl/compare/v0.87.0...v0.88.0
4198
+ [0.87.0]: https://github.com/cardene777/cdl/compare/v0.86.0...v0.87.0
4199
+ [0.86.0]: https://github.com/cardene777/cdl/compare/v0.85.0...v0.86.0
4200
+ [0.85.0]: https://github.com/cardene777/cdl/compare/v0.84.0...v0.85.0
4201
+ [0.84.0]: https://github.com/cardene777/cdl/compare/v0.83.0...v0.84.0
4202
+ [0.83.0]: https://github.com/cardene777/cdl/compare/v0.82.0...v0.83.0
3353
4203
  [0.82.0]: https://github.com/cardene777/cdl/compare/v0.81.0...v0.82.0
3354
4204
  [0.81.0]: https://github.com/cardene777/cdl/compare/v0.80.0...v0.81.0
3355
4205
  [0.80.0]: https://github.com/cardene777/cdl/compare/v0.79.0...v0.80.0