@cardenelabs/cdl 0.40.2 → 0.40.4
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 +42 -1
- package/dist/index.cjs +33 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +33 -10
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +33 -10
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +33 -10
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/src/anim/core/timeline.ts +13 -3
- package/src/anim/core/types.ts +1 -1
- package/src/kinds/chart-gauge.tsx +56 -11
- package/src/render.tsx +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/cdl",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.4",
|
|
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",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { clamp01,
|
|
1
|
+
import { clamp01, easeOut } from "./easing";
|
|
2
2
|
import type {
|
|
3
3
|
EasingFn,
|
|
4
4
|
PhaseDescriptor,
|
|
@@ -30,7 +30,7 @@ import type {
|
|
|
30
30
|
export type TimelineOptions = {
|
|
31
31
|
/** 自動進行時の Phase 間 wait (ms)、 デフォルト Phase の durationMs に従う */
|
|
32
32
|
autoAdvanceMs?: number;
|
|
33
|
-
/** Phase 内補間の easing、 デフォルト
|
|
33
|
+
/** Phase 内補間の easing、 デフォルト easeOut */
|
|
34
34
|
easing?: EasingFn;
|
|
35
35
|
/** loop 再生するか (settled 後に最初に戻る)、 デフォルト false */
|
|
36
36
|
loop?: boolean;
|
|
@@ -86,7 +86,17 @@ export class Timeline {
|
|
|
86
86
|
throw new Error("Timeline requires at least one phase");
|
|
87
87
|
}
|
|
88
88
|
this.phases = phases;
|
|
89
|
-
|
|
89
|
+
/**
|
|
90
|
+
* 既定の曲線 (cdl#736)。
|
|
91
|
+
*
|
|
92
|
+
* **`easeOutQuint` は動きが前半に寄りすぎる**。 実測で、段の長さ 1.2 秒の tween は
|
|
93
|
+
* 9 割が最初の 0.449 秒で終わり、残りの 0.75 秒はほとんど止まって見えた
|
|
94
|
+
* (半分に達するのが段の 13.1% の時点)。 段を長くしても形は変わらず、止まって
|
|
95
|
+
* 見える時間だけが伸びる。
|
|
96
|
+
*
|
|
97
|
+
* `easeOut` は半分に達するのが 34.2% の時点で、段の終わりまで動き続ける。
|
|
98
|
+
*/
|
|
99
|
+
this.easing = options.easing ?? easeOut;
|
|
90
100
|
this.loop = options.loop ?? false;
|
|
91
101
|
this.autoAdvanceMsOverride = options.autoAdvanceMs;
|
|
92
102
|
this.phaseHoldMs = options.phaseHoldMs ?? 0;
|
package/src/anim/core/types.ts
CHANGED
|
@@ -40,7 +40,7 @@ export type TimelineState = {
|
|
|
40
40
|
/**
|
|
41
41
|
* 曲線を通す前の進行度 (0..1、 cdl#711)。 経過時間そのものの割合。
|
|
42
42
|
*
|
|
43
|
-
* `phaseProgress` は既定で `
|
|
43
|
+
* `phaseProgress` は既定で `easeOut` を通るため素の進みより先に出る。
|
|
44
44
|
* **値が落ち着く動きには合うが、 線を引く動きには合わない** =
|
|
45
45
|
* `1.2s` の段で半分に達するのが 158 ms になり、 折れ線の 5 点のうち 4 点が
|
|
46
46
|
* 292 ms の間に出てしまう (実測)。
|
|
@@ -65,10 +65,43 @@ export function ChartGaugeNode({
|
|
|
65
65
|
|
|
66
66
|
const 名前の級 = 14;
|
|
67
67
|
const 数値の級 = 13;
|
|
68
|
-
/** 内訳の 1
|
|
69
|
-
const
|
|
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 内訳の幅 = 使える幅 /
|
|
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
|
|
211
|
-
const
|
|
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
|
|
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={
|
|
261
|
+
y={y + 26}
|
|
218
262
|
fontSize={名前の級}
|
|
219
263
|
fontWeight={700}
|
|
220
264
|
fill="var(--cdl-text, #1a1f2a)"
|
|
221
265
|
>
|
|
222
|
-
{切り詰める(d.label ?? "",
|
|
266
|
+
{切り詰める(d.label ?? "", 収まる幅, 名前の級)}
|
|
223
267
|
</text>
|
|
224
|
-
|
|
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
|
);
|
package/src/render.tsx
CHANGED
|
@@ -136,8 +136,10 @@ export function CdlDiagramView({ diagram, laid: laidProp, hideHeader = false, hi
|
|
|
136
136
|
/**
|
|
137
137
|
* 描く動きが読む進み (cdl#711)。 曲線を通さない = 経過時間そのものの割合。
|
|
138
138
|
*
|
|
139
|
-
*
|
|
140
|
-
* 292 ms
|
|
139
|
+
* 線を引く動きに段の曲線を当てると前半に寄る。 当時の既定 (`easeOutQuint`) では
|
|
140
|
+
* 折れ線の 5 点のうち 4 点が 292 ms の間に出た。 曲線をゆるめた後 (`cdl#736` の
|
|
141
|
+
* `easeOut`) も寄る向きは同じなので、 描く動きは曲線を通さないままにする。
|
|
142
|
+
* ペンの速さは一定であるほど「1 つずつ現れる」 が読める。
|
|
141
143
|
*/
|
|
142
144
|
const drawProgress = reduced ? 1 : state.phaseLinearProgress;
|
|
143
145
|
|