@cardenelabs/dragon 0.15.0 → 0.16.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.
- package/README.md +1 -0
- package/dist/index.cjs +133 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -1
- package/dist/index.d.ts +49 -1
- package/dist/index.js +133 -9
- package/dist/index.js.map +1 -1
- package/package.json +13 -12
- package/src/compile.ts +114 -11
- package/src/json-parser.ts +23 -1
- package/src/schemas/diagram.json +17 -2
- package/src/types.ts +29 -0
- package/src/v05/parser.ts +41 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/dragon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Dragon — Mermaid 感覚で animated SVG を生成する Text DSL。 cdl engine を内部利用。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "cardene777",
|
|
@@ -46,8 +46,18 @@
|
|
|
46
46
|
"node": ">=18"
|
|
47
47
|
},
|
|
48
48
|
"sideEffects": false,
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsup",
|
|
51
|
+
"dev": "tsup --watch",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"typecheck:test": "tsc --noEmit -p tsconfig.test.json",
|
|
54
|
+
"test": "cd ../.. && vitest run packages/dragon",
|
|
55
|
+
"test:watch": "cd ../.. && vitest packages/dragon",
|
|
56
|
+
"lint": "tsc --noEmit",
|
|
57
|
+
"prepublishOnly": "pnpm run typecheck && pnpm run test && pnpm run build"
|
|
58
|
+
},
|
|
49
59
|
"dependencies": {
|
|
50
|
-
"@cardenelabs/cdl": "^0.
|
|
60
|
+
"@cardenelabs/cdl": "^0.15.0"
|
|
51
61
|
},
|
|
52
62
|
"peerDependencies": {
|
|
53
63
|
"react": "^19.0.0",
|
|
@@ -66,14 +76,5 @@
|
|
|
66
76
|
"react": "^19.1.0",
|
|
67
77
|
"tsup": "^8.5.1",
|
|
68
78
|
"typescript": "^5.8.0"
|
|
69
|
-
},
|
|
70
|
-
"scripts": {
|
|
71
|
-
"build": "tsup",
|
|
72
|
-
"dev": "tsup --watch",
|
|
73
|
-
"typecheck": "tsc --noEmit",
|
|
74
|
-
"typecheck:test": "tsc --noEmit -p tsconfig.test.json",
|
|
75
|
-
"test": "cd ../.. && vitest run packages/dragon",
|
|
76
|
-
"test:watch": "cd ../.. && vitest packages/dragon",
|
|
77
|
-
"lint": "tsc --noEmit"
|
|
78
79
|
}
|
|
79
|
-
}
|
|
80
|
+
}
|
package/src/compile.ts
CHANGED
|
@@ -255,6 +255,21 @@ export function compileToCdl(doc: DslDocument, opts?: CompileToCdlOpts): CdlDiag
|
|
|
255
255
|
case "line":
|
|
256
256
|
diagram = compileValueChart(doc, "line", "chart-line", opts?.onNotice);
|
|
257
257
|
break;
|
|
258
|
+
case "gauge":
|
|
259
|
+
diagram = compileValueChart(doc, "gauge", "chart-gauge", opts?.onNotice);
|
|
260
|
+
break;
|
|
261
|
+
case "radial":
|
|
262
|
+
diagram = compileValueChart(doc, "radial", "chart-radial", opts?.onNotice);
|
|
263
|
+
break;
|
|
264
|
+
case "stat":
|
|
265
|
+
diagram = compileValueChart(doc, "stat", "chart-stat", opts?.onNotice);
|
|
266
|
+
break;
|
|
267
|
+
case "waffle":
|
|
268
|
+
diagram = compileValueChart(doc, "waffle", "chart-waffle", opts?.onNotice);
|
|
269
|
+
break;
|
|
270
|
+
case "stacked":
|
|
271
|
+
diagram = compileValueChart(doc, "stacked", "chart-stacked-bar", opts?.onNotice);
|
|
272
|
+
break;
|
|
258
273
|
case "funnel":
|
|
259
274
|
diagram = compileFunnel(doc, opts?.onNotice);
|
|
260
275
|
break;
|
|
@@ -700,6 +715,11 @@ const 図種の作り: Record<PresetType, "登場人物ごとに箱" | "図全
|
|
|
700
715
|
pie: "図全体を 1 箱",
|
|
701
716
|
bar: "図全体を 1 箱",
|
|
702
717
|
line: "図全体を 1 箱",
|
|
718
|
+
gauge: "図全体を 1 箱",
|
|
719
|
+
radial: "図全体を 1 箱",
|
|
720
|
+
stat: "図全体を 1 箱",
|
|
721
|
+
waffle: "図全体を 1 箱",
|
|
722
|
+
stacked: "図全体を 1 箱",
|
|
703
723
|
funnel: "図全体を 1 箱",
|
|
704
724
|
tree: "図全体を 1 箱",
|
|
705
725
|
journey: "図全体を 1 箱",
|
|
@@ -1062,6 +1082,11 @@ const 空の形の逃げ先: Record<PresetType, string[]> = {
|
|
|
1062
1082
|
pie: [],
|
|
1063
1083
|
bar: [],
|
|
1064
1084
|
line: [],
|
|
1085
|
+
gauge: [],
|
|
1086
|
+
radial: [],
|
|
1087
|
+
stat: [],
|
|
1088
|
+
waffle: [],
|
|
1089
|
+
stacked: [],
|
|
1065
1090
|
funnel: [],
|
|
1066
1091
|
tree: [],
|
|
1067
1092
|
journey: [],
|
|
@@ -4591,8 +4616,16 @@ function 参照する名前(value: number | string | null): string | null {
|
|
|
4591
4616
|
*/
|
|
4592
4617
|
function compileValueChart(
|
|
4593
4618
|
doc: DslDocument,
|
|
4594
|
-
型: "pie" | "bar" | "line",
|
|
4595
|
-
kind:
|
|
4619
|
+
型: "pie" | "bar" | "line" | "gauge" | "radial" | "stat" | "waffle" | "stacked",
|
|
4620
|
+
kind:
|
|
4621
|
+
| "chart-pie"
|
|
4622
|
+
| "chart-bar"
|
|
4623
|
+
| "chart-line"
|
|
4624
|
+
| "chart-gauge"
|
|
4625
|
+
| "chart-radial"
|
|
4626
|
+
| "chart-stat"
|
|
4627
|
+
| "chart-waffle"
|
|
4628
|
+
| "chart-stacked-bar",
|
|
4596
4629
|
onNotice?: (notice: CompileNotice) => void,
|
|
4597
4630
|
): CdlDiagram {
|
|
4598
4631
|
const b = diagram(slugify(doc.title), { topic: doc.title });
|
|
@@ -4600,11 +4633,19 @@ function compileValueChart(
|
|
|
4600
4633
|
// **高さは型で違い、 格子に載せる**。 描画側 (`cdl` の `chart()` preset) は `pie` を 320、
|
|
4601
4634
|
// 棒と折れ線を 360 とした上で **16 の倍数へ切り上げる** (360 は 16 で割り切れないので 368)。
|
|
4602
4635
|
// 切り上げないと下端が格子から外れ、 全図で位置の警告が出る (review 指摘)
|
|
4603
|
-
|
|
4636
|
+
// 半円と弧は縦を使わないので円と同じ 320。 描画側 (`cdl` の `chart()` preset) が
|
|
4637
|
+
// `pie` / `gauge` / `radial` を 320、棒と折れ線を 360 とし、16 の倍数へ切り上げる
|
|
4638
|
+
// 縦に余白が要らない型。 描画側 (`cdl` の `chart()` preset) と揃える。
|
|
4639
|
+
// 半円 / 弧 / 割合の印 は縦を使わず、値 1 つを大きく示す図も縦に伸びない
|
|
4640
|
+
const 低い型 =
|
|
4641
|
+
型 === "pie" || 型 === "gauge" || 型 === "radial" || 型 === "waffle" || 型 === "stat";
|
|
4642
|
+
const CHART_H = 低い型 ? 320 : 368;
|
|
4604
4643
|
b.lane("chart", { width: CHART_W + 64 });
|
|
4605
4644
|
|
|
4606
4645
|
const data: NonNullable<CdlDiagram["nodes"][number]["chartData"]> = [];
|
|
4607
4646
|
const 読めない: string[] = [];
|
|
4647
|
+
const 前が読めない: string[] = [];
|
|
4648
|
+
let 前が読めない行 = 0;
|
|
4608
4649
|
const 未宣言: string[] = [];
|
|
4609
4650
|
let 未宣言行 = 0;
|
|
4610
4651
|
const 参照できる = 数の欄から参照できる名前(doc);
|
|
@@ -4631,16 +4672,37 @@ function compileValueChart(
|
|
|
4631
4672
|
continue;
|
|
4632
4673
|
}
|
|
4633
4674
|
// 色はそのまま渡す。 箱が 1 つになっても、 書いた色が消えないようにする
|
|
4634
|
-
|
|
4675
|
+
// 前の時点の値 (#1450)。 読めない形は黙って捨てず知らせる = 書いたのに 2 本目の帯が
|
|
4676
|
+
// 出ない状態になり、手掛かりが残らない
|
|
4677
|
+
const 前 = a.previous === undefined ? null : parseChartValue(a.previous);
|
|
4678
|
+
if (a.previous !== undefined && 前 === null) {
|
|
4679
|
+
if (前が読めない.length === 0) 前が読めない行 = a.pos?.line ?? 0;
|
|
4680
|
+
前が読めない.push(a.name);
|
|
4681
|
+
}
|
|
4682
|
+
data.push({
|
|
4683
|
+
label: 箱の題(a),
|
|
4684
|
+
value,
|
|
4685
|
+
...(前 === null ? {} : { previous: 前 }),
|
|
4686
|
+
...(a.tone !== undefined ? { tone: a.tone } : {}),
|
|
4687
|
+
});
|
|
4635
4688
|
}
|
|
4636
4689
|
// 案内の言葉は型ごとに変える。 共通化した時に `pie` の「割合 / 円 / 45%」 が「値 / 図 / 45」 に
|
|
4637
4690
|
// 薄まり、 既存の案内が後退した (review 指摘)。 何を書けばよいかは型ごとに違う
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4691
|
+
// 何を書けばよいかは型ごとに違う。 まとめると「割合 / 円 / 45%」 が「値 / 図 / 45」 に薄まる
|
|
4692
|
+
//
|
|
4693
|
+
// **表で持つ**。 三項の連鎖にすると、型が増えるたびに深さが増え、最後の枝が
|
|
4694
|
+
// 「それ以外」 になるため型検査が新しい型の漏れを教えてくれない
|
|
4695
|
+
const 語の表: Record<typeof 型, { 量: string; 図: string; 例: string }> = {
|
|
4696
|
+
pie: { 量: "割合", 図: "円", 例: '"45%"' },
|
|
4697
|
+
bar: { 量: "値", 図: "棒", 例: '"420"' },
|
|
4698
|
+
line: { 量: "値", 図: "折れ線", 例: '"180"' },
|
|
4699
|
+
gauge: { 量: "値", 図: "半円", 例: '"680"' },
|
|
4700
|
+
radial: { 量: "値", 図: "弧", 例: '"72"' },
|
|
4701
|
+
stat: { 量: "値", 図: "大きな数字", 例: '"1200"' },
|
|
4702
|
+
waffle: { 量: "割合", 図: "100 個の印", 例: '"45%"' },
|
|
4703
|
+
stacked: { 量: "内訳の値", 図: "帯", 例: '"320"' },
|
|
4704
|
+
};
|
|
4705
|
+
const 語 = 語の表[型];
|
|
4644
4706
|
|
|
4645
4707
|
/**
|
|
4646
4708
|
* 利用者に伝える。 **`console.warn` だけにしない**。 エディタは受け取った notice を画面に
|
|
@@ -4669,6 +4731,15 @@ function compileValueChart(
|
|
|
4669
4731
|
未宣言行,
|
|
4670
4732
|
);
|
|
4671
4733
|
}
|
|
4734
|
+
if (前が読めない.length > 0) {
|
|
4735
|
+
伝える(
|
|
4736
|
+
"chart-value-unreadable",
|
|
4737
|
+
前が読めない[0]!,
|
|
4738
|
+
`type: ${型} で前の時点の値を読めない項目があります (前の値を使いません): ${前が読めない.join(", ")}。` +
|
|
4739
|
+
" `- 名前: { value: " + 語.例 + ", previous: " + 語.例 + " }` の形で書いてください",
|
|
4740
|
+
前が読めない行,
|
|
4741
|
+
);
|
|
4742
|
+
}
|
|
4672
4743
|
if (doc.flow.length > 0) {
|
|
4673
4744
|
伝える(
|
|
4674
4745
|
"chart-edge-dropped",
|
|
@@ -5493,6 +5564,8 @@ type 放射で描けない欄 =
|
|
|
5493
5564
|
| "stack"
|
|
5494
5565
|
| "initial"
|
|
5495
5566
|
| "final"
|
|
5567
|
+
// 前の時点の値 (#1450)。 放射の枝は 1 時点しか描かない = 2 本目の帯に当たるものが無い
|
|
5568
|
+
| "previous"
|
|
5496
5569
|
| "colorHex"
|
|
5497
5570
|
| "stateOverride"
|
|
5498
5571
|
| "posX"
|
|
@@ -5556,6 +5629,7 @@ const 放射で描けない欄の名前: Record<放射で描けない欄, string
|
|
|
5556
5629
|
stack: "積む順",
|
|
5557
5630
|
initial: "始まり / 終わり の印",
|
|
5558
5631
|
final: "始まり / 終わり の印",
|
|
5632
|
+
previous: "前の時点の値",
|
|
5559
5633
|
colorHex: "色番号",
|
|
5560
5634
|
stateOverride: "状態の上書き",
|
|
5561
5635
|
// 位置は「登場人物ごとの箱をどこに置くか」 の指定で、 箱が 1 つの図では置く先が無い
|
|
@@ -6174,6 +6248,9 @@ function injectPhasesFallback(diagram: CdlDiagram, doc: DslDocument): void {
|
|
|
6174
6248
|
body: p.body ?? "",
|
|
6175
6249
|
activate: activateIds,
|
|
6176
6250
|
...(drawIds.length > 0 ? { draw: drawIds } : {}),
|
|
6251
|
+
// 描く速さ (#1441)。 **描く相手が決まった段にだけ載せる** = 語が効かない図種
|
|
6252
|
+
// (`drawIds` が空) で割合だけ渡すと、描画側が「draw が空なのに割合がある」 と知らせる
|
|
6253
|
+
...(drawIds.length > 0 && p.drawRatio !== undefined ? { drawRatio: p.drawRatio } : {}),
|
|
6177
6254
|
tweens: (p.tweens ?? []).map((t) => ({ stateId: t.state, from: t.from, to: t.to })),
|
|
6178
6255
|
sets: (p.sets ?? []).map((s) => ({ stateId: s.state, value: s.value })),
|
|
6179
6256
|
...(p.badge ? { badge: p.badge } : {}),
|
|
@@ -6570,9 +6647,35 @@ function 始まりと終わりの決め方(doc: DslDocument): {
|
|
|
6570
6647
|
};
|
|
6571
6648
|
}
|
|
6572
6649
|
|
|
6650
|
+
/** 状態の図で `stateMachine` preset が全ての箱に使う種類 */
|
|
6651
|
+
const 状態の図の既定の種類: NodeKind = "card";
|
|
6652
|
+
|
|
6653
|
+
/**
|
|
6654
|
+
* 状態の図で、既定と違う種類を書いた登場人物がいるか (#1450)。
|
|
6655
|
+
*
|
|
6656
|
+
* `stateMachine` preset は全ての状態を `card` で描くため、書いた `kind:` が黙って消える。
|
|
6657
|
+
* 始点終点の印 (`mark-start` / `mark-end`) を書けるようにするには、書いた形を効かせる必要がある。
|
|
6658
|
+
*
|
|
6659
|
+
* **「書いたか」 だけでは広すぎる**。 記法だけの種類 (`kind: state` 等) は `card` に読み替わり、
|
|
6660
|
+
* preset の出す形と同じになる = 書いても何も変わらないので経路を切り替える理由が無い。
|
|
6661
|
+
* 切り替えると既存の図の id と枠の作りが変わる (実測で golden 8 件が落ちた)。
|
|
6662
|
+
*
|
|
6663
|
+
* 読み替えた後の種類が既定と違う時だけ切り替える。 こうすると「書いたのに効かない」 は消え、
|
|
6664
|
+
* 「書いたが結果が同じ」 は従来の経路に留まる。
|
|
6665
|
+
*/
|
|
6666
|
+
function 既定と違う種類を書いた(doc: DslDocument): boolean {
|
|
6667
|
+
return doc.actors.some(
|
|
6668
|
+
(a) => a.kindWritten === true && 描ける種別(a.kind) !== 状態の図の既定の種類,
|
|
6669
|
+
);
|
|
6670
|
+
}
|
|
6671
|
+
|
|
6573
6672
|
function compileState(doc: DslDocument): CdlDiagram {
|
|
6574
6673
|
// v0.4 ... animation あり時 builder 直接経路 (各 state を lane で配置、 transition を edge)
|
|
6575
|
-
|
|
6674
|
+
//
|
|
6675
|
+
// **種類を書いた形は動きの有無に関わらず generic 経路へ** (#1450、 #1263 と同じ理由)。
|
|
6676
|
+
// 動く図だけで効かせると、同じ記法でも静止図では指定が黙って消える
|
|
6677
|
+
// (実測 = `kind: mark-start` を書いた箱が `card` になり知らせも出ない)
|
|
6678
|
+
if ((doc.animate && doc.animate.phases.length > 0) || 既定と違う種類を書いた(doc)) {
|
|
6576
6679
|
return compileGenericWithAnimate(doc, { kind: "state", laneWidth: 360 });
|
|
6577
6680
|
}
|
|
6578
6681
|
// stateMachine preset ... actors を state に、 流れ を transition に
|
package/src/json-parser.ts
CHANGED
|
@@ -212,6 +212,13 @@ export interface JsonActor {
|
|
|
212
212
|
subtitle?: string;
|
|
213
213
|
eyebrow?: string;
|
|
214
214
|
value?: string;
|
|
215
|
+
/**
|
|
216
|
+
* 前の時点の値 (#1450)。 記法の `{ value: "320", previous: "280" }` と同じ。
|
|
217
|
+
*
|
|
218
|
+
* 内訳の変化を帯で示す図 (`type: stacked`) が 2 本目の帯として描き、
|
|
219
|
+
* 値 1 つを大きく示す図 (`type: stat`) が差として出す。 書かない図は 1 本のまま。
|
|
220
|
+
*/
|
|
221
|
+
previous?: string;
|
|
215
222
|
rows?: string[];
|
|
216
223
|
lane?: string;
|
|
217
224
|
stack?: number;
|
|
@@ -354,6 +361,13 @@ export interface JsonPhase {
|
|
|
354
361
|
* 受ける 8 語は `DRAW_WORDS` が持つ。 語と同じ図種で、その段の間に図が起点から現れる。
|
|
355
362
|
*/
|
|
356
363
|
draw?: string;
|
|
364
|
+
/**
|
|
365
|
+
* 描き終えるまでに段の何割を使うか (#1441)。 記法の `draw: line 0.4` の後半と同じ。
|
|
366
|
+
*
|
|
367
|
+
* 0 より大きく 1 以下。 書かなければ段の終わりに描き終わる。 `draw` が無い段に書いても
|
|
368
|
+
* 何も起きない (描く相手が決まらないため、写す時に外す)。
|
|
369
|
+
*/
|
|
370
|
+
drawRatio?: number;
|
|
357
371
|
/**
|
|
358
372
|
* 段の中で値を動かす (#1186)。 記法の `tween: name 100 -> 90` と同じ。
|
|
359
373
|
*
|
|
@@ -444,6 +458,8 @@ export const ACCEPTED_KEYS = {
|
|
|
444
458
|
"subtitle",
|
|
445
459
|
"eyebrow",
|
|
446
460
|
"value",
|
|
461
|
+
// 前の時点の値 (#1450)。 内訳の変化を帯で示す図と、値 1 つを大きく示す図が読む
|
|
462
|
+
"previous",
|
|
447
463
|
"rows",
|
|
448
464
|
"lane",
|
|
449
465
|
"stack",
|
|
@@ -496,7 +512,7 @@ export const ACCEPTED_KEYS = {
|
|
|
496
512
|
"overlay",
|
|
497
513
|
"pos",
|
|
498
514
|
],
|
|
499
|
-
phase: ["step", "duration", "focus", "body", "badge", "tween", "set", "draw"],
|
|
515
|
+
phase: ["step", "duration", "focus", "body", "badge", "tween", "set", "draw", "drawRatio"],
|
|
500
516
|
viewport: ["width", "height", "scale", "laneWidth", "gap", "laneGap", "nodeGap", "labelMargin"],
|
|
501
517
|
lane: ["x", "width", "label", "contain", "lifeline", "pos"],
|
|
502
518
|
group: ["label", "lanes"],
|
|
@@ -583,6 +599,7 @@ export const 欄の型表 = {
|
|
|
583
599
|
subtitle: "文字列",
|
|
584
600
|
eyebrow: "文字列",
|
|
585
601
|
value: "文字列",
|
|
602
|
+
previous: "文字列",
|
|
586
603
|
rows: "文字列の並び",
|
|
587
604
|
lane: "文字列",
|
|
588
605
|
stack: "数",
|
|
@@ -644,6 +661,7 @@ export const 欄の型表 = {
|
|
|
644
661
|
tween: "object",
|
|
645
662
|
set: "object",
|
|
646
663
|
draw: "描くもの",
|
|
664
|
+
drawRatio: "数",
|
|
647
665
|
},
|
|
648
666
|
viewport: {
|
|
649
667
|
width: "数",
|
|
@@ -2161,6 +2179,7 @@ export function jsonToDoc(json: DragonJson): DslDocument {
|
|
|
2161
2179
|
subtitle: a.subtitle,
|
|
2162
2180
|
eyebrow: a.eyebrow,
|
|
2163
2181
|
value: a.value,
|
|
2182
|
+
previous: a.previous,
|
|
2164
2183
|
rows: a.rows,
|
|
2165
2184
|
lane: a.lane,
|
|
2166
2185
|
stack: a.stack,
|
|
@@ -2286,6 +2305,9 @@ export function jsonToDoc(json: DragonJson): DslDocument {
|
|
|
2286
2305
|
badge: p.badge,
|
|
2287
2306
|
// 書いた段だけが欄を持つ。 空文字を置くと「書いた」 と「書いていない」 が同じ形になる
|
|
2288
2307
|
...(p.draw !== undefined ? { draw: p.draw, drawPos: p0 } : {}),
|
|
2308
|
+
// 割合は `draw` がある段にだけ写す。 単独で書いても描く相手が決まらず何も起きないので、
|
|
2309
|
+
// 記法側 (同じ行に書かせる形) と同じ状態に揃える
|
|
2310
|
+
...(p.draw !== undefined && p.drawRatio !== undefined ? { drawRatio: p.drawRatio } : {}),
|
|
2289
2311
|
// 段の中で動かす分 (#1186)。 記法側の `tweens` / `sets` と同じ形に写す。
|
|
2290
2312
|
// 空の配列を置かないのは、記法側が「無ければ field ごと持たない」 形だから
|
|
2291
2313
|
...(p.tween && Object.keys(p.tween).length > 0
|
package/src/schemas/diagram.json
CHANGED
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"pie",
|
|
28
28
|
"bar",
|
|
29
29
|
"line",
|
|
30
|
+
"gauge",
|
|
31
|
+
"radial",
|
|
32
|
+
"stat",
|
|
33
|
+
"waffle",
|
|
34
|
+
"stacked",
|
|
30
35
|
"funnel",
|
|
31
36
|
"tree",
|
|
32
37
|
"journey",
|
|
@@ -34,11 +39,11 @@
|
|
|
34
39
|
"c4",
|
|
35
40
|
"mind"
|
|
36
41
|
],
|
|
37
|
-
"description": "図の種類。 型ごとに actors の書き方が違う。 [関係を描く] sequence (時系列の呼び出し) / flow (処理の流れ) / swimlane (責務ごとの流れ) / er (DB の schema) / state (状態の遷移) / topology (network) / solidity (contract) / class (UML の class) / c4 (architecture) / mind (発想の枝分かれ) は actors に名前を並べ flow に矢印を書く。 [値を描く] pie (割合) / bar (棒の高さ) / line (線の高さ、 書いた順に並ぶ) は actors に `- 名前: \"45\"` の形で数を書く。 funnel (段ごとに減る数) も同じ形。 [語を描く] journey (体験の起伏) は `- 登録: \"不満\"` の形で 最高 / 満足 / 普通 / 不満 / 怒り のどれかを書く。 quadrant (2 軸の仕分け) は `- 重複削除: \"左上\"` の形で 左上 / 右上 / 左下 / 右下 のどれかを書く。 [時期を描く] gantt (工程の並び) は `- 設計: \"1月\"` の形で始まりの時期を書き、 flow の矢印で前後関係を書く。 [親子を描く] tree (親子の入れ子) は actors に名前を並べ flow の矢印で親子を書く (矢印の先が子)"
|
|
42
|
+
"description": "図の種類。 型ごとに actors の書き方が違う。 [関係を描く] sequence (時系列の呼び出し) / flow (処理の流れ) / swimlane (責務ごとの流れ) / er (DB の schema) / state (状態の遷移) / topology (network) / solidity (contract) / class (UML の class) / c4 (architecture) / mind (発想の枝分かれ) は actors に名前を並べ flow に矢印を書く。 [値を描く] pie (割合) / bar (棒の高さ) / line (線の高さ、 書いた順に並ぶ) / gauge (合計を半円で示す) / radial (弧の長さで比べる) / stat (値 1 つを大きく示す) / waffle (割合を 100 個の印で示す) / stacked (内訳を帯で示す) は actors に `- 名前: \"45\"` の形で数を書く。 stat と stacked は `- 名前: { value: \"320\", previous: \"280\" }` の形で前の時点の値も書ける。 funnel (段ごとに減る数) も同じ形。 [語を描く] journey (体験の起伏) は `- 登録: \"不満\"` の形で 最高 / 満足 / 普通 / 不満 / 怒り のどれかを書く。 quadrant (2 軸の仕分け) は `- 重複削除: \"左上\"` の形で 左上 / 右上 / 左下 / 右下 のどれかを書く。 [時期を描く] gantt (工程の並び) は `- 設計: \"1月\"` の形で始まりの時期を書き、 flow の矢印で前後関係を書く。 [親子を描く] tree (親子の入れ子) は actors に名前を並べ flow の矢印で親子を書く (矢印の先が子)"
|
|
38
43
|
},
|
|
39
44
|
"eyebrow": {
|
|
40
45
|
"type": "string",
|
|
41
|
-
"description": "図表の箱の上に出す小見出し (省略可)。 効くのは図全体を 1 箱にする型 (pie / bar / line / funnel / tree / journey / quadrant / mind / gantt) だけ。 箱ごとに分かれる型では相手が決まらないため、 actors[].eyebrow に書く"
|
|
46
|
+
"description": "図表の箱の上に出す小見出し (省略可)。 効くのは図全体を 1 箱にする型 (pie / bar / line / gauge / radial / stat / waffle / stacked / funnel / tree / journey / quadrant / mind / gantt) だけ。 箱ごとに分かれる型では相手が決まらないため、 actors[].eyebrow に書く"
|
|
42
47
|
},
|
|
43
48
|
"axes": {
|
|
44
49
|
"type": "object",
|
|
@@ -107,6 +112,10 @@
|
|
|
107
112
|
"type": "string",
|
|
108
113
|
"description": "actor 数値表示 (kind: actor 用)"
|
|
109
114
|
},
|
|
115
|
+
"previous": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"description": "前の時点の値。 type: stacked が 2 本目の帯として描き、type: stat が差として出す。 書かない図は 1 本のまま"
|
|
118
|
+
},
|
|
110
119
|
"rows": {
|
|
111
120
|
"type": "array",
|
|
112
121
|
"items": {
|
|
@@ -584,6 +593,12 @@
|
|
|
584
593
|
"enum": ["line", "bar", "pie", "journey", "mind", "tree", "gantt", "funnel"],
|
|
585
594
|
"description": "この phase で起点から描くもの。 語は図種と揃える。 line / journey = 線が左端から右へ伸びる / bar = 棒が横軸から上へ伸びる / pie = 扇が 12 時から時計回りに開く / mind = 枝が中心から外へ伸びる / tree = 枝が根から下へ伸びる / gantt = 帯が各始端から右へ伸びる / funnel = 段が上端から順に積まれる"
|
|
586
595
|
},
|
|
596
|
+
"drawRatio": {
|
|
597
|
+
"type": "number",
|
|
598
|
+
"exclusiveMinimum": 0,
|
|
599
|
+
"maximum": 1,
|
|
600
|
+
"description": "描き終えるまでに phase の何割を使うか。 0.4 なら進みが 0.4 に達した時点で描き終わり、残りは描き終わった姿のまま値だけが動く。 書かなければ phase の終わりに描き終わる。 draw と一緒に書く (draw が無いと何も起きない)"
|
|
601
|
+
},
|
|
587
602
|
"tween": {
|
|
588
603
|
"type": "object",
|
|
589
604
|
"description": "この phase で補間する状態。 状態名 -> [開始値, 終了値]。 名前は英字か _ で始め、 英数字と _ だけを使う",
|
package/src/types.ts
CHANGED
|
@@ -71,6 +71,11 @@ export type PresetType =
|
|
|
71
71
|
| "pie"
|
|
72
72
|
| "bar"
|
|
73
73
|
| "line"
|
|
74
|
+
| "gauge"
|
|
75
|
+
| "radial"
|
|
76
|
+
| "stat"
|
|
77
|
+
| "waffle"
|
|
78
|
+
| "stacked"
|
|
74
79
|
| "funnel"
|
|
75
80
|
| "tree"
|
|
76
81
|
| "journey"
|
|
@@ -214,6 +219,16 @@ export type DslActor = {
|
|
|
214
219
|
subtitle?: string;
|
|
215
220
|
eyebrow?: string;
|
|
216
221
|
value?: string;
|
|
222
|
+
/**
|
|
223
|
+
* 前の時点の値 (#1450)。
|
|
224
|
+
*
|
|
225
|
+
* 内訳の変化を帯で示す図 (`type: stacked`) が 2 本目の帯として描き、値 1 つを大きく示す図
|
|
226
|
+
* (`type: stat`) が差として出す。 書かない図は 1 本のまま (従来と同じ)。
|
|
227
|
+
*
|
|
228
|
+
* **3 時点以上は持たない**。 描画側が 2 時点で設計されており (`cdl#551`)、足すなら欄の形ごと
|
|
229
|
+
* 決め直すことになる。
|
|
230
|
+
*/
|
|
231
|
+
previous?: string;
|
|
217
232
|
rows?: string[];
|
|
218
233
|
/**
|
|
219
234
|
* 箱の中に描く図形 (`shape:`、 #1374)。 水位や角度を状態で動かせる。
|
|
@@ -546,6 +561,20 @@ export type DslPhase = {
|
|
|
546
561
|
* 相手の名前は書かせない = 対象の 8 図種はいずれも図全体を 1 箱で描くため相手が決まる。
|
|
547
562
|
*/
|
|
548
563
|
draw?: string;
|
|
564
|
+
/**
|
|
565
|
+
* 描き終えるまでに段の何割を使うか (#1441)。
|
|
566
|
+
*
|
|
567
|
+
* `draw: line 0.4` のように語の後ろに書く。 0 より大きく 1 以下。
|
|
568
|
+
* 書かなければ段の終わりに描き終わる (従来どおり)。
|
|
569
|
+
*
|
|
570
|
+
* **段の長さと描く速さを切り離すための欄**。 伸び具合は段の進みそのものなので、
|
|
571
|
+
* これが無いと「線はゆっくり引きたいが値の移りは短くしたい」 が書けず、描く速さのために
|
|
572
|
+
* 段の長さを動かすことになる。 段の長さを動かすと同じ段の `tween` まで遅くなる。
|
|
573
|
+
*
|
|
574
|
+
* **`draw` と同じ行に書かせる**。 別の項目にすると「割合だけ書いて `draw` が無い段」 が
|
|
575
|
+
* 書けてしまい、何も起きない指定になる。 同じ行なら書けない。
|
|
576
|
+
*/
|
|
577
|
+
drawRatio?: number;
|
|
549
578
|
/**
|
|
550
579
|
* `draw` を書いた行 (#1312)。 知らせの行番号に使う。
|
|
551
580
|
*
|
package/src/v05/parser.ts
CHANGED
|
@@ -249,6 +249,11 @@ export const PRESET_TYPES: ReadonlySet<PresetType> = new Set([
|
|
|
249
249
|
"pie",
|
|
250
250
|
"bar",
|
|
251
251
|
"line",
|
|
252
|
+
"gauge",
|
|
253
|
+
"radial",
|
|
254
|
+
"stat",
|
|
255
|
+
"waffle",
|
|
256
|
+
"stacked",
|
|
252
257
|
"funnel",
|
|
253
258
|
"tree",
|
|
254
259
|
"journey",
|
|
@@ -2376,6 +2381,11 @@ function applyContinuationLines(actor: DslActor, rest: Line[], errors: DslError[
|
|
|
2376
2381
|
case "値":
|
|
2377
2382
|
out.value = stripQuotes(raw);
|
|
2378
2383
|
break;
|
|
2384
|
+
// 前の時点の値 (#1450)。 内訳を帯で示す図と値 1 つを大きく示す図が読む
|
|
2385
|
+
case "previous":
|
|
2386
|
+
case "前の値":
|
|
2387
|
+
out.previous = stripQuotes(raw);
|
|
2388
|
+
break;
|
|
2379
2389
|
case "shape":
|
|
2380
2390
|
case "図形":
|
|
2381
2391
|
out.shape = 図形として読む(raw, ln.no, errors);
|
|
@@ -2572,6 +2582,9 @@ export const ACTOR_ITEM_KEYS: ReadonlySet<string> = new Set([
|
|
|
2572
2582
|
"補足",
|
|
2573
2583
|
"value",
|
|
2574
2584
|
"値",
|
|
2585
|
+
// 前の時点の値 (#1450)。 内訳の変化を帯で示す図と、値 1 つを大きく示す図が読む
|
|
2586
|
+
"previous",
|
|
2587
|
+
"前の値",
|
|
2575
2588
|
"rows",
|
|
2576
2589
|
"行",
|
|
2577
2590
|
// 箱の中に描く図形 (#1374)
|
|
@@ -2736,6 +2749,7 @@ const ACTOR_RESERVED_FIELDS: ReadonlySet<string> = new Set([
|
|
|
2736
2749
|
"subtitle",
|
|
2737
2750
|
"eyebrow",
|
|
2738
2751
|
"value",
|
|
2752
|
+
"previous",
|
|
2739
2753
|
"rows",
|
|
2740
2754
|
"lane",
|
|
2741
2755
|
"stack",
|
|
@@ -2888,6 +2902,7 @@ export const INLINE_ACTOR_ALIASES: Record<string, string> = {
|
|
|
2888
2902
|
種類: "kind",
|
|
2889
2903
|
補足: "subtitle",
|
|
2890
2904
|
値: "value",
|
|
2905
|
+
前の値: "previous",
|
|
2891
2906
|
行: "rows",
|
|
2892
2907
|
};
|
|
2893
2908
|
|
|
@@ -2910,6 +2925,7 @@ export const INLINE_ACTOR_KEYS: ReadonlySet<string> = new Set([
|
|
|
2910
2925
|
"subtitle",
|
|
2911
2926
|
"eyebrow",
|
|
2912
2927
|
"value",
|
|
2928
|
+
"previous",
|
|
2913
2929
|
"rows",
|
|
2914
2930
|
"lane",
|
|
2915
2931
|
"stack",
|
|
@@ -3080,6 +3096,7 @@ function parseActor(line: Line, errors: DslError[]): DslActor | null {
|
|
|
3080
3096
|
owner: isPart ? undefined : opts.owner,
|
|
3081
3097
|
end: isPart ? undefined : opts.end,
|
|
3082
3098
|
value: opts.value,
|
|
3099
|
+
previous: opts.previous,
|
|
3083
3100
|
rows: opts.rows
|
|
3084
3101
|
? opts.rows
|
|
3085
3102
|
.replace(/^\[|\]$/g, "")
|
|
@@ -3512,7 +3529,10 @@ function parsePhase(block: Line[], errors: DslError[]): DslPhase | null {
|
|
|
3512
3529
|
continue;
|
|
3513
3530
|
}
|
|
3514
3531
|
if (key === "draw") {
|
|
3515
|
-
|
|
3532
|
+
// `draw: line 0.4` = 語の後ろに「描き終えるまでに段の何割を使うか」 を書ける (#1441)。
|
|
3533
|
+
// 割合を別の項目にすると「割合だけ書いて `draw` が無い段」 が書けてしまい、
|
|
3534
|
+
// 何も起きない指定になる。 同じ行なら書けない
|
|
3535
|
+
const [語 = "", 割合の文字, ...余り] = stripQuotes(value).trim().split(/\s+/);
|
|
3516
3536
|
// **読めない語を黙って捨てない** (#1304 / #1306 と同じ扱い)。 受ける語は 1 つだけで、
|
|
3517
3537
|
// 書き間違いはその段が何も描かない形になって手掛かりが残らない
|
|
3518
3538
|
if (!DRAW_WORDS.has(語)) {
|
|
@@ -3521,9 +3541,29 @@ function parsePhase(block: Line[], errors: DslError[]): DslPhase | null {
|
|
|
3521
3541
|
message: `draw に書けない語です: "${語}"`,
|
|
3522
3542
|
hint: `使える語 = ${[...DRAW_WORDS].join(", ")}`,
|
|
3523
3543
|
});
|
|
3544
|
+
} else if (余り.length > 0) {
|
|
3545
|
+
errors.push({
|
|
3546
|
+
line: ln.no,
|
|
3547
|
+
message: `draw に書ける項目は語と割合の 2 つまでです: "${stripQuotes(value).trim()}"`,
|
|
3548
|
+
hint: "use `draw: line 0.4`",
|
|
3549
|
+
});
|
|
3524
3550
|
} else {
|
|
3525
3551
|
phase.draw = 語;
|
|
3526
3552
|
phase.drawPos = { line: ln.no };
|
|
3553
|
+
if (割合の文字 !== undefined) {
|
|
3554
|
+
const 割合 = Number(割合の文字);
|
|
3555
|
+
// 範囲外を黙って捨てない。 描画側は 1 に落として図を出すため、
|
|
3556
|
+
// 知らせが無いと「書いたのに速さが変わらない」 が手掛かりなしで起きる
|
|
3557
|
+
if (!Number.isFinite(割合) || 割合 <= 0 || 割合 > 1) {
|
|
3558
|
+
errors.push({
|
|
3559
|
+
line: ln.no,
|
|
3560
|
+
message: `draw の割合が範囲外です: "${割合の文字}"`,
|
|
3561
|
+
hint: "0 より大きく 1 以下で書きます (例 `draw: line 0.4`)",
|
|
3562
|
+
});
|
|
3563
|
+
} else {
|
|
3564
|
+
phase.drawRatio = 割合;
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3527
3567
|
}
|
|
3528
3568
|
i += 1;
|
|
3529
3569
|
continue;
|