@cardenelabs/cdl 0.30.3 → 0.31.1

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