@cardenelabs/cdl 0.70.0 → 0.71.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cardenelabs/cdl",
3
- "version": "0.70.0",
3
+ "version": "0.71.0",
4
4
  "description": "CDL (Chainome Diagram Language). Mermaid-like declarative DSL that compiles to animated SVG diagrams. Built for blockchain / Solidity flows, generic enough for sequence / flow / state / ER / topology diagrams.",
5
5
  "license": "MIT",
6
6
  "author": "cardene777",
package/src/index.ts CHANGED
@@ -277,6 +277,7 @@ export type {
277
277
  FlowchartNode,
278
278
  FlowchartEdge,
279
279
  FlowchartNodeShape,
280
+ FlowchartDirection,
280
281
  NetworkPreset,
281
282
  NetworkBuilder,
282
283
  NetworkDevice,
package/src/presets.ts CHANGED
@@ -2289,6 +2289,18 @@ export type FlowchartEdge = {
2289
2289
  tone?: Tone;
2290
2290
  };
2291
2291
 
2292
+ /**
2293
+ * 分かれ道の図を並べる向き (#880)。
2294
+ *
2295
+ * - `"horizontal"` (既定) ... 縦列を横に並べ、箱をその中に上から積む。 役割は縦列の見出しに出る
2296
+ * - `"vertical"` ... 縦列 1 本に全部の箱を書いた順で積む。 役割は箱の上の小さな字に移す
2297
+ *
2298
+ * **縦列を横の帯にして縦に積む形は持たない**。 配置は格子で、縦列が横の位置を、段が縦の
2299
+ * 位置を決める (`layout/nodes.ts`)。 帯にするには軸の入れ替えが要り、入口の option では
2300
+ * 足りない。
2301
+ */
2302
+ export type FlowchartDirection = "horizontal" | "vertical";
2303
+
2292
2304
  export type FlowchartPreset = {
2293
2305
  id: string;
2294
2306
  topic: string;
@@ -2296,6 +2308,8 @@ export type FlowchartPreset = {
2296
2308
  lanes: string[];
2297
2309
  defaultTone?: Tone;
2298
2310
  laneWidth?: number;
2311
+ /** 並べる向き (既定 = `"horizontal"`、 今までの並び) */
2312
+ direction?: FlowchartDirection;
2299
2313
  };
2300
2314
 
2301
2315
  export type FlowchartBuilder = {
@@ -2339,32 +2353,57 @@ const SHAPE_EYEBROW: Record<FlowchartNodeShape, string> = {
2339
2353
  * .edge({ from: "review", to: "revise", label: "false" })
2340
2354
  * .build();
2341
2355
  */
2356
+ /** 縦に積む時に使う 1 本だけの縦列の id (#880) */
2357
+ const VERTICAL_LANE_ID = "flowchart-main";
2358
+
2342
2359
  export function flowchart(preset: FlowchartPreset): FlowchartBuilder {
2343
2360
  const laneW = preset.laneWidth ?? 380;
2344
2361
  const tone: Tone = preset.defaultTone ?? "accent";
2362
+ const 縦に積む = (preset.direction ?? "horizontal") === "vertical";
2345
2363
  const b = diagram(preset.id, { topic: preset.topic, type: "flowchart" });
2346
2364
 
2347
2365
  const laneToId = new Map<string, string>();
2348
2366
  const laneStackCount = new Map<string, number>();
2349
- for (const label of preset.lanes) {
2350
- const id = slugify(label) || `lane-${laneToId.size}`;
2351
- laneToId.set(label, id);
2352
- laneStackCount.set(id, 0);
2353
- b.lane(id, { width: laneW, label });
2367
+ if (縦に積む) {
2368
+ /*
2369
+ * 縦列を 1 本だけ置く (#880)。
2370
+ *
2371
+ * 見出しは付けない = 役割が 1 つに畳まれるので、どれか 1 つの名前を見出しにすると
2372
+ * 他の役割の箱にもその名前が掛かって読める。 役割は箱ごとの小さな字が持つ。
2373
+ */
2374
+ b.lane(VERTICAL_LANE_ID, { width: laneW });
2375
+ laneStackCount.set(VERTICAL_LANE_ID, 0);
2376
+ } else {
2377
+ for (const label of preset.lanes) {
2378
+ const id = slugify(label) || `lane-${laneToId.size}`;
2379
+ laneToId.set(label, id);
2380
+ laneStackCount.set(id, 0);
2381
+ b.lane(id, { width: laneW, label });
2382
+ }
2354
2383
  }
2355
2384
  const phaseActivate: string[] = [];
2356
2385
  let edgeIdx = 0;
2357
2386
 
2387
+ /*
2388
+ * 箱の上に出す字。
2389
+ *
2390
+ * 縦に積む図で役割を 2 つ以上書いた時だけ、形の名前の前に役割を足す。
2391
+ * 1 つしか書いていない図は足さない = 全部の箱に同じ字が並ぶだけで、読む材料が増えない。
2392
+ */
2393
+ const 役割を足す = 縦に積む && preset.lanes.length >= 2;
2394
+ const 箱の上の字 = (n: FlowchartNode): string =>
2395
+ 役割を足す ? `${n.lane} · ${SHAPE_EYEBROW[n.shape]}` : SHAPE_EYEBROW[n.shape];
2396
+
2358
2397
  const api: FlowchartBuilder = {
2359
2398
  node(n) {
2360
- const laneId = laneToId.get(n.lane) ?? n.lane;
2399
+ const laneId = 縦に積む ? VERTICAL_LANE_ID : (laneToId.get(n.lane) ?? n.lane);
2361
2400
  const stack = laneStackCount.get(laneId) ?? 0;
2362
2401
  b.node(n.id, {
2363
2402
  lane: laneId,
2364
2403
  stack,
2365
2404
  kind: SHAPE_KIND[n.shape],
2366
2405
  title: n.title,
2367
- eyebrow: SHAPE_EYEBROW[n.shape],
2406
+ eyebrow: 箱の上の字(n),
2368
2407
  });
2369
2408
  laneStackCount.set(laneId, stack + 1);
2370
2409
  phaseActivate.push(n.id);