@cardenelabs/cdl 0.122.0 → 0.124.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/CHANGELOG.md +28 -1
- package/README.md +70 -1
- package/dist/index.cjs +1125 -618
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -26
- package/dist/index.d.ts +38 -26
- package/dist/index.js +1125 -619
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +894 -404
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +894 -404
- package/dist/react.js.map +1 -1
- package/dist/{render-U_pC-Ksh.d.cts → render-U6omSNH2.d.cts} +23 -4
- package/dist/{render-U_pC-Ksh.d.ts → render-U6omSNH2.d.ts} +23 -4
- package/package.json +9 -12
- package/src/builder.ts +5 -0
- package/src/index.ts +2 -0
- package/src/kinds/box-lines.ts +17 -4
- package/src/kinds/chart-bar.tsx +4 -0
- package/src/kinds/chart-gauge.tsx +20 -9
- package/src/kinds/chart-pie.tsx +67 -17
- package/src/kinds/chart-radial.tsx +7 -2
- package/src/kinds/chart-slope.tsx +26 -7
- package/src/kinds/chart-stacked-bar.tsx +8 -4
- package/src/kinds/chart-stat.tsx +19 -4
- package/src/kinds/chart-waffle.tsx +7 -2
- package/src/kinds/funnel.tsx +9 -2
- package/src/kinds/generic.tsx +5 -2
- package/src/kinds/mind-map.tsx +26 -10
- package/src/kinds/quadrant.tsx +14 -4
- package/src/kinds/row-align.ts +19 -7
- package/src/kinds/sequence-board-metrics.ts +13 -3
- package/src/kinds/sequence-board.tsx +4 -2
- package/src/kinds/shape-basement.tsx +57 -32
- package/src/kinds/shape-blockchain.tsx +83 -34
- package/src/kinds/shape-commerce.tsx +65 -24
- package/src/kinds/shape-finance.tsx +90 -26
- package/src/kinds/shape-hardware.tsx +48 -17
- package/src/kinds/shape-region.tsx +16 -6
- package/src/kinds/shape-software.tsx +30 -8
- package/src/kinds/text-width.ts +17 -3
- package/src/kinds/tree.tsx +25 -7
- package/src/layout/collisions.ts +21 -8
- package/src/layout/curve-path.ts +3 -2
- package/src/layout/edges.ts +173 -29
- package/src/layout/head-label.ts +3 -1
- package/src/layout/lanes.ts +3 -2
- package/src/layout/metro-path.ts +3 -2
- package/src/layout/nodes.ts +14 -6
- package/src/layout/predict-bbox.ts +6 -3
- package/src/layout/self-loop.ts +10 -4
- package/src/layout/spec.ts +20 -6
- package/src/layout/text-width.ts +25 -8
- package/src/layout.ts +39 -15
- package/src/presets.ts +69 -43
- package/src/render/edges.tsx +18 -3
- package/src/render/interactive-panel.tsx +34 -7
- package/src/render/nodes.tsx +97 -48
- package/src/render/stage.tsx +3 -0
- package/src/text-metrics.ts +9 -0
- package/src/types.ts +22 -2
- package/src/visual-validate.ts +67 -17
package/src/layout/text-width.ts
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* Bold は Regular に対し英字で +8-15%、 CJK は同じ、 記号は char により大差 (bold ならではの pen 太り)。
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
import type { CdlTextMetrics } from "../types";
|
|
23
|
+
|
|
22
24
|
type FontFamily = "sans" | "mono";
|
|
23
25
|
|
|
24
26
|
/**
|
|
@@ -39,6 +41,8 @@ interface MeasureOptions {
|
|
|
39
41
|
letterSpacing?: number;
|
|
40
42
|
fontFamily?: FontFamily;
|
|
41
43
|
bound?: WidthBound;
|
|
44
|
+
/** 図全体の字幅規則。`monospace` は `fontFamily: "mono"` と同じ経路で測る */
|
|
45
|
+
textMetrics?: CdlTextMetrics;
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
/**
|
|
@@ -208,22 +212,20 @@ function defaultAdvanceEm(ch: string, code: number): number {
|
|
|
208
212
|
}
|
|
209
213
|
|
|
210
214
|
/**
|
|
211
|
-
*
|
|
215
|
+
* 最低幅を当てる前の SVG render pixel 幅を実測係数で算出する。
|
|
212
216
|
*
|
|
213
|
-
* @param text 対象文字列 (
|
|
217
|
+
* @param text 対象文字列 (空文字は 0)
|
|
214
218
|
* @param opts fontSize / fontWeight / letterSpacing / fontFamily の描画 context
|
|
215
219
|
*
|
|
216
220
|
* default = fontSize 22, fontWeight 700, letterSpacing 0, fontFamily "sans" (Inter Bold)。
|
|
217
221
|
* edge label main text の caller (collisions / predict-bbox / edges) と一致する。
|
|
218
222
|
* sub text (fontSize 19, fontFamily "mono") / lane label (fontSize 20, letterSpacing 2) は
|
|
219
223
|
* opts で明示的に渡す。
|
|
220
|
-
*
|
|
221
|
-
* 最低幅 = fontSize × 1.2 (超短 label で bbox が細くなり shift 判定不安定になる問題を防ぐ)。
|
|
222
224
|
*/
|
|
223
|
-
export function
|
|
225
|
+
export function measureAdvanceWidth(text: string, opts: MeasureOptions = {}): number {
|
|
224
226
|
const fontSize = opts.fontSize ?? 22;
|
|
225
227
|
const letterSpacing = opts.letterSpacing ?? 0;
|
|
226
|
-
const fontFamily = opts.fontFamily ?? "sans";
|
|
228
|
+
const fontFamily = opts.textMetrics === "monospace" ? "mono" : (opts.fontFamily ?? "sans");
|
|
227
229
|
const bound = opts.bound ?? "layout";
|
|
228
230
|
let advanceEmSum = 0;
|
|
229
231
|
let charCount = 0;
|
|
@@ -236,7 +238,7 @@ export function measureTextWidth(text: string, opts: MeasureOptions = {}): numbe
|
|
|
236
238
|
// 割り戻さない = 測っていない字を狭く見積もると、はみ出す題を見落とす
|
|
237
239
|
const 割り戻し =
|
|
238
240
|
bound === "drawn" && !isEmojiGrapheme(ch, code)
|
|
239
|
-
? isAscii(code)
|
|
241
|
+
? isAscii(code) && fontFamily !== "mono"
|
|
240
242
|
? DRAWN_ASCII_RATIO
|
|
241
243
|
: isCJK(code)
|
|
242
244
|
? DRAWN_CJK_RATIO
|
|
@@ -248,6 +250,10 @@ export function measureTextWidth(text: string, opts: MeasureOptions = {}): numbe
|
|
|
248
250
|
continue;
|
|
249
251
|
}
|
|
250
252
|
if (fontFamily === "mono") {
|
|
253
|
+
// `DRAWN_ASCII_RATIO` (1.16) は Inter の比例幅表が実描画より広い分を見本帳の題で測った値。
|
|
254
|
+
// 0.63 は JetBrains Mono を実際に描いて測った値なので、割ると 0.543em になって等幅の
|
|
255
|
+
// 実描画 (0.6em 前後) より狭く見積もる。すると、はみ出す題を見落とし、木の箱の字を
|
|
256
|
+
// 収めたつもりで箱から出す。
|
|
251
257
|
advanceEmSum += (isCJK(code) ? 1.08 : JETBRAINS_MONO_ADVANCE_EM) / 割り戻し;
|
|
252
258
|
continue;
|
|
253
259
|
}
|
|
@@ -262,7 +268,18 @@ export function measureTextWidth(text: string, opts: MeasureOptions = {}): numbe
|
|
|
262
268
|
const table = ch.length === 1 ? INTER_BOLD_ADVANCE_EM[ch] : undefined;
|
|
263
269
|
advanceEmSum += (table !== undefined ? table : defaultAdvanceEm(ch, code)) / 割り戻し;
|
|
264
270
|
}
|
|
265
|
-
|
|
271
|
+
return advanceEmSum * fontSize + letterSpacing * charCount;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* 文字列の SVG render pixel 幅を実測係数で算出する。
|
|
276
|
+
*
|
|
277
|
+
* 最低幅 = fontSize × 1.2 (超短 label で bbox が細くなり shift 判定不安定になる問題を防ぐ)。
|
|
278
|
+
*/
|
|
279
|
+
export function measureTextWidth(text: string, opts: MeasureOptions = {}): number {
|
|
280
|
+
const fontSize = opts.fontSize ?? 22;
|
|
281
|
+
const bound = opts.bound ?? "layout";
|
|
282
|
+
const w = measureAdvanceWidth(text, opts);
|
|
266
283
|
// 最低幅は組み方のための下駄 (短い札で bbox が細くなり判定が揺れるのを防ぐ)。
|
|
267
284
|
// 実描画に合わせる時は当てない = 1 字の題が 1.2 em で描かれることは無い
|
|
268
285
|
return bound === "drawn" ? w : Math.max(w, fontSize * 1.2);
|
package/src/layout.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CdlDiagram, LaidDiagram } from "./types";
|
|
2
2
|
import { resolveLang } from "./lang";
|
|
3
|
+
import { resolveTextMetrics } from "./text-metrics";
|
|
3
4
|
import {
|
|
4
5
|
CLEARANCE_LABEL_LABEL,
|
|
5
6
|
CLEARANCE_NODE_LABEL,
|
|
@@ -219,6 +220,7 @@ export function applyRowLevelNodeShifts<
|
|
|
219
220
|
* - viewBox は cdl が auto 計算 (右端 +80 / 下端 +80)
|
|
220
221
|
*/
|
|
221
222
|
export function layout(diag: CdlDiagram): LaidDiagram {
|
|
223
|
+
const textMetrics = resolveTextMetrics(diag.textMetrics);
|
|
222
224
|
const lanes = layoutLanes(diag);
|
|
223
225
|
// 下端の名札で絵が箱の上へ出る種別は、 ここで **座標ごと** 下げる (#478)。 以降の全ての
|
|
224
226
|
// 処理 (lane の伸長 / 衝突の解消 / 矢印の経路 / 外接矩形 / 図の下端) が動かした後の位置を
|
|
@@ -226,12 +228,17 @@ export function layout(diag: CdlDiagram): LaidDiagram {
|
|
|
226
228
|
//
|
|
227
229
|
// 描画側で `<g transform>` を掛ける形だった頃は、 箱ごと下へ動いて見えるのに `cy` も
|
|
228
230
|
// `data-cdl-cy` も外接矩形も元のままで、 座標を読む側が実際の位置を知らなかった。
|
|
229
|
-
const rawNodes = applyFooterShapeDrops(lanes, layoutNodes(diag, lanes));
|
|
231
|
+
const rawNodes = applyFooterShapeDrops(lanes, layoutNodes(diag, lanes, textMetrics));
|
|
230
232
|
const expandedLanes = expandLanesForNodes(lanes, rawNodes);
|
|
231
233
|
// CAR-470 SSOT ... 隣接 lane 対を跨ぐ edge label の収納幅を engine 側で先手確保。
|
|
232
234
|
// 拡張後、 後続 lane は cumulative shift で連鎖 shift される。 lane.width は
|
|
233
235
|
// `expandLanesForNodes` 後の値のまま (node 収納 phase と gap 拡張 phase を分離)。
|
|
234
|
-
const gapExpandedLanes = expandLaneGapsForEdgeLabels(
|
|
236
|
+
const gapExpandedLanes = expandLaneGapsForEdgeLabels(
|
|
237
|
+
expandedLanes,
|
|
238
|
+
rawNodes,
|
|
239
|
+
diag.edges,
|
|
240
|
+
textMetrics,
|
|
241
|
+
);
|
|
235
242
|
const nodes = rawNodes.map((n) => {
|
|
236
243
|
// posX / posY を明示した node は「user が固定した絶対座標」 なので lane 中心に引き戻さない。
|
|
237
244
|
//
|
|
@@ -248,16 +255,18 @@ export function layout(diag: CdlDiagram): LaidDiagram {
|
|
|
248
255
|
return { ...n, cx: newLane.x + newLane.width / 2 };
|
|
249
256
|
});
|
|
250
257
|
const containedLanesPre = recomputeContainedLanes(gapExpandedLanes, nodes);
|
|
251
|
-
const edgesPre = layoutEdges(diag, nodes, containedLanesPre);
|
|
258
|
+
const edgesPre = layoutEdges(diag, nodes, containedLanesPre, textMetrics);
|
|
252
259
|
|
|
253
260
|
// 衝突 → 自動再配置 (同 kind=node 同士のみ、 sequence preset の lifeline 等は据え置き)。
|
|
254
261
|
// node の cy を shift した後は lane の contain bbox と edge routing も再計算が必要。
|
|
255
|
-
const bboxesPre = collectBBoxes(containedLanesPre, nodes, edgesPre);
|
|
262
|
+
const bboxesPre = collectBBoxes(containedLanesPre, nodes, edgesPre, textMetrics);
|
|
256
263
|
const collisionsPre = detectCollisions(bboxesPre, edgesPre);
|
|
257
264
|
const nodesResolved = resolveOverlaps(nodes, collisionsPre);
|
|
258
265
|
const moved = nodesResolved !== nodes;
|
|
259
266
|
const containedLanes = moved ? recomputeContainedLanes(gapExpandedLanes, nodesResolved) : containedLanesPre;
|
|
260
|
-
const edgesAfterMove = moved
|
|
267
|
+
const edgesAfterMove = moved
|
|
268
|
+
? layoutEdges(diag, nodesResolved, containedLanes, textMetrics)
|
|
269
|
+
: edgesPre;
|
|
261
270
|
|
|
262
271
|
// post-pass (CAR-430 = SSOT 一本化) ... edges.ts routePath() が返す init 位置を SSOT とし、
|
|
263
272
|
// label 重複が生じた場合のみ chain 伝搬 shift (resolveEdgeLabelOverlapsWithChain) で解消。
|
|
@@ -293,10 +302,13 @@ export function layout(diag: CdlDiagram): LaidDiagram {
|
|
|
293
302
|
} else {
|
|
294
303
|
const propagateResult = resolveEdgeLabelOverlapsWithChainAndPropagate(
|
|
295
304
|
edgesAfterMove,
|
|
296
|
-
collectBBoxes(containedLanes, nodesResolved, []).filter(
|
|
305
|
+
collectBBoxes(containedLanes, nodesResolved, [], textMetrics).filter(
|
|
297
306
|
(b) => b.kind === "node" || b.kind === "lane-label",
|
|
298
307
|
),
|
|
299
308
|
chainShiftClearance,
|
|
309
|
+
undefined,
|
|
310
|
+
undefined,
|
|
311
|
+
textMetrics,
|
|
300
312
|
);
|
|
301
313
|
edges = propagateResult.edges;
|
|
302
314
|
// node / lane-label chain 伝搬 shift を反映 (CAR-482)。
|
|
@@ -335,7 +347,7 @@ export function layout(diag: CdlDiagram): LaidDiagram {
|
|
|
335
347
|
// 浮遊)、 label overlap は engine が最終段階で警告可能。 今後 label shift を再度保存する
|
|
336
348
|
// 必要が生じたら labelX/labelY を propagateResult 側から edgePathShifts と同 map に保存し、
|
|
337
349
|
// 再実行後の edges に merge する二段階 approach を検討する。
|
|
338
|
-
edges = layoutEdges(diag, nodesFinal, containedLanesFinal);
|
|
350
|
+
edges = layoutEdges(diag, nodesFinal, containedLanesFinal, textMetrics);
|
|
339
351
|
}
|
|
340
352
|
}
|
|
341
353
|
|
|
@@ -352,13 +364,13 @@ export function layout(diag: CdlDiagram): LaidDiagram {
|
|
|
352
364
|
)
|
|
353
365
|
.map((e) => e.id),
|
|
354
366
|
);
|
|
355
|
-
bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds);
|
|
367
|
+
bowSharedStraightPaths(edges, nodesFinal, positionedEdgeIds, textMetrics);
|
|
356
368
|
// 弧が確定してから、 同じ節の組を結ぶ辺の label を「兄弟の線を跨がない位置」 へ置き直す (#376)。
|
|
357
369
|
// 順序が逆だと、 直線を前提に置いた label を弧が貫く。 label を先に線から離すと、 今度は弧を
|
|
358
370
|
// 膨らませる判定が label を障害物と見なして弧が消える。
|
|
359
371
|
// 同じ辺から出る線は、 最長の 1 本を除いて最初の直線部を 40 world まで引く (#651)。
|
|
360
372
|
// 経路の引き方を変えず、 確定後の最初の折れだけを動かす。
|
|
361
|
-
pullOutgoingFirstCorner(edges, nodesFinal);
|
|
373
|
+
pullOutgoingFirstCorner(edges, nodesFinal, textMetrics);
|
|
362
374
|
// 同じ辺に入る線の終点を辺に沿って離す (#611)。 経路を引き終えてから当てる = 終点を先に
|
|
363
375
|
// 動かすと引き方の分岐が変わり、 迂回していた線が箱を貫通する (実測で 0 件が 7 件になった)。
|
|
364
376
|
const fannedTailShifts = fanIncomingEndpoints(edges, nodesFinal);
|
|
@@ -375,25 +387,35 @@ export function layout(diag: CdlDiagram): LaidDiagram {
|
|
|
375
387
|
// 先に見ると、 その後に経路が動いて札が線を覆う形が戻る。
|
|
376
388
|
// 追従と最後の逃がし pass は、 `collectBBoxes` が含める下端の名札の箱上へのはみ出しと
|
|
377
389
|
// 縦列の題を同じ矩形で測る。 追従だけ箱本体で測ると、 置いた札を最後の pass が押し直す (#1002)。
|
|
378
|
-
const labelClearanceObstacles = collectBBoxes(
|
|
390
|
+
const labelClearanceObstacles = collectBBoxes(
|
|
391
|
+
containedLanesFinal,
|
|
392
|
+
nodesFinal,
|
|
393
|
+
[],
|
|
394
|
+
textMetrics,
|
|
395
|
+
).filter(
|
|
379
396
|
(b) => b.kind === "node" || b.kind === "lane-label",
|
|
380
397
|
);
|
|
381
|
-
followLabelsToFannedTails(edges, labelClearanceObstacles, fannedTailShifts);
|
|
382
|
-
repositionParallelLabels(edges, nodesFinal);
|
|
398
|
+
followLabelsToFannedTails(edges, labelClearanceObstacles, fannedTailShifts, textMetrics);
|
|
399
|
+
repositionParallelLabels(edges, nodesFinal, textMetrics);
|
|
383
400
|
// 縦にずらすだけでは逃げ場が無い札を、 自分の線に沿って動かす (#601)。 ここまでの
|
|
384
401
|
// 置き直しは全て縦方向で、 線に沿って動かす経路が無かった。 いま被っている札だけを
|
|
385
402
|
// 対象にするので、 落ち着いている図の座標は動かない。
|
|
386
|
-
slideLabelsAlongOwnPath(edges, nodesFinal);
|
|
403
|
+
slideLabelsAlongOwnPath(edges, nodesFinal, textMetrics);
|
|
387
404
|
// 経路を動かす pass が全て終わってから、 札を箱と札から離し直す (#659)。
|
|
388
405
|
//
|
|
389
406
|
// 上の chain 伝搬はここより前に走るため、 その後の経路 pass が動かした最終経路との隙間を
|
|
390
407
|
// ここで見直す。
|
|
391
408
|
// ここで動かすのは札だけで、 箱も経路も触らない = 触ると直前の pass が確定させた形を崩す。
|
|
392
409
|
if (!isChainEdgeLabelDisabled()) {
|
|
393
|
-
edges = resolveLabelClearanceAfterPathPasses(
|
|
410
|
+
edges = resolveLabelClearanceAfterPathPasses(
|
|
411
|
+
edges,
|
|
412
|
+
labelClearanceObstacles,
|
|
413
|
+
undefined,
|
|
414
|
+
textMetrics,
|
|
415
|
+
);
|
|
394
416
|
}
|
|
395
417
|
|
|
396
|
-
const bboxes = collectBBoxes(containedLanesFinal, nodesFinal, edges);
|
|
418
|
+
const bboxes = collectBBoxes(containedLanesFinal, nodesFinal, edges, textMetrics);
|
|
397
419
|
const collisions = detectCollisions(bboxes, edges);
|
|
398
420
|
const nearCollisions = detectNearCollisions(bboxes, edges);
|
|
399
421
|
|
|
@@ -436,6 +458,8 @@ export function layout(diag: CdlDiagram): LaidDiagram {
|
|
|
436
458
|
// 描画側の固定の字の言語 (#847)。 既定 (`en`) と型の外の値は持たせない = 配置の結果の形を
|
|
437
459
|
// 変更前と揃え、記法の書き損じで一部の字だけ日本語になる形を作らない
|
|
438
460
|
...(resolveLang(diag.lang) === "ja" ? { lang: "ja" as const } : {}),
|
|
461
|
+
// 既定は持ち越さない。既存の LaidDiagram の形を変えず、等幅の図だけ描画へ伝える
|
|
462
|
+
...(textMetrics === "monospace" ? { textMetrics: "monospace" as const } : {}),
|
|
439
463
|
// 種類も配色と同じく空の目印を出さない。 遮断をここに揃えると手書きの図にも効く
|
|
440
464
|
...(diag.type ? { type: diag.type } : {}),
|
|
441
465
|
bboxes,
|
package/src/presets.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { diagram } from "./builder";
|
|
2
2
|
import type { DiagramBuilder } from "./builder";
|
|
3
|
+
import { resolveTextMetrics } from "./text-metrics";
|
|
3
4
|
import { LANE_PAD_MIN, NODE_SIZE } from "./layout/tokens";
|
|
4
5
|
import { requiredRowsWidth } from "./kinds/row-align";
|
|
5
6
|
import { 木の札の幅 } from "./kinds/tree";
|
|
@@ -12,7 +13,12 @@ import {
|
|
|
12
13
|
type SequenceBoardMessage,
|
|
13
14
|
type SequenceBoardMessageKind,
|
|
14
15
|
} from "./kinds/sequence-board-metrics";
|
|
15
|
-
import type { NodeKind, Tone, EdgeStyle, EdgeHead, EdgeHeadFill, RowMark, JourneyEmotion, QuadrantKey, BoundNumber, EdgeRole } from "./types";
|
|
16
|
+
import type { CdlTextMetrics, NodeKind, Tone, EdgeStyle, EdgeHead, EdgeHeadFill, RowMark, JourneyEmotion, QuadrantKey, BoundNumber, EdgeRole } from "./types";
|
|
17
|
+
|
|
18
|
+
type TextMetricsPreset = {
|
|
19
|
+
/** 図の字幅を測る規則。省略時は `"proportional"` */
|
|
20
|
+
textMetrics?: CdlTextMetrics;
|
|
21
|
+
};
|
|
16
22
|
|
|
17
23
|
/**
|
|
18
24
|
* 状態を読む書き方 (`{名前}`)。
|
|
@@ -175,10 +181,14 @@ function resolveStorageBoxW(width: number | undefined, presetName: string, optio
|
|
|
175
181
|
* 指定値は下限として扱う。 「指定した幅より狭くならない」 は守り、 中身が入らない時だけ広げる。
|
|
176
182
|
* 例外にしない理由は、 著者が行の実寸を事前に計算できないため (font の送り幅に依存する)。
|
|
177
183
|
*/
|
|
178
|
-
function fitRowsWidth(
|
|
184
|
+
function fitRowsWidth(
|
|
185
|
+
boxW: number,
|
|
186
|
+
rows: readonly string[] | undefined,
|
|
187
|
+
textMetrics: CdlTextMetrics = "proportional",
|
|
188
|
+
): number {
|
|
179
189
|
// 呼出は `er` の実体と `classDiagram` のクラスの 2 箇所で、 どちらも `kind: "storage"` を作る。
|
|
180
190
|
// 送り幅と列間は種別で違うため、 どの種別として測るかを渡す
|
|
181
|
-
return Math.max(boxW, requiredRowsWidth(rows ? [...rows] : undefined, "storage"));
|
|
191
|
+
return Math.max(boxW, requiredRowsWidth(rows ? [...rows] : undefined, "storage", textMetrics));
|
|
182
192
|
}
|
|
183
193
|
|
|
184
194
|
/**
|
|
@@ -190,7 +200,7 @@ function fitRowsWidth(boxW: number, rows: readonly string[] | undefined): number
|
|
|
190
200
|
|
|
191
201
|
// ─── swimlane ──────────────────────────────────────────────────
|
|
192
202
|
|
|
193
|
-
export type SwimlanePreset = {
|
|
203
|
+
export type SwimlanePreset = TextMetricsPreset & {
|
|
194
204
|
id: string;
|
|
195
205
|
topic: string;
|
|
196
206
|
/** lane label の配列。 各 lane width は固定 (default 400)、 x は auto-layout */
|
|
@@ -218,7 +228,7 @@ export type SwimlaneResult = DiagramBuilder & {
|
|
|
218
228
|
|
|
219
229
|
export function swimlane(preset: SwimlanePreset): SwimlaneResult {
|
|
220
230
|
const w = preset.laneWidth ?? 400;
|
|
221
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "swimlane" });
|
|
231
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "swimlane" });
|
|
222
232
|
const labelToId = new Map<string, string>();
|
|
223
233
|
const idsInOrder: string[] = [];
|
|
224
234
|
for (const label of preset.lanes) {
|
|
@@ -247,7 +257,7 @@ export type FlowStepInput = {
|
|
|
247
257
|
subtitle?: string;
|
|
248
258
|
};
|
|
249
259
|
|
|
250
|
-
export type FlowPreset = {
|
|
260
|
+
export type FlowPreset = TextMetricsPreset & {
|
|
251
261
|
id: string;
|
|
252
262
|
topic: string;
|
|
253
263
|
/** lane label (1 本のみ、 全 step が縦 stack で並ぶ) */
|
|
@@ -298,7 +308,7 @@ export type FlowBuilder = {
|
|
|
298
308
|
*/
|
|
299
309
|
export function flow(preset: FlowPreset): FlowBuilder {
|
|
300
310
|
const w = preset.laneWidth ?? 400;
|
|
301
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "flow" });
|
|
311
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "flow" });
|
|
302
312
|
b.lane("flow", { width: w, ...(preset.laneLabel ? { label: preset.laneLabel } : {}) });
|
|
303
313
|
const tone: Tone = preset.defaultTone ?? "accent";
|
|
304
314
|
const style: EdgeStyle = preset.defaultStyle ?? "dotted-flow";
|
|
@@ -410,7 +420,7 @@ export type SequenceActor = {
|
|
|
410
420
|
subtitle?: string;
|
|
411
421
|
};
|
|
412
422
|
|
|
413
|
-
export type SequencePreset = {
|
|
423
|
+
export type SequencePreset = TextMetricsPreset & {
|
|
414
424
|
id: string;
|
|
415
425
|
topic: string;
|
|
416
426
|
/** actor label の配列 (lifeline、 column 単位)。 呼び名を添えるなら物で書く (#578) */
|
|
@@ -452,7 +462,7 @@ export type SequenceBuilder = {
|
|
|
452
462
|
*/
|
|
453
463
|
export function sequence(preset: SequencePreset): SequenceBuilder {
|
|
454
464
|
const tone: Tone = preset.defaultTone ?? "accent";
|
|
455
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "sequence" });
|
|
465
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "sequence" });
|
|
456
466
|
|
|
457
467
|
// 名前だけの文字列と、呼び名を添えた物の両方を受ける (#578)
|
|
458
468
|
const 面々: SequenceBoardActor[] = preset.actors.map((a) =>
|
|
@@ -501,7 +511,7 @@ export function sequence(preset: SequencePreset): SequenceBuilder {
|
|
|
501
511
|
.filter((x): x is SequenceBoardBand => x !== null);
|
|
502
512
|
|
|
503
513
|
const data: SequenceBoardData = { actors: 面々, messages: 言づて, bands: 帯 };
|
|
504
|
-
const m = sequenceBoardMetrics(data);
|
|
514
|
+
const m = sequenceBoardMetrics(data, resolveTextMetrics(preset.textMetrics));
|
|
505
515
|
const laneId = "seq";
|
|
506
516
|
b.lane(laneId, { width: m.w + LANE_PAD_MIN * 2 });
|
|
507
517
|
b.node(preset.id, {
|
|
@@ -548,7 +558,7 @@ export type TopologyConnection = {
|
|
|
548
558
|
labelOffsetY?: number;
|
|
549
559
|
};
|
|
550
560
|
|
|
551
|
-
export type TopologyPreset = {
|
|
561
|
+
export type TopologyPreset = TextMetricsPreset & {
|
|
552
562
|
id: string;
|
|
553
563
|
topic: string;
|
|
554
564
|
/** group の lane width (default 360) */
|
|
@@ -592,7 +602,7 @@ export function topology(preset: TopologyPreset): TopologyBuilder {
|
|
|
592
602
|
const groupW = preset.groupWidth ?? 460;
|
|
593
603
|
const tone: Tone = preset.defaultTone ?? "accent";
|
|
594
604
|
const style: EdgeStyle = preset.defaultStyle ?? "solid";
|
|
595
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "topology" });
|
|
605
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "topology" });
|
|
596
606
|
|
|
597
607
|
const groupOrder: string[] = [];
|
|
598
608
|
const groupStackCount = new Map<string, number>();
|
|
@@ -752,7 +762,7 @@ export type ErRelation = {
|
|
|
752
762
|
style?: EdgeStyle;
|
|
753
763
|
};
|
|
754
764
|
|
|
755
|
-
export type ErPreset = {
|
|
765
|
+
export type ErPreset = TextMetricsPreset & {
|
|
756
766
|
id: string;
|
|
757
767
|
topic: string;
|
|
758
768
|
defaultTone?: Tone;
|
|
@@ -804,7 +814,12 @@ export function er(preset: ErPreset): ErBuilder {
|
|
|
804
814
|
const tone: Tone = preset.defaultTone ?? "info";
|
|
805
815
|
const 縞を敷く = preset.rowStripe ?? true;
|
|
806
816
|
// 配色の名前は素通しする。 空文字の遮断は `diagram` が持つ = ここで重ねると到達しない分岐になる
|
|
807
|
-
const b = diagram(preset.id, {
|
|
817
|
+
const b = diagram(preset.id, {
|
|
818
|
+
topic: preset.topic,
|
|
819
|
+
palette: preset.palette,
|
|
820
|
+
textMetrics: preset.textMetrics,
|
|
821
|
+
type: "er",
|
|
822
|
+
});
|
|
808
823
|
|
|
809
824
|
const entities: string[] = [];
|
|
810
825
|
const phaseActivate: string[] = [];
|
|
@@ -834,7 +849,7 @@ export function er(preset: ErPreset): ErBuilder {
|
|
|
834
849
|
const rows = 設計の形 ? 行 : (e.rows ?? []);
|
|
835
850
|
// 帯は実体ごとに決める。 行の長さで箱が広がる実体があるため、 全実体を同じ帯幅で
|
|
836
851
|
// 宣言すると宣言座標と実座標がずれる。
|
|
837
|
-
const boxW = fitRowsWidth(entityW, rows);
|
|
852
|
+
const boxW = fitRowsWidth(entityW, rows, resolveTextMetrics(preset.textMetrics));
|
|
838
853
|
b.lane(laneId, { width: boxLaneW(boxW) });
|
|
839
854
|
b.node(e.id, {
|
|
840
855
|
lane: laneId,
|
|
@@ -986,7 +1001,7 @@ export type FsmTransition = {
|
|
|
986
1001
|
head?: EdgeHead;
|
|
987
1002
|
};
|
|
988
1003
|
|
|
989
|
-
export type StateMachinePreset = {
|
|
1004
|
+
export type StateMachinePreset = TextMetricsPreset & {
|
|
990
1005
|
id: string;
|
|
991
1006
|
topic: string;
|
|
992
1007
|
defaultTone?: Tone;
|
|
@@ -1033,7 +1048,7 @@ export function stateMachine(preset: StateMachinePreset): StateMachineBuilder {
|
|
|
1033
1048
|
const tone: Tone = preset.defaultTone ?? "accent";
|
|
1034
1049
|
// 図の型と最後の段の札は同じ綴り (#859)。 札を別の字にすると、消費側が型の一覧で引けない
|
|
1035
1050
|
const diagramType = "state";
|
|
1036
|
-
const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
|
|
1051
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
|
|
1037
1052
|
|
|
1038
1053
|
const phaseActivate: string[] = [];
|
|
1039
1054
|
const stateOrder = new Map<string, number>();
|
|
@@ -1078,7 +1093,9 @@ export function stateMachine(preset: StateMachinePreset): StateMachineBuilder {
|
|
|
1078
1093
|
const 行 = (s.actions ?? []).map((a) => (a.note ? `${a.label}: ${a.note}` : a.label));
|
|
1079
1094
|
const 印 = (s.actions ?? []).map((a) => FSM_ACTION_MARK[a.when]);
|
|
1080
1095
|
const laneId = 格子 && s.col !== undefined ? `col-${s.col}` : `lane-${s.id}`;
|
|
1081
|
-
const boxW = 設計の形
|
|
1096
|
+
const boxW = 設計の形
|
|
1097
|
+
? fitRowsWidth(stateW, 行, resolveTextMetrics(preset.textMetrics))
|
|
1098
|
+
: stateW;
|
|
1082
1099
|
return { s, 行, 印, laneId, boxW, stack: 格子 ? (s.row ?? 0) : 0 };
|
|
1083
1100
|
});
|
|
1084
1101
|
const 節点の中身 = 節点.map((m) => ({
|
|
@@ -1201,7 +1218,7 @@ export type InfraConnection = {
|
|
|
1201
1218
|
labelOffsetY?: number;
|
|
1202
1219
|
};
|
|
1203
1220
|
|
|
1204
|
-
export type InfrastructurePreset = {
|
|
1221
|
+
export type InfrastructurePreset = TextMetricsPreset & {
|
|
1205
1222
|
id: string;
|
|
1206
1223
|
topic: string;
|
|
1207
1224
|
/** col あたりの lane width (default 380) */
|
|
@@ -1239,7 +1256,11 @@ export function infrastructure(preset: InfrastructurePreset): InfrastructureBuil
|
|
|
1239
1256
|
const laneW = preset.laneWidth ?? 380;
|
|
1240
1257
|
const tone: Tone = preset.defaultTone ?? "accent";
|
|
1241
1258
|
const style: EdgeStyle = preset.defaultStyle ?? "solid";
|
|
1242
|
-
const b = diagram(preset.id, {
|
|
1259
|
+
const b = diagram(preset.id, {
|
|
1260
|
+
topic: preset.topic,
|
|
1261
|
+
textMetrics: preset.textMetrics,
|
|
1262
|
+
type: "infrastructure",
|
|
1263
|
+
});
|
|
1243
1264
|
|
|
1244
1265
|
// col → laneId、 col の数で lane を auto 作成
|
|
1245
1266
|
const colLaneIds = new Map<number, string>();
|
|
@@ -1452,7 +1473,7 @@ export type UmlRelation = {
|
|
|
1452
1473
|
style?: EdgeStyle;
|
|
1453
1474
|
};
|
|
1454
1475
|
|
|
1455
|
-
export type ClassDiagramPreset = {
|
|
1476
|
+
export type ClassDiagramPreset = TextMetricsPreset & {
|
|
1456
1477
|
id: string;
|
|
1457
1478
|
topic: string;
|
|
1458
1479
|
defaultTone?: Tone;
|
|
@@ -1503,7 +1524,12 @@ export function classDiagram(preset: ClassDiagramPreset): ClassDiagramBuilder {
|
|
|
1503
1524
|
const 図の既定 = preset.defaultTone;
|
|
1504
1525
|
// 縞と配色は `er()` と同じ扱い (#627)。 箱の作りが同じなので、既定も揃える
|
|
1505
1526
|
const 縞を敷く = preset.rowStripe ?? true;
|
|
1506
|
-
const b = diagram(preset.id, {
|
|
1527
|
+
const b = diagram(preset.id, {
|
|
1528
|
+
topic: preset.topic,
|
|
1529
|
+
palette: preset.palette,
|
|
1530
|
+
textMetrics: preset.textMetrics,
|
|
1531
|
+
type: "class",
|
|
1532
|
+
});
|
|
1507
1533
|
|
|
1508
1534
|
const classes: string[] = [];
|
|
1509
1535
|
const phaseActivate: string[] = [];
|
|
@@ -1537,7 +1563,7 @@ export function classDiagram(preset: ClassDiagramPreset): ClassDiagramBuilder {
|
|
|
1537
1563
|
}
|
|
1538
1564
|
// 帯はクラスごとに決める。 行の長さで箱が広がるクラスがあるため、 全クラスを同じ帯幅で
|
|
1539
1565
|
// 宣言すると宣言座標と実座標がずれる。
|
|
1540
|
-
const boxW = fitRowsWidth(classW, rows);
|
|
1566
|
+
const boxW = fitRowsWidth(classW, rows, resolveTextMetrics(preset.textMetrics));
|
|
1541
1567
|
// 格子に置くかは `col` を書いたかで決める (#578)。 書かない図は従来どおり横 1 列
|
|
1542
1568
|
const laneId = c.col !== undefined ? `col-${c.col}` : `lane-${c.id}`;
|
|
1543
1569
|
return { c, rows, rowMarks, boxW, laneId, stack: c.col !== undefined ? (c.row ?? 0) : 0 };
|
|
@@ -1619,7 +1645,7 @@ export type TreeNode = {
|
|
|
1619
1645
|
subtitle?: string;
|
|
1620
1646
|
};
|
|
1621
1647
|
|
|
1622
|
-
export type TreePreset = {
|
|
1648
|
+
export type TreePreset = TextMetricsPreset & {
|
|
1623
1649
|
id: string;
|
|
1624
1650
|
topic: string;
|
|
1625
1651
|
/** 図の題の上に出す小見出し (#939)。 書かなければ何も出ない */
|
|
@@ -1649,7 +1675,7 @@ export type TreeBuilder = {
|
|
|
1649
1675
|
*/
|
|
1650
1676
|
export function tree(preset: TreePreset): TreeBuilder {
|
|
1651
1677
|
const canvasH = 480;
|
|
1652
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "tree" });
|
|
1678
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "tree" });
|
|
1653
1679
|
const treeNodes: TreeNode[] = [];
|
|
1654
1680
|
|
|
1655
1681
|
const api: TreeBuilder = {
|
|
@@ -1708,7 +1734,7 @@ export type JourneyStep = {
|
|
|
1708
1734
|
opportunity?: string;
|
|
1709
1735
|
};
|
|
1710
1736
|
|
|
1711
|
-
export type UserJourneyPreset = {
|
|
1737
|
+
export type UserJourneyPreset = TextMetricsPreset & {
|
|
1712
1738
|
id: string;
|
|
1713
1739
|
topic: string;
|
|
1714
1740
|
/** 図の題の上に出す小見出し (#939)。 書かなければ何も出ない */
|
|
@@ -1737,7 +1763,7 @@ export type UserJourneyBuilder = {
|
|
|
1737
1763
|
export function userJourney(preset: UserJourneyPreset): UserJourneyBuilder {
|
|
1738
1764
|
const canvasW = preset.stepWidth ? preset.stepWidth * 2 : 720;
|
|
1739
1765
|
const canvasH = 480;
|
|
1740
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "journey" });
|
|
1766
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "journey" });
|
|
1741
1767
|
const steps: JourneyStep[] = [];
|
|
1742
1768
|
|
|
1743
1769
|
const api: UserJourneyBuilder = {
|
|
@@ -1788,7 +1814,7 @@ export type MindBranch = {
|
|
|
1788
1814
|
subtitle?: string;
|
|
1789
1815
|
};
|
|
1790
1816
|
|
|
1791
|
-
export type MindMapPreset = {
|
|
1817
|
+
export type MindMapPreset = TextMetricsPreset & {
|
|
1792
1818
|
id: string;
|
|
1793
1819
|
topic: string;
|
|
1794
1820
|
/** 図の題の上に出す小見出し (#939)。 書かなければ何も出ない */
|
|
@@ -1825,7 +1851,7 @@ export function mindMap(preset: MindMapPreset): MindMapBuilder {
|
|
|
1825
1851
|
// 型は他の組み立て関数と同じく短い名前 (`state` / `class` / `journey` と並ぶ `mind`)。
|
|
1826
1852
|
// 最後の段の札も同じ綴り (#859)
|
|
1827
1853
|
const diagramType = "mind";
|
|
1828
|
-
const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
|
|
1854
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
|
|
1829
1855
|
const branches: MindBranch[] = [];
|
|
1830
1856
|
|
|
1831
1857
|
const api: MindMapBuilder = {
|
|
@@ -1880,7 +1906,7 @@ export type FunnelStage = {
|
|
|
1880
1906
|
subtitle?: string;
|
|
1881
1907
|
};
|
|
1882
1908
|
|
|
1883
|
-
export type FunnelPreset = {
|
|
1909
|
+
export type FunnelPreset = TextMetricsPreset & {
|
|
1884
1910
|
id: string;
|
|
1885
1911
|
topic: string;
|
|
1886
1912
|
/** 図の題の上に出す小見出し (#939)。 書かなければ何も出ない */
|
|
@@ -1909,7 +1935,7 @@ export type FunnelBuilder = {
|
|
|
1909
1935
|
export function funnel(preset: FunnelPreset): FunnelBuilder {
|
|
1910
1936
|
const canvasW = toGridSize(preset.stageWidth ?? 560);
|
|
1911
1937
|
const canvasH = 480;
|
|
1912
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "funnel" });
|
|
1938
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "funnel" });
|
|
1913
1939
|
const stages: FunnelStage[] = [];
|
|
1914
1940
|
|
|
1915
1941
|
const api: FunnelBuilder = {
|
|
@@ -1961,7 +1987,7 @@ export type QuadrantItem = {
|
|
|
1961
1987
|
subtitle?: string;
|
|
1962
1988
|
};
|
|
1963
1989
|
|
|
1964
|
-
export type QuadrantPreset = {
|
|
1990
|
+
export type QuadrantPreset = TextMetricsPreset & {
|
|
1965
1991
|
id: string;
|
|
1966
1992
|
topic: string;
|
|
1967
1993
|
/** 図の題の上に出す小見出し (#939)。 書かなければ何も出ない */
|
|
@@ -1998,7 +2024,7 @@ export type QuadrantBuilder = {
|
|
|
1998
2024
|
export function quadrant(preset: QuadrantPreset): QuadrantBuilder {
|
|
1999
2025
|
const canvasW = 640;
|
|
2000
2026
|
const canvasH = 480;
|
|
2001
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "quadrant" });
|
|
2027
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "quadrant" });
|
|
2002
2028
|
const items: QuadrantItem[] = [];
|
|
2003
2029
|
|
|
2004
2030
|
const api: QuadrantBuilder = {
|
|
@@ -2071,7 +2097,7 @@ export type ChartDatum = {
|
|
|
2071
2097
|
tone?: Tone;
|
|
2072
2098
|
};
|
|
2073
2099
|
|
|
2074
|
-
export type ChartPreset = {
|
|
2100
|
+
export type ChartPreset = TextMetricsPreset & {
|
|
2075
2101
|
id: string;
|
|
2076
2102
|
topic: string;
|
|
2077
2103
|
/** 図の題の上に出す小見出し (#939)。 書かなければ何も出ない */
|
|
@@ -2115,7 +2141,7 @@ export function chart(preset: ChartPreset): ChartBuilder {
|
|
|
2115
2141
|
? 320
|
|
2116
2142
|
: 360,
|
|
2117
2143
|
);
|
|
2118
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "chart" });
|
|
2144
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "chart" });
|
|
2119
2145
|
const data: ChartDatum[] = [];
|
|
2120
2146
|
|
|
2121
2147
|
const kindMap = {
|
|
@@ -2186,7 +2212,7 @@ export type GanttTask = {
|
|
|
2186
2212
|
dependsOn?: string;
|
|
2187
2213
|
};
|
|
2188
2214
|
|
|
2189
|
-
export type GanttPreset = {
|
|
2215
|
+
export type GanttPreset = TextMetricsPreset & {
|
|
2190
2216
|
id: string;
|
|
2191
2217
|
topic: string;
|
|
2192
2218
|
/** 図の題の上に出す小見出し (#939)。 書かなければ何も出ない */
|
|
@@ -2229,7 +2255,7 @@ export function gantt(preset: GanttPreset): GanttBuilder {
|
|
|
2229
2255
|
const canvasW = preset.laneWidth ? preset.laneWidth * 2 : 720;
|
|
2230
2256
|
const canvasH = 360;
|
|
2231
2257
|
const tone: Tone = preset.defaultTone ?? "teal";
|
|
2232
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "gantt" });
|
|
2258
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "gantt" });
|
|
2233
2259
|
const tasks: GanttTask[] = [];
|
|
2234
2260
|
|
|
2235
2261
|
const api: GanttBuilder = {
|
|
@@ -2319,7 +2345,7 @@ export type FlowchartEdge = {
|
|
|
2319
2345
|
*/
|
|
2320
2346
|
export type FlowchartDirection = "horizontal" | "vertical";
|
|
2321
2347
|
|
|
2322
|
-
export type FlowchartPreset = {
|
|
2348
|
+
export type FlowchartPreset = TextMetricsPreset & {
|
|
2323
2349
|
id: string;
|
|
2324
2350
|
topic: string;
|
|
2325
2351
|
/** swimlane の lane (role) ラベル */
|
|
@@ -2378,7 +2404,7 @@ export function flowchart(preset: FlowchartPreset): FlowchartBuilder {
|
|
|
2378
2404
|
const laneW = preset.laneWidth ?? 380;
|
|
2379
2405
|
const tone: Tone = preset.defaultTone ?? "accent";
|
|
2380
2406
|
const 縦に積む = (preset.direction ?? "horizontal") === "vertical";
|
|
2381
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "flowchart" });
|
|
2407
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "flowchart" });
|
|
2382
2408
|
|
|
2383
2409
|
const laneToId = new Map<string, string>();
|
|
2384
2410
|
const laneStackCount = new Map<string, number>();
|
|
@@ -2488,7 +2514,7 @@ export type NetworkLink = {
|
|
|
2488
2514
|
tone?: Tone;
|
|
2489
2515
|
};
|
|
2490
2516
|
|
|
2491
|
-
export type NetworkPreset = {
|
|
2517
|
+
export type NetworkPreset = TextMetricsPreset & {
|
|
2492
2518
|
id: string;
|
|
2493
2519
|
topic: string;
|
|
2494
2520
|
defaultTone?: Tone;
|
|
@@ -2534,7 +2560,7 @@ const NET_KIND_LABEL: Record<NetworkDeviceKind, string> = {
|
|
|
2534
2560
|
export function network(preset: NetworkPreset): NetworkBuilder {
|
|
2535
2561
|
const laneW = preset.laneWidth ?? 320;
|
|
2536
2562
|
const tone: Tone = preset.defaultTone ?? "info";
|
|
2537
|
-
const b = diagram(preset.id, { topic: preset.topic, type: "network" });
|
|
2563
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: "network" });
|
|
2538
2564
|
|
|
2539
2565
|
const colLaneIds = new Map<number, string>();
|
|
2540
2566
|
const phaseActivate: string[] = [];
|
|
@@ -2609,7 +2635,7 @@ export type FsmTransitionExt = {
|
|
|
2609
2635
|
tone?: Tone;
|
|
2610
2636
|
};
|
|
2611
2637
|
|
|
2612
|
-
export type StateMachine2Preset = {
|
|
2638
|
+
export type StateMachine2Preset = TextMetricsPreset & {
|
|
2613
2639
|
id: string;
|
|
2614
2640
|
topic: string;
|
|
2615
2641
|
defaultTone?: Tone;
|
|
@@ -2653,7 +2679,7 @@ export function stateMachine2(preset: StateMachine2Preset): StateMachine2Builder
|
|
|
2653
2679
|
const tone: Tone = preset.defaultTone ?? "accent";
|
|
2654
2680
|
// 入れ子を持つ状態の図も型は `state`。 最後の段の札も同じ綴りで、1 つ目の図との見分けは題が持つ (#859)
|
|
2655
2681
|
const diagramType = "state";
|
|
2656
|
-
const b = diagram(preset.id, { topic: preset.topic, type: diagramType });
|
|
2682
|
+
const b = diagram(preset.id, { topic: preset.topic, textMetrics: preset.textMetrics, type: diagramType });
|
|
2657
2683
|
|
|
2658
2684
|
const stateOrder = new Map<string, number>();
|
|
2659
2685
|
const phaseActivate: string[] = [];
|