@cardenelabs/cdl 0.30.3 → 0.31.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/dist/index.cjs CHANGED
@@ -22383,8 +22383,300 @@ function StateDiffCard({
22383
22383
  }
22384
22384
  );
22385
22385
  }
22386
+ var \u6570\u3092\u66F8\u304F = (value) => value.toLocaleString("en-US", { maximumFractionDigits: 12 });
22387
+ function \u6298\u308C\u7DDA\u306E\u76EE\u76DB(values) {
22388
+ let rawMin = values.length > 0 ? Math.min(...values) : 0;
22389
+ let rawMax = values.length > 0 ? Math.max(...values) : 1;
22390
+ if (rawMin === rawMax) {
22391
+ const room = 10 ** Math.floor(Math.log10(Math.abs(rawMin) || 1) - 1);
22392
+ rawMin -= room;
22393
+ rawMax += room;
22394
+ }
22395
+ const roughStep = (rawMax - rawMin) / 4;
22396
+ const power = 10 ** Math.floor(Math.log10(roughStep));
22397
+ const fraction = roughStep / power;
22398
+ const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10;
22399
+ const step = niceFraction * power;
22400
+ const min = Math.floor(rawMin / step) * step;
22401
+ const max = Math.ceil(rawMax / step) * step;
22402
+ const tickCount = Math.round((max - min) / step);
22403
+ const ticks = Array.from({ length: tickCount + 1 }, (_, i) => {
22404
+ const value = min + step * i;
22405
+ return Math.abs(value) < step * 1e-12 ? 0 : value;
22406
+ });
22407
+ return { min, max, ticks };
22408
+ }
22409
+ function ChartLineNode({
22410
+ node,
22411
+ active,
22412
+ stateValues = {},
22413
+ scale: fixedScale,
22414
+ drawing = false,
22415
+ progress = 1
22416
+ }) {
22417
+ const x0 = node.cx - node.w / 2;
22418
+ const y0 = node.cy - node.h / 2;
22419
+ const data = resolveChartData(node.chartData ?? [], stateValues);
22420
+ const PAD_TOP2 = 36;
22421
+ const PAD_RIGHT2 = 40;
22422
+ const PAD_BOTTOM2 = 56;
22423
+ const PAD_LEFT2 = 72;
22424
+ const canvasW = node.w - PAD_LEFT2 - PAD_RIGHT2;
22425
+ const canvasH = node.h - PAD_TOP2 - PAD_BOTTOM2;
22426
+ const scale = fixedScale ?? \u6298\u308C\u7DDA\u306E\u76EE\u76DB(data.map((d) => d.value));
22427
+ const vRange = scale.max - scale.min;
22428
+ const LABEL_ROOM = 20;
22429
+ const plotTop = PAD_TOP2 + LABEL_ROOM;
22430
+ const plotH = Math.max(canvasH - LABEL_ROOM * 2, 1);
22431
+ const POINT_EDGE_ROOM = 24;
22432
+ const plotW = Math.max(canvasW - POINT_EDGE_ROOM * 2, 1);
22433
+ const xAt = (idx) => PAD_LEFT2 + POINT_EDGE_ROOM + (data.length <= 1 ? plotW / 2 : plotW * idx / (data.length - 1));
22434
+ const yAt = (v) => plotTop + plotH - (v - scale.min) / vRange * plotH;
22435
+ const plotBottom = PAD_TOP2 + canvasH;
22436
+ let \u7DDA\u306E\u5168\u9577 = 0;
22437
+ let \u524D\u306E\u70B9;
22438
+ const \u63CF\u753B\u70B9 = data.map((datum, idx) => {
22439
+ const \u4ECA\u306E\u70B9 = { datum, x: xAt(idx), y: yAt(datum.value), \u3053\u3053\u307E\u3067\u306E\u9577\u3055: 0 };
22440
+ if (\u524D\u306E\u70B9) {
22441
+ \u7DDA\u306E\u5168\u9577 += Math.hypot(\u4ECA\u306E\u70B9.x - \u524D\u306E\u70B9.x, \u4ECA\u306E\u70B9.y - \u524D\u306E\u70B9.y);
22442
+ }
22443
+ \u4ECA\u306E\u70B9.\u3053\u3053\u307E\u3067\u306E\u9577\u3055 = \u7DDA\u306E\u5168\u9577;
22444
+ \u524D\u306E\u70B9 = \u4ECA\u306E\u70B9;
22445
+ return \u4ECA\u306E\u70B9;
22446
+ });
22447
+ const points = \u63CF\u753B\u70B9.map((\u70B9) => `${\u70B9.x},${\u70B9.y}`).join(" ");
22448
+ const \u6BB5\u306E\u9032\u307F = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
22449
+ const \u7C92\u3092\u8D70\u3089\u305B\u308B = drawing && node.chartTrace === true;
22450
+ const \u4F38\u3073 = \u7C92\u3092\u8D70\u3089\u305B\u308B ? Math.min(1, \u6BB5\u306E\u9032\u307F / 0.5) : \u6BB5\u306E\u9032\u307F;
22451
+ const \u7C92\u306E\u9032\u307F = \u7C92\u3092\u8D70\u3089\u305B\u308B ? Math.min(1, Math.max(0, (\u6BB5\u306E\u9032\u307F - 0.55) / 0.45)) : \u4F38\u3073;
22452
+ const \u7C92\u304C\u51FA\u308B = \u7C92\u3092\u8D70\u3089\u305B\u308B && \u6BB5\u306E\u9032\u307F >= 0.55 && \u6BB5\u306E\u9032\u307F < 1;
22453
+ const \u5230\u7740\u7A93 = 0.12;
22454
+ let \u7C92\u306E\u4F4D\u7F6E;
22455
+ const \u6700\u521D\u306E\u70B9 = \u63CF\u753B\u70B9[0];
22456
+ if (\u7C92\u304C\u51FA\u308B && \u6700\u521D\u306E\u70B9) {
22457
+ const \u7C92\u307E\u3067\u306E\u9577\u3055 = \u7C92\u306E\u9032\u307F * \u7DDA\u306E\u5168\u9577;
22458
+ let \u533A\u9593\u306E\u524D = \u6700\u521D\u306E\u70B9;
22459
+ let \u533A\u9593\u306E\u5F8C = \u6700\u521D\u306E\u70B9;
22460
+ for (const \u70B9 of \u63CF\u753B\u70B9.slice(1)) {
22461
+ \u533A\u9593\u306E\u5F8C = \u70B9;
22462
+ if (\u70B9.\u3053\u3053\u307E\u3067\u306E\u9577\u3055 >= \u7C92\u307E\u3067\u306E\u9577\u3055) break;
22463
+ \u533A\u9593\u306E\u524D = \u70B9;
22464
+ }
22465
+ const \u533A\u9593\u306E\u59CB\u3081 = \u533A\u9593\u306E\u524D.\u3053\u3053\u307E\u3067\u306E\u9577\u3055;
22466
+ const \u533A\u9593\u306E\u9577\u3055 = \u533A\u9593\u306E\u5F8C.\u3053\u3053\u307E\u3067\u306E\u9577\u3055 - \u533A\u9593\u306E\u59CB\u3081;
22467
+ const \u533A\u9593\u306E\u9032\u307F = \u533A\u9593\u306E\u9577\u3055 === 0 ? 0 : (\u7C92\u307E\u3067\u306E\u9577\u3055 - \u533A\u9593\u306E\u59CB\u3081) / \u533A\u9593\u306E\u9577\u3055;
22468
+ \u7C92\u306E\u4F4D\u7F6E = {
22469
+ x: \u533A\u9593\u306E\u524D.x + (\u533A\u9593\u306E\u5F8C.x - \u533A\u9593\u306E\u524D.x) * \u533A\u9593\u306E\u9032\u307F,
22470
+ y: \u533A\u9593\u306E\u524D.y + (\u533A\u9593\u306E\u5F8C.y - \u533A\u9593\u306E\u524D.y) * \u533A\u9593\u306E\u9032\u307F
22471
+ };
22472
+ }
22473
+ const gridTicks = scale.ticks.map((value) => ({ y: yAt(value), value }));
22474
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
22475
+ gridTicks.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
22476
+ /* @__PURE__ */ jsxRuntime.jsx(
22477
+ "line",
22478
+ {
22479
+ x1: PAD_LEFT2,
22480
+ y1: t.y,
22481
+ x2: PAD_LEFT2 + canvasW,
22482
+ y2: t.y,
22483
+ stroke: "var(--cdl-divider, #d4d4d8)",
22484
+ strokeWidth: 0.75,
22485
+ strokeDasharray: "3 3",
22486
+ opacity: 0.65
22487
+ }
22488
+ ),
22489
+ /* @__PURE__ */ jsxRuntime.jsx(
22490
+ "text",
22491
+ {
22492
+ x: PAD_LEFT2 - 8,
22493
+ y: t.y + 4,
22494
+ fontSize: 11,
22495
+ textAnchor: "end",
22496
+ fill: "var(--cdl-text-dim, #5a6270)",
22497
+ children: \u6570\u3092\u66F8\u304F(t.value)
22498
+ }
22499
+ )
22500
+ ] }, `grid-${i}`)),
22501
+ node.chartFillUnder && data.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
22502
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
22503
+ "linearGradient",
22504
+ {
22505
+ id: `chart-line-fill-${node.id}`,
22506
+ gradientUnits: "userSpaceOnUse",
22507
+ x1: 0,
22508
+ y1: plotTop,
22509
+ x2: 0,
22510
+ y2: plotBottom,
22511
+ children: [
22512
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: "var(--cdl-tone-accent, #2d6a8f)", stopOpacity: 0.22 }),
22513
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: "var(--cdl-tone-accent, #2d6a8f)", stopOpacity: 0 })
22514
+ ]
22515
+ }
22516
+ ) }),
22517
+ /* @__PURE__ */ jsxRuntime.jsx(
22518
+ "path",
22519
+ {
22520
+ "data-cdl-role": "chart-line-fill-under",
22521
+ d: `M ${xAt(0)} ${plotBottom} L ${points.replaceAll(",", " ")} L ${xAt(data.length - 1)} ${plotBottom} Z`,
22522
+ fill: `url(#chart-line-fill-${node.id})`,
22523
+ stroke: "none"
22524
+ }
22525
+ )
22526
+ ] }),
22527
+ data.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
22528
+ "polyline",
22529
+ {
22530
+ "data-cdl-role": "chart-line",
22531
+ points,
22532
+ fill: "none",
22533
+ stroke: "var(--cdl-tone-accent, #2d6a8f)",
22534
+ strokeWidth: active ? 3 : 2,
22535
+ strokeLinejoin: "round",
22536
+ strokeLinecap: "round",
22537
+ ...\u4F38\u3070\u3059dash(drawing, \u4F38\u3073)
22538
+ }
22539
+ ),
22540
+ \u7C92\u306E\u4F4D\u7F6E && /* @__PURE__ */ jsxRuntime.jsx(
22541
+ "circle",
22542
+ {
22543
+ "data-cdl-role": "chart-line-trace",
22544
+ cx: \u7C92\u306E\u4F4D\u7F6E.x,
22545
+ cy: \u7C92\u306E\u4F4D\u7F6E.y,
22546
+ r: 4.5,
22547
+ fill: "var(--cdl-now)"
22548
+ }
22549
+ ),
22550
+ \u63CF\u753B\u70B9.map(({ datum: d, x: cx, y: cy, \u3053\u3053\u307E\u3067\u306E\u9577\u3055 }, idx) => {
22551
+ const prev = data[idx - 1]?.value;
22552
+ const next = data[idx + 1]?.value;
22553
+ const isValley = (prev === void 0 || d.value <= prev) && (next === void 0 || d.value <= next);
22554
+ const labelAbove = !isValley;
22555
+ const labelY = labelAbove ? cy - 12 : cy + 18;
22556
+ const \u5230\u7740\u5F8C = \u7DDA\u306E\u5168\u9577 === 0 ? \u7C92\u306E\u9032\u307F : \u7C92\u306E\u9032\u307F - \u3053\u3053\u307E\u3067\u306E\u9577\u3055 / \u7DDA\u306E\u5168\u9577;
22557
+ const \u51FA\u3059 = !drawing || (!\u7C92\u3092\u8D70\u3089\u305B\u308B || \u6BB5\u306E\u9032\u307F >= 0.55) && \u5230\u7740\u5F8C >= 0;
22558
+ const \u5149\u308B = drawing && \u51FA\u3059 && \u5230\u7740\u5F8C < \u5230\u7740\u7A93;
22559
+ const \u5149\u306E\u9032\u307F = \u5149\u308B ? \u5230\u7740\u5F8C / \u5230\u7740\u7A93 : 1;
22560
+ let \u70B9\u3068\u5024;
22561
+ if (\u51FA\u3059) {
22562
+ const \u5149\u306E\u534A\u5F84 = 6 + 16 * \u5149\u306E\u9032\u307F;
22563
+ const \u5024 = /* @__PURE__ */ jsxRuntime.jsx(
22564
+ "text",
22565
+ {
22566
+ "data-cdl-role": "chart-line-value",
22567
+ x: cx,
22568
+ y: labelY,
22569
+ fontSize: 11,
22570
+ fontWeight: 600,
22571
+ textAnchor: "middle",
22572
+ fill: "var(--cdl-text, #1a1f2a)",
22573
+ children: \u6570\u3092\u66F8\u304F(d.value)
22574
+ }
22575
+ );
22576
+ \u70B9\u3068\u5024 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
22577
+ \u5149\u308B && // marker の `circle` を数える利用側へ混ぜず、専用 role の等径 ellipse として輪を出す。
22578
+ /* @__PURE__ */ jsxRuntime.jsx(
22579
+ "ellipse",
22580
+ {
22581
+ "data-cdl-role": "chart-line-arrival-ring",
22582
+ cx,
22583
+ cy,
22584
+ rx: \u5149\u306E\u534A\u5F84,
22585
+ ry: \u5149\u306E\u534A\u5F84,
22586
+ fill: "none",
22587
+ stroke: "var(--cdl-now)",
22588
+ strokeWidth: 2,
22589
+ opacity: 0.85 * (1 - \u5149\u306E\u9032\u307F)
22590
+ }
22591
+ ),
22592
+ /* @__PURE__ */ jsxRuntime.jsx(
22593
+ "circle",
22594
+ {
22595
+ cx,
22596
+ cy,
22597
+ r: 5,
22598
+ fill: "var(--cdl-node-fill, #ffffff)",
22599
+ stroke: \u5149\u308B ? "var(--cdl-now)" : "var(--cdl-tone-accent, #2d6a8f)",
22600
+ strokeWidth: 2.5
22601
+ }
22602
+ ),
22603
+ /* @__PURE__ */ jsxRuntime.jsx(
22604
+ "circle",
22605
+ {
22606
+ cx,
22607
+ cy,
22608
+ r: 2.5,
22609
+ fill: \u5149\u308B ? "var(--cdl-now)" : "var(--cdl-tone-accent, #2d6a8f)"
22610
+ }
22611
+ ),
22612
+ node.chartValueRise && \u5149\u308B ? /* @__PURE__ */ jsxRuntime.jsx(
22613
+ "g",
22614
+ {
22615
+ "data-cdl-role": "chart-line-value-rise",
22616
+ transform: `translate(0 ${8 * (1 - \u5149\u306E\u9032\u307F)})`,
22617
+ children: \u5024
22618
+ }
22619
+ ) : \u5024
22620
+ ] });
22621
+ }
22622
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-unresolved": d.unresolved ? "true" : void 0, children: [
22623
+ \u70B9\u3068\u5024,
22624
+ /* @__PURE__ */ jsxRuntime.jsx(
22625
+ "text",
22626
+ {
22627
+ x: cx,
22628
+ y: PAD_TOP2 + canvasH + 20,
22629
+ fontSize: 12,
22630
+ textAnchor: "middle",
22631
+ fill: "var(--cdl-text-dim, #5a6270)",
22632
+ children: d.label
22633
+ }
22634
+ )
22635
+ ] }, `pt-${idx}`);
22636
+ })
22637
+ ] });
22638
+ }
22639
+
22640
+ // src/kinds/draw-ratio.ts
22641
+ var DRAW_RATIO_DEFAULT = 1;
22642
+ function \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio) {
22643
+ if (ratio === void 0) return DRAW_RATIO_DEFAULT;
22644
+ if (!Number.isFinite(ratio)) return DRAW_RATIO_DEFAULT;
22645
+ if (ratio <= 0 || ratio > 1) return DRAW_RATIO_DEFAULT;
22646
+ return ratio;
22647
+ }
22648
+ function \u63CF\u304F\u9032\u307F\u306B\u76F4\u3059(progress, ratio) {
22649
+ const \u5272\u5408 = \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio);
22650
+ if (\u5272\u5408 === DRAW_RATIO_DEFAULT) return progress;
22651
+ if (!Number.isFinite(progress)) return progress;
22652
+ return Math.min(1, progress / \u5272\u5408);
22653
+ }
22654
+
22655
+ // src/layout/lifeline.ts
22656
+ function lifelineStartYs(nodes) {
22657
+ const topmost = /* @__PURE__ */ new Map();
22658
+ for (const n of nodes) {
22659
+ const cur = topmost.get(n.lane);
22660
+ if (cur === void 0 || n.cy < cur.cy) topmost.set(n.lane, n);
22661
+ }
22662
+ const starts = /* @__PURE__ */ new Map();
22663
+ for (const [laneId, n] of topmost) starts.set(laneId, n.cy + n.h / 2);
22664
+ return starts;
22665
+ }
22666
+ function uniformLifelineEndY(lanes, nodes, starts = lifelineStartYs(nodes)) {
22667
+ const lifelineLanes = lanes.filter((l) => l.lifeline);
22668
+ let deepestStart = Number.NEGATIVE_INFINITY;
22669
+ for (const lane of lifelineLanes) {
22670
+ const start = starts.get(lane.id);
22671
+ if (start !== void 0) deepestStart = Math.max(deepestStart, start);
22672
+ }
22673
+ const footerTops = lifelineFooterNodes(lanes, nodes).map((f) => footerShapeDrawTop(f)).filter((top) => top > deepestStart);
22674
+ if (footerTops.length > 0) return Math.min(...footerTops);
22675
+ return lifelineLanes[0] ? lifelineLanes[0].y + lifelineLanes[0].height : 0;
22676
+ }
22386
22677
 
22387
22678
  // src/render/edge-head.ts
22679
+ var EDGE_HEAD_MUTED_MARKER_ID = "cdl-arrow-muted";
22388
22680
  var EDGE_HEAD_SHAPE = {
22389
22681
  // 何も描かない端。 marker 自体を出さないので `d` は読まれない
22390
22682
  none: { d: "", w: 10, h: 10, refX: 0, filled: false },
@@ -22415,6 +22707,11 @@ function edgeHeadMarkerId(tone, head, small, fill = EDGE_HEAD_FILL_DEFAULT) {
22415
22707
  const \u5857 = fill === EDGE_HEAD_FILL_DEFAULT || !EDGE_HEAD_SHAPE[head].filled ? "" : `-${fill}`;
22416
22708
  return head === EDGE_HEAD_DEFAULT && \u5857 === "" ? `cdl-arrow-${tone}${\u5C0F}` : `cdl-arrow-${tone}-${head}${\u5857}${\u5C0F}`;
22417
22709
  }
22710
+ function edgeHeadMarkerName(tone, head, small, fill) {
22711
+ const \u5B9F\u969B\u306E\u5F62 = head ?? EDGE_HEAD_DEFAULT;
22712
+ if (\u5B9F\u969B\u306E\u5F62 === "none") return void 0;
22713
+ return hasTone(tone) ? edgeHeadMarkerId(tone, \u5B9F\u969B\u306E\u5F62, small, fill ?? EDGE_HEAD_FILL_DEFAULT) : EDGE_HEAD_MUTED_MARKER_ID;
22714
+ }
22418
22715
  function edgeHeadPaint(head, fill, color) {
22419
22716
  const \u5F62 = EDGE_HEAD_SHAPE[head];
22420
22717
  if (!\u5F62.filled) return { fill: "none", stroke: color, strokeWidth: 1.6 };
@@ -22443,13 +22740,8 @@ function CdlEdgeView({
22443
22740
  stateValues
22444
22741
  }) {
22445
22742
  const color = edgeColor(edge);
22446
- const \u7AEF\u306E\u540D\u524D = (h, f) => {
22447
- const \u5F62 = h ?? EDGE_HEAD_DEFAULT;
22448
- if (\u5F62 === "none") return void 0;
22449
- return hasTone(edge.tone) ? edgeHeadMarkerId(edge.tone, \u5F62, !active, f ?? EDGE_HEAD_FILL_DEFAULT) : "cdl-arrow-muted";
22450
- };
22451
- const marker = \u7AEF\u306E\u540D\u524D(edge.head, edge.headFill);
22452
- const tailMarker = edge.tailHead === void 0 ? void 0 : \u7AEF\u306E\u540D\u524D(edge.tailHead, edge.tailHeadFill);
22743
+ const marker = edgeHeadMarkerName(edge.tone, edge.head, !active, edge.headFill);
22744
+ const tailMarker = edge.tailHead === void 0 ? void 0 : edgeHeadMarkerName(edge.tone, edge.tailHead, !active, edge.tailHeadFill);
22453
22745
  const style = edge.style ?? "solid";
22454
22746
  const isDotted = style === "dotted-flow";
22455
22747
  const isPassThrough = isDotted && Boolean(edge.dThrough);
@@ -24025,191 +24317,6 @@ function interpolateColor(template, stateValues, fallback) {
24025
24317
  if (!template) return fallback;
24026
24318
  return interpolate(template, stateValues);
24027
24319
  }
24028
- function ChartLineNode({
24029
- node,
24030
- active,
24031
- stateValues = {},
24032
- drawing = false,
24033
- progress = 1
24034
- }) {
24035
- const x0 = node.cx - node.w / 2;
24036
- const y0 = node.cy - node.h / 2;
24037
- const data = resolveChartData(node.chartData ?? [], stateValues);
24038
- const PAD_TOP2 = 36;
24039
- const PAD_RIGHT2 = 40;
24040
- const PAD_BOTTOM2 = 56;
24041
- const PAD_LEFT2 = 72;
24042
- const canvasW = node.w - PAD_LEFT2 - PAD_RIGHT2;
24043
- const canvasH = node.h - PAD_TOP2 - PAD_BOTTOM2;
24044
- const values = data.map((d) => d.value);
24045
- const vMin = values.length > 0 ? Math.min(...values) : 0;
24046
- const vMax = values.length > 0 ? Math.max(...values) : 1;
24047
- const vRange = vMax - vMin || 1;
24048
- const LABEL_ROOM = 20;
24049
- const plotTop = PAD_TOP2 + LABEL_ROOM;
24050
- const plotH = Math.max(canvasH - LABEL_ROOM * 2, 1);
24051
- const xAt = (idx) => PAD_LEFT2 + (data.length <= 1 ? canvasW / 2 : canvasW * idx / (data.length - 1));
24052
- const yAt = (v) => plotTop + plotH - (v - vMin) / vRange * plotH;
24053
- const points = data.map((d, idx) => `${xAt(idx)},${yAt(d.value)}`).join(" ");
24054
- const \u70B9\u307E\u3067\u306E\u9577\u3055 = [];
24055
- let \u7DDA\u306E\u5168\u9577 = 0;
24056
- let \u524D\u306E\u70B9;
24057
- for (const [idx, datum] of data.entries()) {
24058
- const \u4ECA\u306E\u70B9 = { x: xAt(idx), y: yAt(datum.value) };
24059
- if (\u524D\u306E\u70B9) {
24060
- \u7DDA\u306E\u5168\u9577 += Math.hypot(\u4ECA\u306E\u70B9.x - \u524D\u306E\u70B9.x, \u4ECA\u306E\u70B9.y - \u524D\u306E\u70B9.y);
24061
- }
24062
- \u70B9\u307E\u3067\u306E\u9577\u3055.push(\u7DDA\u306E\u5168\u9577);
24063
- \u524D\u306E\u70B9 = \u4ECA\u306E\u70B9;
24064
- }
24065
- const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
24066
- const \u7DDA\u306E\u5148\u304C\u5C4A\u3044\u305F = (idx) => {
24067
- if (!drawing) return true;
24068
- if (data.length <= 1) return true;
24069
- if (\u7DDA\u306E\u5168\u9577 === 0) return true;
24070
- return \u4F38\u3073 >= (\u70B9\u307E\u3067\u306E\u9577\u3055[idx] ?? 0) / \u7DDA\u306E\u5168\u9577;
24071
- };
24072
- const gridCount = 4;
24073
- const gridTicks = Array.from({ length: gridCount + 1 }, (_, i) => {
24074
- const v = vMin + vRange * i / gridCount;
24075
- return { y: yAt(v), value: v };
24076
- });
24077
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
24078
- /* @__PURE__ */ jsxRuntime.jsx(
24079
- "rect",
24080
- {
24081
- "data-cdl-role": "node-body",
24082
- x: 0,
24083
- y: 0,
24084
- width: node.w,
24085
- height: node.h,
24086
- rx: 16,
24087
- fill: "var(--cdl-node-fill, #ffffff)",
24088
- stroke: active ? "var(--cdl-tone-accent, #2d6a8f)" : "var(--cdl-divider, #d4d4d8)",
24089
- strokeWidth: active ? 3 : 1.25
24090
- }
24091
- ),
24092
- gridTicks.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
24093
- /* @__PURE__ */ jsxRuntime.jsx(
24094
- "line",
24095
- {
24096
- x1: PAD_LEFT2,
24097
- y1: t.y,
24098
- x2: PAD_LEFT2 + canvasW,
24099
- y2: t.y,
24100
- stroke: "var(--cdl-divider, #d4d4d8)",
24101
- strokeWidth: 0.75,
24102
- strokeDasharray: "3 3",
24103
- opacity: 0.65
24104
- }
24105
- ),
24106
- /* @__PURE__ */ jsxRuntime.jsx(
24107
- "text",
24108
- {
24109
- x: PAD_LEFT2 - 8,
24110
- y: t.y + 4,
24111
- fontSize: 11,
24112
- textAnchor: "end",
24113
- fill: "var(--cdl-text-dim, #5a6270)",
24114
- children: Math.round(t.value)
24115
- }
24116
- )
24117
- ] }, `grid-${i}`)),
24118
- /* @__PURE__ */ jsxRuntime.jsx(
24119
- "line",
24120
- {
24121
- x1: PAD_LEFT2,
24122
- y1: plotTop + plotH,
24123
- x2: PAD_LEFT2 + canvasW,
24124
- y2: plotTop + plotH,
24125
- stroke: "var(--cdl-text-mute, #8a8678)",
24126
- strokeWidth: 1.25
24127
- }
24128
- ),
24129
- /* @__PURE__ */ jsxRuntime.jsx(
24130
- "line",
24131
- {
24132
- x1: PAD_LEFT2,
24133
- y1: plotTop,
24134
- x2: PAD_LEFT2,
24135
- y2: plotTop + plotH,
24136
- stroke: "var(--cdl-text-mute, #8a8678)",
24137
- strokeWidth: 1.25
24138
- }
24139
- ),
24140
- data.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
24141
- "polyline",
24142
- {
24143
- "data-cdl-role": "chart-line",
24144
- points,
24145
- fill: "none",
24146
- stroke: "var(--cdl-tone-accent, #2d6a8f)",
24147
- strokeWidth: 2.5,
24148
- strokeLinejoin: "round",
24149
- strokeLinecap: "round",
24150
- ...\u4F38\u3070\u3059dash(drawing, \u4F38\u3073)
24151
- }
24152
- ),
24153
- data.map((d, idx) => {
24154
- const cx = xAt(idx);
24155
- const cy = yAt(d.value);
24156
- const prev = idx > 0 ? data[idx - 1].value : void 0;
24157
- const next = idx < data.length - 1 ? data[idx + 1].value : void 0;
24158
- const isValley = (prev === void 0 || d.value <= prev) && (next === void 0 || d.value <= next);
24159
- const labelAbove = !isValley;
24160
- const labelY = labelAbove ? cy - 12 : cy + 18;
24161
- const \u51FA\u3059 = \u7DDA\u306E\u5148\u304C\u5C4A\u3044\u305F(idx);
24162
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-unresolved": d.unresolved ? "true" : void 0, children: [
24163
- \u51FA\u3059 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
24164
- /* @__PURE__ */ jsxRuntime.jsx(
24165
- "circle",
24166
- {
24167
- cx,
24168
- cy,
24169
- r: 5,
24170
- fill: "var(--cdl-node-fill, #ffffff)",
24171
- stroke: "var(--cdl-tone-accent, #2d6a8f)",
24172
- strokeWidth: 2.5
24173
- }
24174
- ),
24175
- /* @__PURE__ */ jsxRuntime.jsx(
24176
- "circle",
24177
- {
24178
- cx,
24179
- cy,
24180
- r: 2.5,
24181
- fill: "var(--cdl-tone-accent, #2d6a8f)"
24182
- }
24183
- ),
24184
- /* @__PURE__ */ jsxRuntime.jsx(
24185
- "text",
24186
- {
24187
- "data-cdl-role": "chart-line-value",
24188
- x: cx,
24189
- y: labelY,
24190
- fontSize: 11,
24191
- fontWeight: 600,
24192
- textAnchor: "middle",
24193
- fill: "var(--cdl-text, #1a1f2a)",
24194
- children: d.value.toLocaleString()
24195
- }
24196
- )
24197
- ] }),
24198
- /* @__PURE__ */ jsxRuntime.jsx(
24199
- "text",
24200
- {
24201
- x: cx,
24202
- y: PAD_TOP2 + canvasH + 20,
24203
- fontSize: 12,
24204
- textAnchor: "middle",
24205
- fill: "var(--cdl-text-dim, #5a6270)",
24206
- children: d.label
24207
- }
24208
- )
24209
- ] }, `pt-${idx}`);
24210
- })
24211
- ] });
24212
- }
24213
24320
  function ChartPieNode({
24214
24321
  node,
24215
24322
  active,
@@ -29720,7 +29827,8 @@ function CdlNodeView({
29720
29827
  drawing = false,
29721
29828
  progress,
29722
29829
  stateValues,
29723
- currentPhaseId
29830
+ currentPhaseId,
29831
+ chartLineScale
29724
29832
  }) {
29725
29833
  const value = node.value ? interpolate(node.value, stateValues) : void 0;
29726
29834
  const rows = (node.rows ?? []).map((r) => interpolate(r, stateValues));
@@ -29776,6 +29884,7 @@ function CdlNodeView({
29776
29884
  node: resolvedNode,
29777
29885
  active,
29778
29886
  stateValues,
29887
+ scale: chartLineScale,
29779
29888
  drawing,
29780
29889
  progress
29781
29890
  }
@@ -30017,44 +30126,6 @@ function CdlNodeView({
30017
30126
  }
30018
30127
  );
30019
30128
  }
30020
-
30021
- // src/layout/lifeline.ts
30022
- function lifelineStartYs(nodes) {
30023
- const topmost = /* @__PURE__ */ new Map();
30024
- for (const n of nodes) {
30025
- const cur = topmost.get(n.lane);
30026
- if (cur === void 0 || n.cy < cur.cy) topmost.set(n.lane, n);
30027
- }
30028
- const starts = /* @__PURE__ */ new Map();
30029
- for (const [laneId, n] of topmost) starts.set(laneId, n.cy + n.h / 2);
30030
- return starts;
30031
- }
30032
- function uniformLifelineEndY(lanes, nodes, starts = lifelineStartYs(nodes)) {
30033
- const lifelineLanes = lanes.filter((l) => l.lifeline);
30034
- let deepestStart = Number.NEGATIVE_INFINITY;
30035
- for (const lane of lifelineLanes) {
30036
- const start = starts.get(lane.id);
30037
- if (start !== void 0) deepestStart = Math.max(deepestStart, start);
30038
- }
30039
- const footerTops = lifelineFooterNodes(lanes, nodes).map((f) => footerShapeDrawTop(f)).filter((top) => top > deepestStart);
30040
- if (footerTops.length > 0) return Math.min(...footerTops);
30041
- return lifelineLanes[0] ? lifelineLanes[0].y + lifelineLanes[0].height : 0;
30042
- }
30043
-
30044
- // src/kinds/draw-ratio.ts
30045
- var DRAW_RATIO_DEFAULT = 1;
30046
- function \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio) {
30047
- if (ratio === void 0) return DRAW_RATIO_DEFAULT;
30048
- if (!Number.isFinite(ratio)) return DRAW_RATIO_DEFAULT;
30049
- if (ratio <= 0 || ratio > 1) return DRAW_RATIO_DEFAULT;
30050
- return ratio;
30051
- }
30052
- function \u63CF\u304F\u9032\u307F\u306B\u76F4\u3059(progress, ratio) {
30053
- const \u5272\u5408 = \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio);
30054
- if (\u5272\u5408 === DRAW_RATIO_DEFAULT) return progress;
30055
- if (!Number.isFinite(progress)) return progress;
30056
- return Math.min(1, progress / \u5272\u5408);
30057
- }
30058
30129
  function CdlStage({
30059
30130
  laid,
30060
30131
  currentPhase,
@@ -30096,6 +30167,26 @@ function CdlStage({
30096
30167
  };
30097
30168
  }, [laid.phases, currentPhase, laid.edgeReveal]);
30098
30169
  const drawSet = new Set(currentPhase?.draw ?? []);
30170
+ const chartLineScales = react.useMemo(() => {
30171
+ const nodes = laid.nodes.filter((node) => node.kind === "chart-line");
30172
+ if (nodes.length === 0) return /* @__PURE__ */ new Map();
30173
+ const frames = [
30174
+ // phase index -1 はどの段にも入る前の初期値。
30175
+ computeStateValues(laid, -1, 0),
30176
+ ...laid.phases.flatMap((_, phaseIndex) => [
30177
+ computeStateValues(laid, phaseIndex, 0),
30178
+ computeStateValues(laid, phaseIndex, 1)
30179
+ ])
30180
+ ];
30181
+ const scales = /* @__PURE__ */ new Map();
30182
+ for (const node of nodes) {
30183
+ const values = frames.flatMap(
30184
+ (stateValues2) => resolveChartData(node.chartData ?? [], stateValues2).map((datum) => datum.value)
30185
+ );
30186
+ scales.set(node.id, \u6298\u308C\u7DDA\u306E\u76EE\u76DB(values));
30187
+ }
30188
+ return scales;
30189
+ }, [laid]);
30099
30190
  const \u63CF\u304F\u9032\u307F = \u63CF\u304F\u9032\u307F\u306B\u76F4\u3059(progress, currentPhase?.drawRatio);
30100
30191
  const { lifelineStarts, uniformFooterTop } = react.useMemo(() => {
30101
30192
  const starts = lifelineStartYs(laid.nodes);
@@ -30104,6 +30195,63 @@ function CdlStage({
30104
30195
  uniformFooterTop: uniformLifelineEndY(laid.lanes, laid.nodes, starts)
30105
30196
  };
30106
30197
  }, [laid]);
30198
+ const edgeHeadMarkers = react.useMemo(() => {
30199
+ const referenced = /* @__PURE__ */ new Set();
30200
+ const add = (tone, head, fill) => {
30201
+ for (const small of [false, true]) {
30202
+ const id = edgeHeadMarkerName(tone, head, small, fill);
30203
+ if (id !== void 0) referenced.add(id);
30204
+ }
30205
+ };
30206
+ for (const edge of laid.edges) {
30207
+ add(edge.tone, edge.head, edge.headFill);
30208
+ if (edge.tailHead !== void 0) add(edge.tone, edge.tailHead, edge.tailHeadFill);
30209
+ }
30210
+ return Object.entries(TONE).flatMap(
30211
+ ([tone, color]) => [
30212
+ [false, 14],
30213
+ [true, 10]
30214
+ ].flatMap(
30215
+ ([small, size]) => EDGE_HEADS.flatMap(
30216
+ (head) => EDGE_HEAD_FILLS.map((fill) => {
30217
+ const \u5F62 = EDGE_HEAD_SHAPE[head];
30218
+ const id = edgeHeadMarkerId(tone, head, small, fill);
30219
+ if (!referenced.has(id) || \u5F62.d === "") return null;
30220
+ if (fill !== EDGE_HEAD_FILL_DEFAULT && !\u5F62.filled) return null;
30221
+ const \u5857 = edgeHeadPaint(head, fill, color);
30222
+ return /* @__PURE__ */ jsxRuntime.jsx(
30223
+ "marker",
30224
+ {
30225
+ id,
30226
+ viewBox: `0 0 ${\u5F62.w} ${\u5F62.h}`,
30227
+ refX: \u5F62.refX,
30228
+ refY: \u5F62.h / 2,
30229
+ markerWidth: size * (\u5F62.scale ?? 1) * \u5F62.w / \u5F62.h,
30230
+ markerHeight: size * (\u5F62.scale ?? 1),
30231
+ markerUnits: "userSpaceOnUse",
30232
+ orient: "auto-start-reverse",
30233
+ children: /* @__PURE__ */ jsxRuntime.jsx(
30234
+ "path",
30235
+ {
30236
+ "data-cdl-role": "edge-arrowhead",
30237
+ "data-cdl-edge-head": head,
30238
+ "data-cdl-edge-head-fill": fill,
30239
+ d: \u5F62.d,
30240
+ fill: \u5857.fill,
30241
+ stroke: \u5857.stroke,
30242
+ strokeWidth: \u5857.strokeWidth,
30243
+ strokeLinecap: \u5857.strokeWidth === void 0 ? void 0 : "round",
30244
+ strokeLinejoin: \u5857.strokeWidth === void 0 ? void 0 : "round"
30245
+ }
30246
+ )
30247
+ },
30248
+ id
30249
+ );
30250
+ })
30251
+ )
30252
+ )
30253
+ );
30254
+ }, [laid]);
30107
30255
  const diagramScale = laid.diagramScale ?? 1;
30108
30256
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: compact ? "px-3 py-3" : "px-6 py-6", style: compact ? void 0 : { minHeight: 460 }, children: [
30109
30257
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -30122,55 +30270,11 @@ function CdlStage({
30122
30270
  "data-cdl-type": laid.type,
30123
30271
  children: [
30124
30272
  /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
30125
- Object.entries(TONE).flatMap(
30126
- ([tone, color]) => [["", 14], ["-sm", 10]].flatMap(
30127
- ([suffix, size]) => EDGE_HEADS.flatMap(
30128
- (head) => (
30129
- // 塗り方は形と別の軸 (#578)。 塗らない形では 2 つが同じ名前に畳まれるので、
30130
- // `edgeHeadMarkerId` が返す名前で重複を外す
30131
- EDGE_HEAD_FILLS.map((fill) => {
30132
- const \u5F62 = EDGE_HEAD_SHAPE[head];
30133
- const id = edgeHeadMarkerId(tone, head, suffix === "-sm", fill);
30134
- if (\u5F62.d === "") return null;
30135
- if (fill !== EDGE_HEAD_FILL_DEFAULT && !\u5F62.filled) return null;
30136
- const \u5857 = edgeHeadPaint(head, fill, color);
30137
- return /* @__PURE__ */ jsxRuntime.jsx(
30138
- "marker",
30139
- {
30140
- id,
30141
- viewBox: `0 0 ${\u5F62.w} ${\u5F62.h}`,
30142
- refX: \u5F62.refX,
30143
- refY: \u5F62.h / 2,
30144
- markerWidth: size * (\u5F62.scale ?? 1) * \u5F62.w / \u5F62.h,
30145
- markerHeight: size * (\u5F62.scale ?? 1),
30146
- markerUnits: "userSpaceOnUse",
30147
- orient: "auto-start-reverse",
30148
- children: /* @__PURE__ */ jsxRuntime.jsx(
30149
- "path",
30150
- {
30151
- "data-cdl-role": "edge-arrowhead",
30152
- "data-cdl-edge-head": head,
30153
- "data-cdl-edge-head-fill": fill,
30154
- d: \u5F62.d,
30155
- fill: \u5857.fill,
30156
- stroke: \u5857.stroke,
30157
- strokeWidth: \u5857.strokeWidth,
30158
- strokeLinecap: \u5857.strokeWidth === void 0 ? void 0 : "round",
30159
- strokeLinejoin: \u5857.strokeWidth === void 0 ? void 0 : "round"
30160
- }
30161
- )
30162
- },
30163
- id
30164
- );
30165
- })
30166
- )
30167
- )
30168
- )
30169
- ),
30273
+ edgeHeadMarkers,
30170
30274
  /* @__PURE__ */ jsxRuntime.jsx(
30171
30275
  "marker",
30172
30276
  {
30173
- id: "cdl-arrow-muted",
30277
+ id: EDGE_HEAD_MUTED_MARKER_ID,
30174
30278
  viewBox: "0 0 10 10",
30175
30279
  refX: "9",
30176
30280
  refY: "5",
@@ -30277,7 +30381,8 @@ function CdlStage({
30277
30381
  drawing: \u63CF\u304F,
30278
30382
  progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
30279
30383
  stateValues,
30280
- currentPhaseId: currentPhase?.id
30384
+ currentPhaseId: currentPhase?.id,
30385
+ chartLineScale: chartLineScales.get(node.id)
30281
30386
  }
30282
30387
  );
30283
30388
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: view }, node.id);