@cardenelabs/cdl 0.40.7 → 0.40.8
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 +57 -1
- package/dist/index.cjs +24 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +24 -19
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +24 -19
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +24 -19
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/kinds/axis-ticks.ts +32 -0
- package/src/kinds/chart-bar.tsx +14 -19
- package/src/kinds/chart-line.tsx +24 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/cdl",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.8",
|
|
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",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 目盛りの刻みを、人が読む数から選ぶ (cdl#751)。
|
|
3
|
+
*
|
|
4
|
+
* `1 / 2 / 2.5 / 5` に 10 の累乗を掛けた中から、目盛りが目安の本数前後になるものを取る。
|
|
5
|
+
* 範囲をそのまま本数で割ると `680 / 4 = 170` のような数が目盛りに出て、
|
|
6
|
+
* 機械が割った数字に見える。
|
|
7
|
+
*
|
|
8
|
+
* **棒と折れ線が同じ規則を持つのでここに 1 つだけ置く**。 図ごとに書くと、片方だけ直した
|
|
9
|
+
* 時に目盛りの出方がずれる (実際に棒を直した cdl#747 で 2 箇所になった)。
|
|
10
|
+
* 図どうしに上下関係を作らないため、どちらの図でもない場所に置く。
|
|
11
|
+
*
|
|
12
|
+
* **天井と床の決め方はここに持たない**。 折れ線は床も動かし、棒は床が必ず 0 で、
|
|
13
|
+
* 規則が違う。 共有するのは刻みの選び方だけ。
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 刻みを 1 つ選ぶ。
|
|
18
|
+
*
|
|
19
|
+
* @param 範囲 縦軸が受け持つ幅。 折れ線は `最大 - 最小`、棒は最小が 0 なので `最大`
|
|
20
|
+
* @param 目安の本数 目盛りを何本くらい引きたいか
|
|
21
|
+
* @returns 刻み。 **範囲か本数が 0 以下なら 0 を返す** = 刻みを決められないことを
|
|
22
|
+
* 0 で表し、呼ぶ側がその図に合った逃げ方を選ぶ (`rules/quality.md` の
|
|
23
|
+
* 「判定できなかったことを値に潰さない」 に合わせ、勝手に 1 を返さない)
|
|
24
|
+
*/
|
|
25
|
+
export function 目盛りの刻み(範囲: number, 目安の本数: number): number {
|
|
26
|
+
if (!(範囲 > 0) || !(目安の本数 > 0)) return 0;
|
|
27
|
+
const 粗い = 範囲 / 目安の本数;
|
|
28
|
+
const 桁 = 10 ** Math.floor(Math.log10(粗い));
|
|
29
|
+
const 正規 = 粗い / 桁;
|
|
30
|
+
const 候補 = 正規 <= 1 ? 1 : 正規 <= 2 ? 2 : 正規 <= 2.5 ? 2.5 : 正規 <= 5 ? 5 : 10;
|
|
31
|
+
return 候補 * 桁;
|
|
32
|
+
}
|
package/src/kinds/chart-bar.tsx
CHANGED
|
@@ -2,23 +2,7 @@ import type { JSX } from "react";
|
|
|
2
2
|
import type { LaidNode } from "../types";
|
|
3
3
|
import { resolveChartData } from "../render/payload-binding";
|
|
4
4
|
import { 進みを畳む } from "./draw-progress";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 目盛りの刻みを、人が読む数から選ぶ (cdl#747)。
|
|
8
|
-
*
|
|
9
|
-
* `1 / 2 / 2.5 / 5` に 10 の累乗を掛けた中から、目盛りが目安の本数前後になるものを取る。
|
|
10
|
-
* 最大値をそのまま割ると `680 / 4 = 170` のような数が目盛りに出て、機械が割った数字に見える。
|
|
11
|
-
*
|
|
12
|
-
* 最大が 0 以下の図では刻みを決められないので 0 を返す (呼ぶ側が今までの割り方に落ちる)。
|
|
13
|
-
*/
|
|
14
|
-
export function 目盛りの刻み(最大: number, 目安の本数: number): number {
|
|
15
|
-
if (!(最大 > 0) || !(目安の本数 > 0)) return 0;
|
|
16
|
-
const 粗い = 最大 / 目安の本数;
|
|
17
|
-
const 桁 = 10 ** Math.floor(Math.log10(粗い));
|
|
18
|
-
const 正規 = 粗い / 桁;
|
|
19
|
-
const 候補 = 正規 <= 1 ? 1 : 正規 <= 2 ? 2 : 正規 <= 2.5 ? 2.5 : 正規 <= 5 ? 5 : 10;
|
|
20
|
-
return 候補 * 桁;
|
|
21
|
-
}
|
|
5
|
+
import { 目盛りの刻み } from "./axis-ticks";
|
|
22
6
|
|
|
23
7
|
/**
|
|
24
8
|
* その数を書き切るのに要る小数の桁数。
|
|
@@ -32,6 +16,16 @@ function 小数の桁(n: number): number {
|
|
|
32
16
|
return Math.min(20, Math.max(0, 小数部 - Number(指数)));
|
|
33
17
|
}
|
|
34
18
|
|
|
19
|
+
/**
|
|
20
|
+
* 字の大きさ (cdl#753)。
|
|
21
|
+
*
|
|
22
|
+
* **値札を軸の名前より大きくする** = 値札は棒の上に載る数そのもので、
|
|
23
|
+
* 軸の名前は目盛りの側にある。 折れ線 (`chart-line.tsx`) と同じ組にしてある。
|
|
24
|
+
* 2 図で揃っていることは検査が実物から読んで確かめる (`chart-label-rank.test.tsx`)。
|
|
25
|
+
*/
|
|
26
|
+
const 値札の級 = 12;
|
|
27
|
+
const 軸の名前の級 = 11;
|
|
28
|
+
|
|
35
29
|
/** 刻みの倍数を足し込んだ時に出る誤差 (`0.1 * 3 = 0.30000000000000004`) を落とす */
|
|
36
30
|
const 桁で丸める = (v: number, 桁: number): number => Number(v.toFixed(桁));
|
|
37
31
|
|
|
@@ -80,6 +74,7 @@ export function ChartBarNode({
|
|
|
80
74
|
* 最大値をそのまま使うと 0 が 5 つ並ぶ縦軸になり、何も読めない。
|
|
81
75
|
*/
|
|
82
76
|
const 天井のもと = vMax > 0 ? vMax : 1;
|
|
77
|
+
// 棒は床が必ず 0 なので、範囲 = 天井のもと
|
|
83
78
|
const 刻み = 目盛りの刻み(天井のもと, 目盛りの目安);
|
|
84
79
|
const 刻みの桁 = 小数の桁(刻み);
|
|
85
80
|
/**
|
|
@@ -213,7 +208,7 @@ export function ChartBarNode({
|
|
|
213
208
|
data-cdl-role="chart-bar-value"
|
|
214
209
|
x={bx + barW / 2}
|
|
215
210
|
y={見えている頭 - 8}
|
|
216
|
-
fontSize={
|
|
211
|
+
fontSize={値札の級}
|
|
217
212
|
fontWeight={600}
|
|
218
213
|
textAnchor="middle"
|
|
219
214
|
fill="var(--cdl-text, #1a1f2a)"
|
|
@@ -224,7 +219,7 @@ export function ChartBarNode({
|
|
|
224
219
|
data-cdl-role="chart-bar-label"
|
|
225
220
|
x={bx + barW / 2}
|
|
226
221
|
y={PAD_TOP + canvasH + 18}
|
|
227
|
-
fontSize={
|
|
222
|
+
fontSize={軸の名前の級}
|
|
228
223
|
textAnchor="middle"
|
|
229
224
|
fill="var(--cdl-text-dim, #5a6270)"
|
|
230
225
|
>
|
package/src/kinds/chart-line.tsx
CHANGED
|
@@ -2,9 +2,24 @@ import type { JSX } from "react";
|
|
|
2
2
|
import type { LaidNode } from "../types";
|
|
3
3
|
import { resolveChartData } from "../render/payload-binding";
|
|
4
4
|
import { 進みを畳む, 伸ばすdash } from "./draw-progress";
|
|
5
|
+
import { 目盛りの刻み } from "./axis-ticks";
|
|
5
6
|
|
|
6
7
|
export type ChartLineScale = { min: number; max: number; ticks: number[] };
|
|
7
8
|
|
|
9
|
+
/** 縦軸に引きたい目盛りの本数の目安 */
|
|
10
|
+
const 目盛りの目安 = 4;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 字の大きさ (cdl#753)。
|
|
14
|
+
*
|
|
15
|
+
* **値札を軸の名前より大きくする** = 値札は印の上に載る数そのもので、
|
|
16
|
+
* 軸の名前は目盛りの側にある。 棒グラフ (`chart-bar.tsx`) と同じ組にしてある。
|
|
17
|
+
* 凡例を持つ図 (半円ゲージ / 同心の弧 / 100 個の印 / 内訳の帯) は
|
|
18
|
+
* 名前が行を見分ける鍵になるので逆の順で、そちらは揃えない。
|
|
19
|
+
*/
|
|
20
|
+
const 値札の級 = 12;
|
|
21
|
+
const 軸の名前の級 = 11;
|
|
22
|
+
|
|
8
23
|
const 数を書く = (value: number): string =>
|
|
9
24
|
value.toLocaleString("en-US", { maximumFractionDigits: 12 });
|
|
10
25
|
|
|
@@ -17,14 +32,13 @@ export function 折れ線の目盛(values: readonly number[]): ChartLineScale {
|
|
|
17
32
|
rawMax += room;
|
|
18
33
|
}
|
|
19
34
|
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const fraction = roughStep / power;
|
|
23
|
-
const niceFraction =
|
|
24
|
-
fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10;
|
|
25
|
-
const step = niceFraction * power;
|
|
35
|
+
// 折れ線は床も動かすので、範囲 = 最大 - 最小。 直前の広げ方で必ず正になる
|
|
36
|
+
const step = 目盛りの刻み(rawMax - rawMin, 目盛りの目安);
|
|
26
37
|
const min = Math.floor(rawMin / step) * step;
|
|
27
38
|
const max = Math.ceil(rawMax / step) * step;
|
|
39
|
+
// 刻みが決まらない入力 (値が数でない) では `tickCount` が数にならず、
|
|
40
|
+
// 目盛りは空になる。 **この空を守りの分岐で作らない** = 同じものを 2 通りで作ると、
|
|
41
|
+
// 片方を外しても検査が落ちず、要るのか要らないのか判らなくなる (cdl#751 の変異試験で実測)
|
|
28
42
|
const tickCount = Math.round((max - min) / step);
|
|
29
43
|
const ticks = Array.from({ length: tickCount + 1 }, (_, i) => {
|
|
30
44
|
const value = min + step * i;
|
|
@@ -165,6 +179,7 @@ export function ChartLineNode({
|
|
|
165
179
|
opacity={0.65}
|
|
166
180
|
/>
|
|
167
181
|
<text
|
|
182
|
+
data-cdl-role="chart-line-tick"
|
|
168
183
|
x={PAD_LEFT - 8}
|
|
169
184
|
y={t.y + 4}
|
|
170
185
|
fontSize={11}
|
|
@@ -254,7 +269,7 @@ export function ChartLineNode({
|
|
|
254
269
|
data-cdl-role="chart-line-value"
|
|
255
270
|
x={cx}
|
|
256
271
|
y={labelY}
|
|
257
|
-
fontSize={
|
|
272
|
+
fontSize={値札の級}
|
|
258
273
|
fontWeight={600}
|
|
259
274
|
textAnchor="middle"
|
|
260
275
|
fill="var(--cdl-text, #1a1f2a)"
|
|
@@ -309,9 +324,10 @@ export function ChartLineNode({
|
|
|
309
324
|
<g key={`pt-${idx}`} data-cdl-unresolved={d.unresolved ? "true" : undefined}>
|
|
310
325
|
{点と値}
|
|
311
326
|
<text
|
|
327
|
+
data-cdl-role="chart-line-label"
|
|
312
328
|
x={cx}
|
|
313
329
|
y={PAD_TOP + canvasH + 20}
|
|
314
|
-
fontSize={
|
|
330
|
+
fontSize={軸の名前の級}
|
|
315
331
|
textAnchor="middle"
|
|
316
332
|
fill="var(--cdl-text-dim, #5a6270)"
|
|
317
333
|
>
|