@cardenelabs/dragon 0.34.0 → 0.35.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 (127) hide show
  1. package/README.md +39 -720
  2. package/dist/cli.cjs +4529 -0
  3. package/dist/cli.cjs.map +1 -0
  4. package/dist/cli.js +4523 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/export.cjs +3912 -0
  7. package/dist/export.cjs.map +1 -0
  8. package/dist/export.d.cts +36 -0
  9. package/dist/export.d.ts +36 -0
  10. package/dist/export.js +3907 -0
  11. package/dist/export.js.map +1 -0
  12. package/dist/fonts.cjs +7 -0
  13. package/dist/fonts.cjs.map +1 -0
  14. package/dist/fonts.js +4 -0
  15. package/dist/fonts.js.map +1 -0
  16. package/dist/index.cjs +4105 -20356
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +227 -5522
  19. package/dist/index.d.ts +227 -5522
  20. package/dist/index.js +4091 -20283
  21. package/dist/index.js.map +1 -1
  22. package/dist/player.global.js +2 -0
  23. package/dist/schema-BBWfniwH.d.cts +112 -0
  24. package/dist/schema-BBWfniwH.d.ts +112 -0
  25. package/package.json +39 -24
  26. package/src/cli.ts +237 -0
  27. package/src/export/capture.ts +277 -0
  28. package/src/export/fonts.ts +68 -0
  29. package/src/export/html.ts +32 -0
  30. package/src/export/index.ts +146 -0
  31. package/src/field-messages.ts +104 -0
  32. package/src/figure-text.ts +42 -0
  33. package/src/index.ts +30 -283
  34. package/src/layout/architecture.ts +381 -0
  35. package/src/layout/measure.ts +21 -0
  36. package/src/layout/scene.ts +353 -0
  37. package/src/layout/sequence.ts +189 -0
  38. package/src/load-fonts.ts +8 -0
  39. package/src/look/fonts.ts +33 -0
  40. package/src/look/palettes.json +209 -0
  41. package/src/look/values.ts +155 -0
  42. package/src/markdown.ts +35 -0
  43. package/src/messages.ts +122 -0
  44. package/src/parser.ts +342 -310
  45. package/src/player-global.ts +4 -0
  46. package/src/player.ts +271 -0
  47. package/src/printer.ts +76 -0
  48. package/src/render/icons.ts +41 -0
  49. package/src/render/motion.ts +106 -0
  50. package/src/render/parts.ts +279 -0
  51. package/src/render/svg.ts +341 -0
  52. package/src/schema.ts +161 -16
  53. package/src/schemas/diagram.schema.json +150 -0
  54. package/src/schemas/validate-diagram.d.ts +12 -0
  55. package/src/schemas/validate-diagram.js +8 -0
  56. package/src/timeline.ts +166 -0
  57. package/src/tokenize.ts +20 -281
  58. package/src/version.ts +55 -0
  59. package/src/view.ts +16 -0
  60. package/src/words.ts +79 -0
  61. package/examples/quick-start.md +0 -142
  62. package/src/canvas-bounds.ts +0 -52
  63. package/src/color.ts +0 -197
  64. package/src/compile/actor-ids.ts +0 -297
  65. package/src/compile/actor-option-notice.ts +0 -379
  66. package/src/compile/actors.ts +0 -103
  67. package/src/compile/c4.ts +0 -74
  68. package/src/compile/chain.ts +0 -93
  69. package/src/compile/chart-fields.ts +0 -193
  70. package/src/compile/deep-rewrite.ts +0 -30
  71. package/src/compile/derived-source.ts +0 -18
  72. package/src/compile/direction.ts +0 -102
  73. package/src/compile/edge-option-notice.ts +0 -112
  74. package/src/compile/er-relation.ts +0 -200
  75. package/src/compile/flow.ts +0 -54
  76. package/src/compile/flowchart.ts +0 -344
  77. package/src/compile/funnel.ts +0 -87
  78. package/src/compile/gantt.ts +0 -337
  79. package/src/compile/generic.ts +0 -696
  80. package/src/compile/hierarchy.ts +0 -92
  81. package/src/compile/journey.ts +0 -93
  82. package/src/compile/kinds.ts +0 -139
  83. package/src/compile/lanes.ts +0 -138
  84. package/src/compile/metro.ts +0 -271
  85. package/src/compile/mind.ts +0 -393
  86. package/src/compile/node-title.ts +0 -24
  87. package/src/compile/notice.ts +0 -141
  88. package/src/compile/order.ts +0 -57
  89. package/src/compile/parts-lookup.ts +0 -17
  90. package/src/compile/parts.ts +0 -2709
  91. package/src/compile/placement-apply.ts +0 -689
  92. package/src/compile/placement.ts +0 -15
  93. package/src/compile/quadrant.ts +0 -265
  94. package/src/compile/record.ts +0 -75
  95. package/src/compile/row-marks.ts +0 -128
  96. package/src/compile/rows.ts +0 -40
  97. package/src/compile/sequence.ts +0 -305
  98. package/src/compile/slug.ts +0 -37
  99. package/src/compile/stages.ts +0 -247
  100. package/src/compile/subtitle.ts +0 -35
  101. package/src/compile/swimlane-marks.ts +0 -87
  102. package/src/compile/swimlane.ts +0 -82
  103. package/src/compile/timeline.ts +0 -213
  104. package/src/compile/topology.ts +0 -44
  105. package/src/compile/tree.ts +0 -69
  106. package/src/compile/value-chart.ts +0 -337
  107. package/src/compile/values.ts +0 -432
  108. package/src/compile/word-state.ts +0 -82
  109. package/src/compile.ts +0 -3168
  110. package/src/focus.ts +0 -46
  111. package/src/input-size.ts +0 -181
  112. package/src/json-line-map.ts +0 -30
  113. package/src/json-parser.ts +0 -4306
  114. package/src/keywords.ts +0 -417
  115. package/src/near-name.ts +0 -42
  116. package/src/notation-lint.ts +0 -342
  117. package/src/relative-pos.ts +0 -251
  118. package/src/schemas/diagram.json +0 -3088
  119. package/src/types.ts +0 -1009
  120. package/src/v05/index.ts +0 -9
  121. package/src/v05/input-table.generated.ts +0 -138
  122. package/src/v05/parser-types.ts +0 -32
  123. package/src/v05/parser.ts +0 -6668
  124. package/src/v05/readout-table.generated.ts +0 -1088
  125. package/src/v05/removed-syntax.ts +0 -115
  126. package/src/value-syntax.ts +0 -313
  127. package/src/write-position.ts +0 -270
package/README.md CHANGED
@@ -1,739 +1,58 @@
1
1
  # @cardenelabs/dragon
2
2
 
3
- Dragon は [@cardenelabs/cdl](https://www.npmjs.com/package/@cardenelabs/cdl) engine の上に乗る、 Mermaid 感覚の Text DSL。
4
- 箇条書きで書ける宣言的 syntax から animated SVG diagram を生成する。
3
+ 動く図を、人は行ごとの記法で、AI は JSON で書くための package。
5
4
 
6
- ## Why Dragon
5
+ ## 入れ方
7
6
 
8
- Mermaid は静的、 cdl 直書きは TypeScript builder が必要。
9
- Dragon は両者の中間 ... Mermaid に似た短文 syntax で書きつつ、 cdl の animation engine 上で動く。
10
-
11
- - Mermaid 風 syntax (1 行 = 1 step、 `A -> B` 矢印、 box-drawing 不要)
12
- - Mermaid にない animation (state tween / phase highlight / badge)
13
- - 出力は cdl の `CdlDiagram`、 そのまま `CdlDiagramView` 等に渡せる
14
- - engine 部 (layout / render / animation) は cdl に委譲、 dragon は parser + compiler に専念
15
-
16
- ## Quickstart
17
-
18
- ```bash
19
- npm install @cardenelabs/dragon @cardenelabs/cdl
20
- ```
21
-
22
- ```ts
23
- import { textDslToDiagram } from "@cardenelabs/dragon";
24
- import { CdlDiagramView } from "@cardenelabs/cdl/react";
25
-
26
- const diagram = textDslToDiagram(`
27
- title: "送金フロー"
28
- type: sequence
29
-
30
- actors:
31
- - Alice
32
- - Vault: storage
33
- - Bob
34
-
35
- flow:
36
- - Alice -> Vault: "deposit"
37
- - Vault -> Bob: "send" (success)
38
- `);
39
-
40
- // React で render
41
- <CdlDiagramView diagram={diagram} />
42
- ```
43
-
44
- ## 記法に書ける欄
45
-
46
- **この節の一覧は検査が実装と突き合わせる** (`test/readme-notation-keys.test.ts`)。
47
- 実装に欄が増えてここを直さないと落ちる。
48
-
49
- ### 最上位のブロック
50
-
51
- <!-- notation:top-level:start -->
52
-
53
- | 欄 | 何を書くか |
54
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
55
- | `title` | 図の題 |
56
- | `type` | 図種 (`sequence` / `flow` / `flowchart` / `swimlane` / `record` / `topology` / `gantt` / `mind` / `tree` / `c4` / `chart` / その他)。 古い綴りは組に読み替える = 数を描く 9 つ (`pie` 等) は `chart` と同じ綴りの `shape` |
57
- | `actors` | 箱 |
58
- | `flow` | 矢印 |
59
- | `states` | 状態の初期値 |
60
- | `values` | 他の状態から決まる値 (式) |
61
- | `animation` | 段 |
62
- | `viewport` | 図全体の大きさと間隔 |
63
- | `lanes` | 縦列の見出しと幅 |
64
- | `groups` | 縦列を束ねる枠 |
65
- | `eyebrow` | 図全体を 1 箱にする図種で、その箱の上に出す小見出し |
66
- | `axes` | 2 軸で仕分ける図の軸の名前 |
67
- | `regions` | 2 軸で仕分ける図の区画に出す名前 |
68
- | `readouts` | 値を見せる部品 (割合の輪 / 数え上げ / 目盛り) |
69
- | `inputs` | 読む人が動かすつまみ (すべり / 選び / 入り切り など。 書ける種類は、知らない種類を書いた時の知らせが `使える種類 = ...` の形で全て並べる。 選択肢を `{ value, label }` の組で、入り切りを `onLabel` / `offLabel` で書くと、値は綴りのまま名前で描く) |
70
- | `formulas` | つまみの値から決まる値 (式。 `values` は段が動かす状態を読み、こちらはつまみを読む。 `{ expression, label }` の組で書くと操作部に名札を出す) |
71
- | `events` | 押下などの出来事で動く仕掛け (相手は名前で指す) |
72
- | `scrolls` | 巻き上げに応じて進む値 (画面を巻き上げた量から 0 から 1 を作る) |
73
- | `bands` | 動いている間の帯 (順序図。 `- DB: 1..2` の形で言づての番号の区間を書く。 0 から数える) |
74
- | `reveal` | 矢印をいつ出すか (`phase` = 段が名指しする矢印はその段まで描かない (既定) / `all` = 最初から全部描く) |
75
- | `relations` | 触れた箱の関係を光らせるか (`off` = 何もしない (既定) / `hover` = 触れた箱と繋がる線と相手の箱だけが光る) |
76
- | `direction` | 図の並ぶ向き (`縦` / `横`、英語なら `vertical` / `horizontal`)。 効くのは `flow` と `swimlane` だけ |
77
- | `order` | 箱を並べ替える軸 (`種類`、英語なら `kind`)。 効くのは `sequence` だけで、書くと `kind:` の順 (人 → 契約 → 保管 → 出来事) に箱が並ぶ |
78
- | `shape` | 図種ごとの形。`chart` は `pie` / `bar` / `line` / `gauge` / `radial` / `stat` / `waffle` / `stacked` / `slope` (書かなければ `bar`)、`swimlane` は `stages` / `metro` / `timeline` |
79
- | `form` | `shape: pie` の見せ方 (`ring` / `arcs` / `table`、和名は `輪` / `積層の弧` / `銘板`)。 `見せ方:` とも書ける |
80
- | `ticks` | `type: gantt` の目盛りを左から順に並べる (`目盛り:` とも書ける)。 書かなければ工程の始まりから作る |
81
- | `ganttToday` | `type: gantt` の今日の位置と札 (`{ index, label }`) |
82
- | `ganttTickLabels` | `type: gantt` の各目盛りに出す名前の並び |
83
- | `ganttBarEnd` | `position` で帯を `end` の位置までにする |
84
- | `ganttBarThickness` | `thin` で帯を見本の比の細さにする |
85
- | `chartSeriesSkipMuted` | `true` で `tone: muted` の項目を系列色の番号から外す |
86
- | `chartLineSeries` | 折れ線の複数系列 (`points` / `label` / `tone` / `dash` / `marker` / `valueIndexes`)。`marker: dot` は塗った点、`hollow` は中抜きの点、`none` は点を描かない |
87
- | `chartPieCenterLabel` | 円の中心で合計の下に置く字 |
88
- | `chartPieTableColumns` | 円の表の列 (`share-value` / `value`) |
89
- | `chartPieRingWidth` | 円の輪の太さ (`thick` / `thin`) |
90
- | `chartSlopePeriods` | 傾き図の左右の時点名 2 つ |
91
- | `chartSlopeEmphasisIds` | 傾き図で主役にする項目の id |
92
- | `chartSlopeUnit` | 傾き図の値に付ける単位 |
93
- | `chartStackedPeriods` | 内訳の帯の期間と系列ごとの値 (`{ label, values }`) |
94
- | `chartStackedRateId` | 内訳の帯の右に割合を出す項目の id |
95
- | `chartStackedLegendPosition` | 内訳の帯の凡例の位置 (`top` / `bottom`) |
96
- | `chartGaugeValue` | 半円の固定尺 (`{ max, current, target?, previous?, previousLabel? }`)。`current`・`target`・`previous` は `{名前}` で段の状態を読める。`max` は数だけ |
97
- | `chartWaffleLegendPosition` | 升目の一覧の位置 (`left` / `right`) |
98
- | `funnelForm` | 漏斗の形 (`trapezoid` / `proportional-bars`) |
99
- | `funnelRate` | 漏斗の率。`drop` は前段から減った割合、`conversion` は前段から残った割合、`none` は率を描かない |
100
- | `quadrantPointLabelSide` | 四象限の座標点の名前を置く側 (`auto` / `right`) |
101
- | `treeNodeForm` | 木の箱の見せ方 (`accent` / `frame`) |
102
- | `treeSize` | 木の深さごとの札幅、札高、題・副題の字、同段・段間の隙間 (`{ nodeWidths?, nodeHeight?, titleFontSize?, subtitleFontSize?, siblingGap?, levelGap? }`) |
103
- | `treeEdgeTone` | 木の枝色の付け方 (`accent` / `depth`) |
104
- | `treeEdgeHead` | 木の枝先の形 (`none` / `triangle`) |
105
- | `mindForm` | 放射の箱の見せ方 (`filled` / `outline`) |
106
- | `mindSize` | 放射の中心・枝・葉の位置・札・字、中心から枝・枝から葉・各行の間隔とずらし (`{ contentOffset?: { x, y }, root?, branch?, leaf?, rootBranchGap?, branchLeafGap?, branchRowGap?, branchRowOffset?, leafRowGap?, leafRowOffset? }`) |
107
- | `journeyForm` | ジャーニーの段の見せ方 (`bands` / `rules`) |
108
- | `journeyLineForm` | ジャーニーの点を結ぶ線 (`curve` / `straight`) |
109
- | `journeyLabels` | ジャーニーの 5 段の名前 (`{ delighted, happy, neutral, frustrated, angry }`) |
110
- | `journeySize` | ジャーニーの描画面と点列の左右余白 (`{ plotPadding?: { left?, right? }, pointPadding?: { left?, right? } }`) |
111
- | `sequenceActorForm` | `box` で順序図の参加者を枠で囲む |
112
- | `sequenceLabelForm` | `kind` で順序図の段に種類印と種類名を添える |
113
- | `sequenceReturnHead` | `solid` で返す言づてにも塗った三角の矢じりを使う |
114
- | `sequenceKindLabels` | 順序図の種類名 (`{ call?, return?, fire? }`) を言い換える |
115
- | `sequenceRowGap` | 順序図の言づての段の間 (正の数、既定 64) |
116
- | `sequenceGutter` | 順序図の左の札の列の幅。最初の糸は「この幅 + 列幅 / 2」に来る |
117
- | `sequenceBandWidth` | 順序図の動いている間の帯の幅 |
118
- | `sequenceSelfLoop` | 順序図の自分へ戻る線 (`{ form?: "orthogonal", width?, drop? }`) |
119
- | `figureCard` | 図表の見出し帯と足 (`{ label, note? }`) |
120
- | `figureSize` | 図全体を 1 箱にする図種の札の幅と高さ (`{ width, height }`) |
121
- | `terminalDecoration` | 端末意匠用の窓操作・字送り・行番号 (`{ windowControls?, cursor?, rowOrdinal? }`) |
122
- | `cornerForm` | `theme-variants` で矩形札の一様角と手描き角を意匠から選ぶ |
123
- | `figureKindLabel` | 階層図・放射図の種類札 (`{ text, x?, y?, fontSize?, fontWeight?, letterSpacing? }`) |
124
- | `figureInset` | 図表札の飾りの凹み面 (`{ top?, right?, bottom?, left?, radius? }`) |
125
- | `chartBarSize` | 棒の目盛り・値・名前・余白・棒幅 |
126
- | `chartBarShape` | 棒を分割するか上だけ丸めた一体の形にするか (`split` / `top-rounded`) |
127
- | `chartLineSize` | 折れ線の値札間隔・目盛り・時点・点・描画面と点列の余白・時点名の基線 |
128
- | `chartPieSize` | 円の一覧幅・字・行間・余白・外半径・中心 x |
129
- | `chartWaffleSize` | 升目図の左端と升目の送り (`{ gridLeft?, cellPitch? }`) |
130
- | `chartSlopeLabelTemplate` | 傾き図の左右の札 (`{ left?, right? }`、`{name}` / `{value}` / `{unit}`) |
131
- | `chartSlopeSize` | 傾き図の点・時点・札・軸・描画面と点列の上下余白 |
132
- | `chartStackedLayout` | 内訳の帯の凡例列・間隔・帯・字・凡例の縦ずらし |
133
- | `chartGaugeSize` | 半円の帯・外半径・上位置・値の字 |
134
- | `ganttSize` | 工程名の列・時間軸の右余白・目盛り・帯・節目・依存線の寸法 |
135
- | `quadrantLabelPosition` | `outside-corners` で四象限の区画名を角の外へ置く |
136
- | `quadrantSize` | 四象限の面・点・字・札間の寸法 |
137
- | `theme` | 図の意匠 (`kinari` = 生成りに茶 / `celadon` = 青磁に墨 / `blueprint` = 図面 / `letterpress` = 活版 / `catalog` = 図録 / `terminal` = 端末 / `sketch` = 手描き / `neon` = 電飾 / `relief` = 浮彫、日本語なら `生成り` / `青磁` / `図面` / `活版` / `図録` / `端末` / `手描き` / `電飾` / `浮彫`)。 `palette:` も別名として読み、両方書くと `theme:` が勝って知らせが出る |
138
- | `legend` | 図の下へ置く凡例。 `凡例:` とも書ける。 印付きは `{ mark, text, tone?, lineStyle? }`、注記は `{ text, align?, lead? }`。和名なら `{ 印, 説明 }`。 印の種類は下の節を参照 |
139
- | `legendFontSize` | 凡例の字の大きさ |
140
- | `legendOffset` | 図全体の凡例の位置をずらす (`{ x?, y? }`) |
141
- | `edgeEndGap` | 線の両端と発着する箱の縁との隙間 (0 以上) |
142
- | `stageHeader` | `shape: stages` で全意匠に共通して使う見出し寸法 (`leftPad` / `topPad` / `numberSize` / `gap` / `nameSize` / `bottomPad`) |
143
- | `stageLayout` | `shape: stages` の列幅・列間・戻る線の迂回寸法 (`columnWidths` / `columnGap` / `backDetourTopGap` / `backDetourSideGap` / `backDetourTargetInset`) |
144
-
145
- <!-- notation:top-level:end -->
146
-
147
- ### 円の見せ方、四象限の座標、ガントの細かな位置
148
-
149
- 円は `form: table` (`見せ方: 銘板`) で名前と値の表、`arcs` で積層した弧、`ring` で輪になる。
150
- 書かなければ従来どおり輪で、円以外に書いた欄と読めない値は知らせて無視する。
151
-
152
- 四象限の箱には `at: [0.2, 0.8]` (`点の位置`) の形で x、y の順に座標を書ける。左下が
153
- `[0, 0]`、右上が `[1, 1]` で、数の代わりに `"{状態名}"` も書ける。0..1 の範囲外は知らせ、
154
- CDL の描画時に最寄りの端へ寄せる。区画の語と併記した時は座標を採り、象限が食い違えば知らせる。
155
-
156
- ガントは `ticks: [6月, 7月, 8月, 9月, 10月]` で尺と目盛り順を固定する。始まりと終わりは
157
- `"6月+0.55"` のように月内の割合 (0..1) を足せる。始まりの割合を省けば月初、`end` の割合を
158
- 省けば月末である。CDL は 1 目盛り未満の帯を描けないため、変換後の終わりが始まりより前になる
159
- 指定は知らせて 1 目盛りの幅へ倒す。工程が指さない目盛りの字は、CDL に独立した目盛り名の欄が
160
- 無いため空になる。
161
-
162
- ### 図の下に凡例を書く
163
-
164
- `legend:` の下へ、印と説明を中括弧で 1 項目ずつ書く。全ての図種で、図の下に指定順の横一列で描かれる。`legend:` を書かない図の配置と出力は変わらない。
165
-
166
- ```yaml
167
- legend:
168
- - { mark: diamond, text: "分かれ道" }
169
- - { mark: filled-circle, text: "始まり" }
170
- - { mark: line-diamond-hollow, text: "参照", tone: accent, lineStyle: dotted }
171
- - { text: "注: 点線は参照", align: end, lead: "注:" }
172
- ```
173
-
174
- 最上位の語、項目名、印はいずれも和名で書ける。英語と和名を同じ項目に併記した時は英語を使う。
175
-
176
- ```yaml
177
- 凡例:
178
- - { 印: 菱形, 説明: "分かれ道" }
179
- - { 印: 塗った丸, 説明: "始まり" }
180
- ```
181
-
182
- | `mark` | `印` |
183
- | --- | --- |
184
- | `diamond` | 菱形 |
185
- | `filled-circle` | 塗った丸 |
186
- | `double-circle` | 二重丸 |
187
- | `dotted-line` | 点線 |
188
- | `solid-line` | 実線 |
189
- | `curved-line` | 曲線 |
190
- | `rounded-label` | 角丸の札 |
191
- | `numbered-circle` | 番号の丸 |
192
- | `station` | 駅 |
193
- | `arrow` | 矢印 |
194
- | `line-triangle-hollow` | 白抜き三角の線端 |
195
- | `line-diamond-hollow` | 白抜き菱の線端 |
196
- | `line-diamond-solid` | 塗った菱の線端 |
197
- | `rounded-box` | 角丸の箱 |
198
-
199
- ### 箱に書ける欄
200
-
201
- `- 名前: { 欄: 値, ... }` の形で書く。
202
-
203
- <!-- notation:actor:start -->
204
-
205
- | 欄 | 何を書くか |
206
- | --------------- | ------------------------------------------------------------------------------ |
207
- | `kind` | 見た目の種別 (`card` / `storage` / `service` / `person` 等、`種類` とも書ける)。 種別に無い名前は部品の名前として部品の一覧 (`partsCatalog`) から引き、一覧にも無ければ種別を書かなかった箱になる。 部品を持つ一覧を渡した時は、書いた行に知らせ (`onNotice`) が出て綴りの近い名前を案内する |
208
- | `subtitle` | 題の下の補足 (`補足` とも書ける) |
209
- | `kindForm` | `icon` で kind の意味を保ったまま共通枠の部品箱にする |
210
- | `icon` | 共通枠へ描く線画 (`person` / `box` / `database` / `lightning` / `cloud` / `terminal`) |
211
- | `emptyRowsNote` | 行を持たない `storage` に行の代わりに描く注記 |
212
- | `titleAlign` | `center` で `storage` の題と小見出しを中央へ揃える |
213
- | `rowRules` | `true` で `storage` の見出し下と行の間に罫線を描く |
214
- | `rowDividerForm` | `full` で `storage` の見出し下の線を箱の左右端まで引く |
215
- | `rowWell` | 行のまとまりを収める透明な面 (`{ top?, right?, bottom?, left?, radius? }`。空 object は 2 / 16 / 4 / 16 / 15) |
216
- | `rowMarkForm` | `tone` で行頭の印を形でなく色の段で分ける |
217
- | `rowLayout` | `storage` の箱上端からの題の基準線・1 行目の基準線・行間 (`{ titleBaseline?, rowTop?, rowPitch? }`) |
218
- | `rowStripe` | `false` で `storage` の行の縞を描かない |
219
- | `nestIn` | 親の `storage` の名前。書いた表を親の内側へ入れる |
220
- | `figureCard` | `storage` または `kindForm: icon` の足 (`{ label, note? }`) |
221
- | `stationNamePosition` | 路線図の駅名を下へ置く (`bottom`) |
222
- | `subtitlePlacement` | 時間軸の担当を札の右へ置く (`right`) |
223
- | `titleFontSize` | 流れ図の `function` の札の題の大きさ |
224
- | `markGap` | 流れ図の始まり・終わりの印と次の箱との間 |
225
- | `eyebrow` | 題の上の小見出し |
226
- | `value` | 箱に出す値 (`値` とも書ける) |
227
- | `previous` | 前の時点の値 (`前の値` とも書ける)。 `type: stacked` が 2 本目の帯として描く |
228
- | `rows` | 箱の中に並べる行 (`行` とも書ける) |
229
- | `marks` | 行頭の印 (`印` とも書ける。`rows` と同じ並び)。文字列のほか `{ mark, tone? }` で `primary` / `muted` の色の段を書ける |
230
- | `stage` | `shape: stages` の泳法図で箱を入れる段階 (`段階` とも書ける) |
231
- | `lane` | どの縦列に置くか |
232
- | `stack` | 縦列の中の何段目に置くか |
233
- | `initial` | 状態遷移図で始まりの状態か |
234
- | `final` | 状態遷移図で終わりの状態か |
235
- | `tone` | 色 |
236
- | `color` | 色 (`tone` と同じ意味。 両方書いた時は `tone` を採る) |
237
- | `touchpoint` | ユーザージャーニーで、利用者が触れる場所 |
238
- | `opportunity` | ユーザージャーニーで、改善の余地 |
239
- | `opportunityPosition` | ユーザージャーニーで、改善の余地を置く場所 (`below-chart` / `below-point`) |
240
- | `owner` | 工程の並びで、担当 |
241
- | `end` | 工程の並びで、終わりの位置。 始まりより前の時期は始まりと同じに倒し、知らせ (`onNotice`) が出る |
242
- | `startLabel` | 工程の始まりに出す札。節目の位置名とは別に書ける |
243
- | `milestone` | `true` なら工程を帯ではなく節目の菱形で描く |
244
- | `emphasis` | `primary` なら工程の帯または `storage` の枠を主役として描く |
245
- | `at` | 四象限の点の座標 `[x, y]` (`点の位置` とも書ける)。 左下が 0,0、右上が 1,1 |
246
- | `posX` | 置く場所の横位置 |
247
- | `posY` | 置く場所の縦位置 |
248
- | `posW` | 箱の幅 |
249
- | `posH` | 箱の高さ |
250
- | `offsetX` | 自動で決まった位置から横へずらす量 (JSON の `pos.x`。 `posX` は座標で、こちらはずらし) |
251
- | `offsetY` | 自動で決まった位置から縦へずらす量 (JSON の `pos.y`。 片方だけ書くと残りは 0) |
252
- | `scale` | 見本 (parts) の倍率 (`倍率` とも書ける) |
253
- | `shape` | 箱の中に描く図形 (水位 / 角度 / 半径を状態で動かす、`図形` とも書ける) |
254
- | `visibleIf` | その箱を出すかどうかの条件 (`出す条件` とも書ける) |
255
- | `title` | 箱に出す題。 書かなければ名前がそのまま題になる (`題` とも書ける) |
256
- | `wBind` | 箱の幅を値に追随させる (状態の名前を `{名前}` の形で書く) |
257
- | `hBind` | 箱の高さを値に追随させる (`wBind` と同じ読み方) |
258
- | `opacity` | 箱の濃さ (0 から 1 の数か、状態の名前) |
259
- | `renderOffsetX` | 描く時だけ箱を横へずらす量 (配置と矢印はずらす前の位置を使う) |
260
- | `renderOffsetY` | 描く時だけ箱を縦へずらす量 (`renderOffsetX` と同じ読み方) |
261
-
262
- <!-- notation:actor:end -->
263
-
264
- ### 矢印に書ける欄
265
-
266
- `- A -> B: "説明" (色, 線種) { 欄: 値, ... }` の形で書く。
267
-
268
- <!-- notation:flow:start -->
269
-
270
- | 欄 | 何を書くか |
271
- | ---------------- | ------------------------------------------------------------------- |
272
- | `sub` | 説明の下の補足。`relation` と一緒に書いた record では行き先の端の多重度 |
273
- | `tailSub` | 出どころ側の端に添える字 (`1` 等)。`relation` と一緒なら UML 関係の多重度 |
274
- | `guard` | 状態遷移の条件 |
275
- | `cardinality` | ER 図の関係の多重度 (`1:1` / `1:N` / `N:1` / `N:M` / `0..1` / `1..*`)。 両端の形が語から決まり (`tailHead` / `head` を書けばそちらが勝つ)、語は説明の下の行に出る。 6 語以外の語と、ER 図以外に書いた多重度は端の形にならず、知らせ (`onNotice`) が出る |
276
- | `widthBind` | 線の太さを値に追随させる (状態やつまみの名前を `{名前}` の形で書く) |
277
- | `strokeBind` | 線の色を値に追随させる (`widthBind` と同じ読み方) |
278
- | `dashOffsetBind` | 破線の位置を値に追随させる (流れているように見せる) |
279
- | `side` | 矢印がどの辺から出るか (`top` / `right` / `bottom` / `left`) |
280
- | `fromSide` | 矢印が出どころのどの辺から出るか (`top` / `right` / `bottom` / `left`) |
281
- | `toSide` | 矢印が行き先のどの辺へ入るか (`top` / `right` / `bottom` / `left`) |
282
- | `head` | 矢印の先の形 (`triangle` 継承・実装 / `diamond` 集約・コンポジション / `open` 関連・依存 / `dot` 点 / `crow` 多 / `one` `zero-one` `many` `zero-many` ER の端 / `none` 描かない) |
283
- | `tailHead` | 出どころ側の端の形 (`dot` で点。ER は端ごとに違う個数を示すので両端に要る) |
284
- | `headFill` | 端の印の塗り (`solid` 塗る / `hollow` 白抜き) |
285
- | `tailHeadFill` | 出どころ側の印の塗り |
286
- | `relation` | record に書く UML 関係の種類 (`extends` 継承 / `implements` 実装 / `aggregates` 集約 / `composes` コンポジション / `associates` 関連 / `uses` 依存)。 書くと線と端の形と塗りと付く側がまとめて決まる |
287
- | `kind` | 順序図の言づての種類 (`call` 呼ぶ / `return` 返す / `fire` 投げる) |
288
- | `role` | 辺の役目 (`main` 主となる道)。 書いた辺だけ「いま」 の色で引く。 主となる 1 本 (または 1 続き) にだけ書く |
289
- | `labelPlate` | 説明文の下地を敷くか (`false` で外す)。 丸い下地は箱と同じ形なので、罫の細い図では名前が小さな箱に見える |
290
- | `labelOffsetX` | 説明文の位置を横にずらす |
291
- | `labelOffsetY` | 説明文の位置を縦にずらす |
292
- | `posX1` | 線の出どころ側を固定する world x 座標 |
293
- | `posY1` | 線の出どころ側を固定する world y 座標 |
294
- | `posX2` | 線の行き先側を固定する world x 座標 |
295
- | `posY2` | 線の行き先側を固定する world y 座標 |
296
- | `waypoints` | 4 つの固定端点と一緒に書く直角折れ線の途中点 (`[{ x, y }, ...]`) |
297
- | `labelCollision` | `auto` で自動回避、`author` で作者が書いた札位置を保つ |
298
- | `labelSize` | 説明文の札の幅・高さ・字 (`{ width?, height?, fontSize? }`) |
299
- | `overlay` | `true` で説明文を線の上に重ねる (分岐図の条件ラベル用) |
300
- | `fromPartNode` | 出どころが部品 (kind に部品の名前を書いた箱) の時、矢印を繋ぐ部品の中の要素の id。 要素を 1 つだけ持つ部品は書かなくてもその要素に繋がり、2 つ以上持つ部品は書かないと矢印を外して知らせる |
301
- | `toPartNode` | 行き先が部品の時、矢印を繋ぐ部品の中の要素の id (`fromPartNode` と同じ読み方) |
302
-
303
- <!-- notation:flow:end -->
304
-
305
- ## 記法の癖
306
-
307
- ### 分かれ道の図の形
308
-
309
- `type: flowchart` は、既定の横向きでは普通の手順を小見出しの無い札、`decision` を菱形、
310
- 題を書かない `mark-start` / `mark-end` を塗った丸 / 二重丸で描く。印に `title:` を書いた時は、
311
- 開始・終了の小見出しを持つ札のままにする。`loop` も「繰り返し」の小見出しを持つ札のままにする。
312
- `database` など、そのほかに種類を明記した箱は、横向きでも書いた種類の見た目を保つ。
313
- `direction: 縦` では、担当と種類を札の小見出しへまとめる従来の描き方を保つ。
314
-
315
- ### 箱の `lane:` が効く図種は限られる
316
-
317
- `type: swimlane` と `shape: stages` を組み合わせると、`stage:` (`段階:`) ごとに同じ上端と
318
- 高さの列を左から並べ、列の見出しに「段階 N」と段階の名前を出す。箱は列の中へ書いた順に積む札
319
- (`card`) になり、書いた `kind` は効かない (知らせが 1 件出る)。この形では `lane:` は縦列ではなく
320
- 担当を表し、札の右に小さな字で出る。`lanes:` に同じ id の `label` があれば、その名前を使う。
321
-
322
- 列の中の札は真下の線で結び、右の列へ進む線は列の間を曲線で渡る。札は左の列から入る線が
323
- 真横に通る段から積み始める。左の列や同じ列の上の札へ戻る線は、列の見出しより上を回る。
324
-
325
- ```yaml
326
- type: swimlane
327
- shape: stages
328
-
329
- actors:
330
- - 受付: { stage: 申請, lane: front }
331
- - 確認: { 段階: 審査, lane: review }
332
- ```
333
-
334
- `shape: metro` は担当 (`lane`) ごとに横の線路を 1 本作り、箱を駅として左から並べる。
335
- `lanes:` の `label` は担当の名札の名前、`subtitle` はその下の補足になり、名札から線路の右端まで
336
- 一点鎖線の案内線を引く。
337
- 担当が替わる線は、横線と 45 度の斜線をつないだ乗り換え線になる。
338
-
339
- ```yaml
340
- type: swimlane
341
- shape: metro
342
-
343
- lanes:
344
- shipper: { label: 荷主, subtitle: 頼む人 }
345
- courier: { label: 配送便, subtitle: 運ぶ }
346
-
347
- actors:
348
- - 始まり: { kind: mark-start, lane: shipper }
349
- - 集荷を頼む: { lane: shipper }
350
- - 在宅?: { kind: decision, lane: courier }
351
- - 受け取る: { lane: shipper }
352
- - 持ち戻る: { lane: courier }
353
- - 終わり: { kind: mark-end, lane: shipper }
354
-
355
- flow:
356
- - 始まり -> 集荷を頼む
357
- - 集荷を頼む -> 在宅?
358
- - 在宅? -> 受け取る: "はい"
359
- - 在宅? -> 持ち戻る: "いいえ"
360
- - 持ち戻る -> 集荷を頼む: "翌日もう一度" (dashed)
361
- - 受け取る -> 終わり
362
- ```
363
-
364
- 担当を書かない箱は、その箱の名前を線路名に使い、図全体で 1 件知らせる。
365
- 分かれ道から出る 1 本目は「はい」の色、2 本目以降は「いいえ」の色になり、後ろへ続く線と駅も
366
- 同じ色を引き継ぐ。
367
- 同じ担当へ向かう 2 本目以降の枝の駅は分かれ道の真下へ下ろし、横の線路上の駅としては数えない。
368
- 本線と「はい」「いいえ」の実線には矢じりを付けない。
369
- 前の駅へ戻る `(dashed)` の線は点線になり、戻り先の駅の下へ入る矢印を付ける。
370
-
371
- `animation` がある路線図でも全ての線を描く。
372
- 初めて `focus` される段がまだ来ていない線には `data-cdl-pending="true"` が付き、画面側でまだの区間を
373
- 薄く見せられる。
374
-
375
- `shape: timeline` は普通の段へ 1 から番号を振り、丸い番号を実線の縦軸上へ置く。
376
- 札は `card` で固定し、札を持つ段の上から順に軸の左右へ交互に並べる。
377
- `lane` の名前は札の右端へ担当として添え、札から同じ段の番号へ点線の補助線を引く。
378
-
379
- ```yaml
380
- type: swimlane
381
- shape: timeline
382
-
383
- lanes:
384
- front: { label: 窓口 }
385
- review: { label: 審査係 }
386
-
387
- actors:
388
- - 受付: { lane: front }
389
- - 審査: { lane: review }
390
- - 修正: { lane: front }
391
-
392
- flow:
393
- - 受付 -> 審査
394
- - 審査 -> 修正
395
- - 修正 -> 審査
7
+ ```sh
8
+ npm install @cardenelabs/dragon
396
9
  ```
397
10
 
398
- `decision` からだけ入る普通の段のうち、`decision` の直後に書かれていない段は分かれ道の脇へ置く。
399
- 脇の札は番号と補助線を持たず、分かれ道と同じ高さで担当を名前の下へ中央揃えで置く。
400
- 脇の札は、軸から札の内側までを見本の 220 以上とする。
401
- 戻る線を持つ脇の札は、軸から札の内側まで 220 空ける。
402
- 普通の段の間は見本どおり 125 とする。
403
- 次の段へ進む線は番号か軸上の印どうしを結び、終わりへ入る線を除いて矢頭を付けない。
404
- 線に書いた色と種類は軸上でも保ち、分かれ道から色付きの線で入る番号はその線と同じ色を持つ。
405
- 字のある線には `overlay: true` を渡し、描く側が線上に置ける札は線へ重ねる。
406
- 固定 7 意匠では線の札を success / error の線色で塗り、高さ 40・字 21 の太字にする。角は通常 9、端末 4、浮彫 20 とする。
407
- 電飾の分かれ道は面 `#09070f`、水色 `#00e5ff` の 3 の縁と同色の光で描く。
408
- 軸と「はい」と戻る線は 6、「いいえ」は 5、補助線は 2、番号の縁は 4、終わりの外輪は 3.5 とする。
409
- 前の段へ戻る線は札どうしを `back-detour` で結び、それ以外の分かれ道は札か軸上の印を結ぶ。
410
- 戻る線は太さ 6、丸い線端、`0 9.6` の細かな点の並びで描く。
411
- 2 段以上前へ戻る線は、道筋が途中の札や番号と交わる時だけ、それらを避けた一番近い外側の列を回る。
412
- 交わらない線の道筋は変えず、外側を回る線の札は横の区間の中点に置く。
11
+ 0.35.0 は根本から作り直した版で、0.34.0 までの記法と入口は使えない。
12
+ 今までの記法 (日本語の鍵の YAML と JSON)、`textDslToDiagram` と `jsonToDiagram` を含む入口、`@cardenelabs/cdl` へ渡して描く仕組みは [#2983](https://github.com/cardene777/dragon/issues/2983) で消した。
13
+ 作り直しで決めたことは [#2982](https://github.com/cardene777/dragon/issues/2982) にまとめている。
413
14
 
414
- 戻る線には `fromSide` / `toSide` を書ける。時間軸は右から右、段の箱は右から上へ結ぶ。
415
- `leaderTo` の無い脇の札は `subtitlePlacement: right` で担当を右へ置ける。
416
-
417
- ### 段の箱・路線図・時間軸に分かれ道と始まりと終わりを書く
418
-
419
- 泳法図の3形では、箱の `kind` に `decision` / `mark-start` / `mark-end` を書ける。
420
- 同じ印でも、形に応じて次のように描く。
421
-
422
- | 形 | `decision` | `mark-start` | `mark-end` |
423
- |---|---|---|---|
424
- | `shape: stages` | 札の右へ「分かれ道」を添える | 描かない | 描かない |
425
- | `shape: metro` | 線路上の分かれ道 | 線路の始まり | 線路の終わり |
426
- | `shape: timeline` | 軸上の分かれ道 | 描かない | 軸上の終わり |
427
-
428
- 描かない印の前後に線がある時は、前の段と後ろの段を直接結ぶ。
429
- 始まりから出る線だけ、または終わりへ入る線だけのように片側しかない線は図から外す。
430
-
431
- ```yaml
432
- title: 荷物を届ける
433
- type: swimlane
434
- shape: timeline
435
-
436
- actors:
437
- - 始まり: { kind: mark-start, lane: 荷主 }
438
- - 配達に出る: { lane: 配送便 }
439
- - 在宅?: { kind: decision, lane: 配送便 }
440
- - 受け取る: { lane: 荷主 }
441
- - 持ち戻る: { lane: 配送便 }
442
- - 終わり: { kind: mark-end, lane: 荷主 }
443
-
444
- flow:
445
- - 始まり -> 配達に出る
446
- - 配達に出る -> 在宅?
447
- - 在宅? -> 受け取る: "はい" (success)
448
- - 在宅? -> 持ち戻る: "いいえ" (error)
449
- - 持ち戻る -> 配達に出る: "翌日もう一度" (error, dashed)
450
- - 受け取る -> 終わり
451
- ```
15
+ この package は次の 4 つを持つ。
452
16
 
453
- 分かれ道から進む線には「はい」「いいえ」のような答えを書く。
454
- 前の段へ戻る線は、説明の後ろへ `(dashed)` を添えると破線になる。
455
-
456
- 縦列を並べるために使う図種 (`flow` / `topology` / `swimlane`) では効く。 縦列が骨格その
457
- ものになる図種 (`sequence` は縦列がそのまま時間軸の線) では効かず、知らせが出る。
458
-
459
- 効く図種でも **全ての箱に書いた時だけ** 効く。 一部だけ書くと、書かなかった箱をどこに
460
- 置くか決められないため知らせが出る。
461
-
462
- ```yaml
463
- type: flow
464
-
465
- lanes:
466
- left: { width: 320 }
467
- right: { width: 320 }
468
-
469
- actors:
470
- - A: { kind: card, lane: left }
471
- - B: { kind: card, lane: right }
472
- ```
473
-
474
- `lanes:` の id は組み立て側が作る形に合わせて、字 / 数 / 下線 / hyphen を受ける
475
- (`lane-idle` のような自動で作られた縦列の幅も書き直せる)。
476
- `label` は縦列の名前、`subtitle` はその補足で、通常の `topology` / `flow` の縦列見出しにも使える。
477
-
478
- `groups:` は並べた縦列のうち何本かを 1 つの枠で囲む。 枠は縦列の位置が決まった後に、束ねた縦列と
479
- 中の箱を全て含む位置と大きさで描かれ、縦列と箱の位置は組を書かない図と変わらない。
480
-
481
- ```yaml
482
- lanes:
483
- web: { label: "受付の層" }
484
- app: { label: "処理の層" }
485
- db: { label: "保存の層" }
486
-
487
- groups:
488
- inside: { label: "社内の網", lanes: [app, db] }
489
- ```
490
-
491
- 図に無い縦列は除いて囲み、1 本も無ければ枠を描かない。 束ねる縦列の間に束ねない縦列を挟むと、
492
- その縦列ごと囲む。 どちらも知らせが出る。
493
-
494
- ### 静止した `type: flow` は書いた矢印の端を使わない
495
-
496
- この図種は **登場人物を書いた順に鎖状に繋ぐ**。 矢印の説明文は「その箱を to に持つ行」
497
- から拾い、書いた側の端は使わない。
498
-
499
- ```yaml
500
- type: flow
501
-
502
- actors: [A, B, C]
503
-
504
- flow:
505
- - A -> C: "x" # 出来るのは A -> B
506
- - C -> B: "y" # 出来るのは B -> C
507
- ```
508
-
509
- 書いた端どおりに繋ぎたい時は `direction: 縦` を書くか、箱に `lane:` を書く。 向きか縦列を書いた形は
510
- 別の組み立てを通り、書いた端がそのまま矢印になる。 `direction: 縦` は並びも鎖の時と変わらない。
511
- 段 (`animation`) を書いた形も同じく書いた端を使う。 端が使われなかった行には知らせが出る。
512
-
513
- 部品 (`kind` に部品の名前を書いた箱) は、どの行の端にも書かれていなければ鎖に入らない。
514
- 部品は図の下に並び、`受付 / 部品 / 出荷` と書いても `受付 -> 出荷` が繋がる。
515
-
516
- 図の下に並ぶ部品と位置を書いた部品は、部品のすぐ上に登場人物の名前の名札を 1 つ出す
517
- (`flow` / `sequence` / `topology` / `c4`)。 部品の中に縦列を 2 本以上持つ部品でも名札は 1 つで、
518
- 部品が自分の縦列に書いた名札はそのまま残る。 部品をいくつ並べても、縦列が右へ送られて図が横に伸びることはない。
519
-
520
- 部品の中の要素は、部品の頁と同じ間で並ぶ。 頁で空けた箱の間と段の間が図に置いても詰まらないので、
521
- 部品の中の要素どうしが間隔の検査に掛からない。 頁の配置が使えない部品だけは、部品に書いた縦列の位置と
522
- 段の番号で置く。
523
-
524
- ### 段の `focus:` で部品の全体か中の 1 つを光らせる
525
-
526
- 段の `focus:` に部品の名前を書くと、部品の要素と部品の中の線が全て光る。
527
- 中の 1 つだけを光らせる時は `{部品の名前}__{要素の id}` か `{部品の名前}__{中の線の id}` を書く。
528
- 要素の id は矢印の `fromPartNode` / `toPartNode` に書く id と同じ。
529
-
530
- ```yaml
531
- title: "注文を 2 つの窓口へ分ける"
532
- type: swimlane
533
-
534
- actors:
535
- - 受注: { kind: card }
536
- - split: { kind: split-router, phase: false }
537
-
538
- flow:
539
- - 受注 -> split: "注文" { toPartNode: inP }
540
-
541
- animation:
542
- - step: "注文が入る" 1.2s
543
- focus: [split__inP]
544
- - step: "A へ渡す" 1.2s
545
- focus: [split__outA, split__sr-a]
546
- - step: "まとめて見せる" 1.2s
547
- focus: [split]
548
- ```
549
-
550
- | 段 | 光る所 |
17
+ | 持つ物 | 形 |
551
18
  |---|---|
552
- | 注文が入る | 振り分け器の入口 (`inP`) だけ |
553
- | A へ渡す | 出口 A (`outA`) と、入口から出口 A への中の線 (`sr-a`) |
554
- | まとめて見せる | 振り分け器の要素と中の線の全て |
19
+ | 原本 | 共通の骨格と図の種類ごとの欄を持つ JSON。版を持ち、古い版は読む時に変換する |
20
+ | 記法 | 1 行が 1 つの文になる行ごとの記法。JSON と行き来でき、日本語の語でも英語の語でも書ける ([書き方](https://github.com/cardene777/dragon/blob/main/packages/dragon/examples/quick-start.md)、[英語の語の書き方](https://github.com/cardene777/dragon/blob/main/packages/dragon/examples/quick-start.en.md)) |
21
+ | 描く部品 | 原本から時系列図と構成図を描き、段ごとに動かす部品。cdl には頼らない |
22
+ | 書き出し | 同じ原本から mp4、GIF、HTML、PNG を書き出す命令 |
555
23
 
556
- 部品に無い名前を書くと何も光らず、知らせ (`focus-target-missing`) が部品の要素と中の線の名前を案内する。
557
- 部品の名前そのものが `__` を含む時は、一番長く一致する部品の名前で読む。
558
-
559
- ### 順序図の段は `focus:` で強調する言づてを選ぶ
560
-
561
- `sequence` の図は 1 枚の板に言づてを行で並べる。 段ごとに 1 通を強調し、それより前は
562
- 描き済みとして残し、後ろは隠す。 どの言づてを強調するかは段の `focus:` から決まる。
563
-
564
- | `focus:` に書いたもの | 合う言づて |
565
- |---|---|
566
- | 矢印 `A -> B` | 元が A で先が B |
567
- | 箱の名前 2 つ以上 | 元と先の両方が書いた箱に含まれる |
568
- | 箱の名前 1 つ | 元か先がその箱 |
24
+ ## 書き出し
569
25
 
570
- 矢印を 1 本でも書いた段は、矢印だけで言づてを選ぶ。 同じ段の箱の名前は数えない。
26
+ 書き出しは画面なしの Chromium で、頁と同じ描画を時刻を止めて 1 コマずつ撮る。
27
+ 撮ったコマは同じ Chromium の中で mp4 と GIF に詰めるので、ffmpeg は要らない。
28
+ Chromium を動かす `playwright-core` は、書き出しを使う時だけ入れる。
571
29
 
572
- 言づては先頭から段の数に切り分け、各段が続きの言づてを受け持つ。 切り分けは次の順に良いものを選ぶ。
573
-
574
- 1. 合う言づてを持つ段が多い (どの段も板を進める)
575
- 2. 段に合う言づての数が多い
576
- 3. 2 つの段に合う言づてを、図全体で合う言づてが少ない段 (狭く指した段) に置く
577
-
578
- 段はその区間で合う最後の言づてを強調する。 合う言づてが無い段は前の段の強調を保つ。
579
-
580
- ```yaml
581
- flow:
582
- - 利用者 -> 認証窓口: "POST 認証情報"
583
- - 認証窓口 -> DB: "照合"
584
- - 認証窓口 -> 利用者: "JWT を発行"
585
-
586
- animation:
587
- - step: "照合" 1.5s
588
- focus: [利用者, 認証窓口, DB] # 1-2 通目を束ね、「照合」 を強調する
589
- - step: "発行" 1.0s
590
- focus: [認証窓口, 利用者] # 3 通目を強調する
30
+ ```sh
31
+ pnpm add -D playwright-core
32
+ pnpm exec playwright-core install chromium
591
33
  ```
592
34
 
593
- 段の題と強調する言づてを確実に揃えたい時は、矢印で書く。 同じ 2 者の矢印が続く時は、同じ矢印を段の数だけ
594
- 並べれば 1 通ずつ進む。
595
-
596
- ## API
597
-
598
- **Text DSL (人向け YAML)**
599
-
600
- - `textDslToDiagram(src: string): CdlDiagram` ... 一発変換 (v0.4 / v0.5 auto-detect、 recommended entry)
601
- - `parseTextDslV05(src: string): V05ParseResult` ... v0.5 parser を直接呼出 (error 詳細取得)
602
- - `compileToCdl(doc: DslDocument): CdlDiagram` ... AST → CdlDiagram
603
-
604
- **JSON DSL (LLM 向け)**
605
-
606
- - `jsonToDiagram(json: unknown, opts?): CdlDiagram` ... JSON DSL → CdlDiagram、 validation error は throw。 `opts` は部品の一覧 (`partsCatalog`)、 書いた通りにならなかったことの受け取り口 (`onNotice`)、 書いた場所から行を引く表 (`行の表`) の 3 つ
607
- - `書いた場所の鍵(...道): string` ... `行の表` の鍵を作る (`書いた場所の鍵("actors", 1)` が `/actors/1`)。 本文の行が分かる入口 (編集画面の YAML 欄) が表を作る時に使い、`jsonToDiagram` が同じ関数で引く
608
- - `validateDragonJson(json: unknown): { ok, data | errors }` ... compile なしで validation のみ
609
- - `diagramJsonSchema` ... JSON Schema (Draft 7)、 LLM の tool schema にそのまま注入可能
35
+ 原本の JSON (`.json`) か記法 (`.dragon`) を渡すと、同じ名前の 4 つの file を書き出す。
610
36
 
611
- **Deprecated (2026-12-31 削除予定)**
612
-
613
- - `parseTextDsl(src: string): ParseResult` ... v0.4 parser、 `textDslToDiagram` に移行推奨
614
-
615
- 組み立てた図は、色味の有無にかかわらず `textMetrics: "widest"` を持つ。比例字と等幅字の
616
- 広い方で箱・札を測るため、色味を替えても骨組みは変わらない。従来の比例字だけの配置に比べ、
617
- 字に合わせて幅が決まる箱や札は少し広がることがある。記法から測り方を指定する欄は持たない。
618
-
619
- ## LLM 向け JSON DSL
620
-
621
- LLM (Anthropic Claude / OpenAI GPT) が structured output で確実に diagram を生成できるよう、 YAML DSL と 1:1 対応する JSON 記法を提供する。
622
-
623
- ### 最小 example
624
-
625
- ```ts
626
- import { jsonToDiagram } from "@cardenelabs/dragon";
627
- import { CdlDiagramView } from "@cardenelabs/cdl/react";
628
-
629
- const diagram = jsonToDiagram({
630
- title: "ログインAPI",
631
- type: "sequence",
632
- actors: ["ユーザー", "API", "DB"],
633
- flow: [
634
- { from: "ユーザー", to: "API", label: "ログイン要求" },
635
- { from: "API", to: "DB", label: "ユーザー検索" },
636
- { from: "DB", to: "API", label: "結果", tone: "success" },
637
- { from: "API", to: "ユーザー", label: "認証成功", tone: "success" },
638
- ],
639
- animation: [
640
- { step: "call", duration: 1.4, focus: ["ユーザー", "API"] },
641
- { step: "query", duration: 1.4, focus: ["API", "DB"] },
642
- { step: "return", duration: 1.4, focus: ["DB", "API"] },
643
- { step: "ok", duration: 1.4, focus: ["API", "ユーザー"] },
644
- ],
645
- });
646
- // <CdlDiagramView diagram={diagram} />
37
+ ```sh
38
+ dragon export ccip.json --out out
647
39
  ```
648
40
 
649
- ### Anthropic Claude で LLM に書かせる example
650
-
651
- ```ts
652
- import Anthropic from "@anthropic-ai/sdk";
653
- import { jsonToDiagram, diagramJsonSchema, validateDragonJson } from "@cardenelabs/dragon";
654
-
655
- const client = new Anthropic();
656
-
657
- async function generateDiagramFromLLM(userRequest: string, maxRetry = 3) {
658
- const messages: Anthropic.MessageParam[] = [{ role: "user", content: userRequest }];
659
- for (let attempt = 0; attempt < maxRetry; attempt++) {
660
- const res = await client.messages.create({
661
- model: "claude-sonnet-5",
662
- max_tokens: 4096,
663
- tools: [
664
- {
665
- name: "create_diagram",
666
- description: "Create an animated diagram from user's request using Dragon DSL.",
667
- input_schema: diagramJsonSchema,
668
- },
669
- ],
670
- tool_choice: { type: "tool", name: "create_diagram" },
671
- messages,
672
- });
673
- const toolUse = res.content.find((c) => c.type === "tool_use");
674
- if (!toolUse || toolUse.type !== "tool_use") throw new Error("no tool_use in LLM response");
675
- const validation = validateDragonJson(toolUse.input);
676
- if (validation.ok) {
677
- return jsonToDiagram(validation.data);
678
- }
679
- // retry loop = error path を prompt に注入して LLM に修正させる
680
- const errorSummary = validation.errors.map((e) => ` ${e.path}: ${e.message}`).join("\n");
681
- messages.push({ role: "assistant", content: res.content });
682
- messages.push({
683
- role: "user",
684
- content: `The diagram JSON has validation errors:\n${errorSummary}\nPlease fix and retry.`,
685
- });
686
- }
687
- throw new Error(`LLM failed to generate valid diagram after ${maxRetry} attempts`);
688
- }
689
-
690
- // 使用例
691
- const diagram = await generateDiagramFromLLM(
692
- "ユーザーが API 経由で DB に検索をかけて結果を受け取るシーケンス図を作って",
693
- );
694
- ```
695
-
696
- ### OpenAI GPT で structured output に使う場合
697
-
698
- ```ts
699
- import OpenAI from "openai";
700
- import { jsonToDiagram, diagramJsonSchema } from "@cardenelabs/dragon";
701
-
702
- const client = new OpenAI();
703
- const res = await client.chat.completions.create({
704
- model: "gpt-4o-2024-08-06",
705
- messages: [{ role: "user", content: "..." }],
706
- response_format: {
707
- type: "json_schema",
708
- json_schema: { name: "diagram", strict: true, schema: diagramJsonSchema },
709
- },
710
- });
711
- const json = JSON.parse(res.choices[0].message.content!);
712
- const diagram = jsonToDiagram(json);
713
- ```
714
-
715
- ### JSON Schema の場所
716
-
717
- - SSOT = `packages/dragon/src/schemas/diagram.json`
718
- - npm 経由取得 = `@cardenelabs/dragon/schemas/diagram.json` (package.json exports)
719
- - TypeScript import = `import { diagramJsonSchema } from "@cardenelabs/dragon"`
720
-
721
- ### YAML と JSON の 1:1 対応
722
-
723
- 同じ図を両方の記法で書ける。 人 → YAML、 LLM → JSON が推奨だが、 混在可能。
724
-
725
- | YAML | JSON |
726
- | ---------------------- | ------------------------------------------------------- |
727
- | `title: "..."` | `{title: "..."}` |
728
- | `actors: [A, B: kind]` | `{actors: [{name: "A"}, {name: "B", kind: "storage"}]}` |
729
- | `- A -> B: "label"` | `{from: "A", to: "B", label: "label"}` |
730
- | `step: "..." 1.4s` | `{step: "...", duration: 1.4}` |
731
- | `focus: [A, B]` | `{focus: ["A", "B"]}` |
732
-
733
- 箱に書ける項目 (`tone` / `owner` / `posX` 等) は両方の記法で同じ。 一覧は実装
734
- (`INLINE_ACTOR_KEYS`) が持ち、`packages/dragon/test/json-actor-fields.test.ts` が
735
- 両入口の一致を確かめる。 ここに一覧を写すと項目が増えた時に取り残されるため書かない。
736
-
737
- ## License
41
+ | 設定 | 意味 |
42
+ |---|---|
43
+ | `--out <dir>` | 書き出す先。無ければ作る (既定は今の dir) |
44
+ | `--width <px>` | 枠の幅。見せ方 (全体を止める / 寄って追う) を選び、寄って追う窓の幅になる |
45
+ | `--palette <名前>` | 色味 (`clear` / `paper` / `night`、既定は `paper`) |
46
+ | `--theme <明暗>` | `light` か `dark` |
47
+ | `--lang <言葉>` | 図の中の字 (全体図の札、HTML の読み上げの名前、描けない時の断りの文) と、命令が出す使い方の文と誤りの文の言葉 (`ja` か `en`)。既定は記法の file の言葉で、JSON の原本と file を読む前の誤りは `ja`。記法の行の誤りだけは、書き方の例が合うよう記法の file の言葉で出す |
48
+ | `--fps <数>` | mp4 の 1 秒のコマの数 (既定 30) |
49
+ | `--gif-fps <数>` | GIF の 1 秒のコマの数 (既定 10) |
50
+ | `--format <形>` | 書き出す形を `,` で区切る (既定 `mp4,gif,html,png`) |
51
+
52
+ PNG は最後の段の止め絵を、全体を止めた見せ方で撮る。
53
+ HTML は図で描く字だけに削った字の file を埋めた 1 file で、外へ何も取りに行かない。
54
+ node から呼ぶ時は `@cardenelabs/dragon/export` の `exportDiagram` を使う。
55
+
56
+ ## license
738
57
 
739
58
  MIT