@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/react.cjs CHANGED
@@ -9887,8 +9887,314 @@ function StateDiffCard({
9887
9887
  }
9888
9888
  );
9889
9889
  }
9890
+ var \u6570\u3092\u66F8\u304F = (value) => value.toLocaleString("en-US", { maximumFractionDigits: 12 });
9891
+ function \u6298\u308C\u7DDA\u306E\u76EE\u76DB(values) {
9892
+ let rawMin = values.length > 0 ? Math.min(...values) : 0;
9893
+ let rawMax = values.length > 0 ? Math.max(...values) : 1;
9894
+ if (rawMin === rawMax) {
9895
+ const room = 10 ** Math.floor(Math.log10(Math.abs(rawMin) || 1) - 1);
9896
+ rawMin -= room;
9897
+ rawMax += room;
9898
+ }
9899
+ const roughStep = (rawMax - rawMin) / 4;
9900
+ const power = 10 ** Math.floor(Math.log10(roughStep));
9901
+ const fraction = roughStep / power;
9902
+ const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10;
9903
+ const step = niceFraction * power;
9904
+ const min = Math.floor(rawMin / step) * step;
9905
+ const max = Math.ceil(rawMax / step) * step;
9906
+ const tickCount = Math.round((max - min) / step);
9907
+ const ticks = Array.from({ length: tickCount + 1 }, (_, i) => {
9908
+ const value = min + step * i;
9909
+ return Math.abs(value) < step * 1e-12 ? 0 : value;
9910
+ });
9911
+ return { min, max, ticks };
9912
+ }
9913
+ function ChartLineNode({
9914
+ node,
9915
+ active,
9916
+ stateValues = {},
9917
+ scale: fixedScale,
9918
+ drawing = false,
9919
+ progress = 1
9920
+ }) {
9921
+ const x0 = node.cx - node.w / 2;
9922
+ const y0 = node.cy - node.h / 2;
9923
+ const data = resolveChartData(node.chartData ?? [], stateValues);
9924
+ const PAD_TOP2 = 36;
9925
+ const PAD_RIGHT2 = 40;
9926
+ const PAD_BOTTOM2 = 56;
9927
+ const PAD_LEFT2 = 72;
9928
+ const canvasW = node.w - PAD_LEFT2 - PAD_RIGHT2;
9929
+ const canvasH = node.h - PAD_TOP2 - PAD_BOTTOM2;
9930
+ const scale = fixedScale ?? \u6298\u308C\u7DDA\u306E\u76EE\u76DB(data.map((d) => d.value));
9931
+ const vRange = scale.max - scale.min;
9932
+ const LABEL_ROOM = 20;
9933
+ const plotTop = PAD_TOP2 + LABEL_ROOM;
9934
+ const plotH = Math.max(canvasH - LABEL_ROOM * 2, 1);
9935
+ const POINT_EDGE_ROOM = 24;
9936
+ const plotW = Math.max(canvasW - POINT_EDGE_ROOM * 2, 1);
9937
+ const xAt = (idx) => PAD_LEFT2 + POINT_EDGE_ROOM + (data.length <= 1 ? plotW / 2 : plotW * idx / (data.length - 1));
9938
+ const yAt = (v) => plotTop + plotH - (v - scale.min) / vRange * plotH;
9939
+ const plotBottom = PAD_TOP2 + canvasH;
9940
+ let \u7DDA\u306E\u5168\u9577 = 0;
9941
+ let \u524D\u306E\u70B9;
9942
+ const \u63CF\u753B\u70B9 = data.map((datum, idx) => {
9943
+ const \u4ECA\u306E\u70B9 = { datum, x: xAt(idx), y: yAt(datum.value), \u3053\u3053\u307E\u3067\u306E\u9577\u3055: 0 };
9944
+ if (\u524D\u306E\u70B9) {
9945
+ \u7DDA\u306E\u5168\u9577 += Math.hypot(\u4ECA\u306E\u70B9.x - \u524D\u306E\u70B9.x, \u4ECA\u306E\u70B9.y - \u524D\u306E\u70B9.y);
9946
+ }
9947
+ \u4ECA\u306E\u70B9.\u3053\u3053\u307E\u3067\u306E\u9577\u3055 = \u7DDA\u306E\u5168\u9577;
9948
+ \u524D\u306E\u70B9 = \u4ECA\u306E\u70B9;
9949
+ return \u4ECA\u306E\u70B9;
9950
+ });
9951
+ const points = \u63CF\u753B\u70B9.map((\u70B9) => `${\u70B9.x},${\u70B9.y}`).join(" ");
9952
+ const \u6BB5\u306E\u9032\u307F = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
9953
+ const \u7C92\u3092\u8D70\u3089\u305B\u308B = drawing && node.chartTrace === true;
9954
+ const \u4F38\u3073 = \u7C92\u3092\u8D70\u3089\u305B\u308B ? Math.min(1, \u6BB5\u306E\u9032\u307F / 0.5) : \u6BB5\u306E\u9032\u307F;
9955
+ 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;
9956
+ const \u7C92\u304C\u51FA\u308B = \u7C92\u3092\u8D70\u3089\u305B\u308B && \u6BB5\u306E\u9032\u307F >= 0.55 && \u6BB5\u306E\u9032\u307F < 1;
9957
+ const \u5230\u7740\u7A93 = 0.12;
9958
+ let \u7C92\u306E\u4F4D\u7F6E;
9959
+ const \u6700\u521D\u306E\u70B9 = \u63CF\u753B\u70B9[0];
9960
+ if (\u7C92\u304C\u51FA\u308B && \u6700\u521D\u306E\u70B9) {
9961
+ const \u7C92\u307E\u3067\u306E\u9577\u3055 = \u7C92\u306E\u9032\u307F * \u7DDA\u306E\u5168\u9577;
9962
+ let \u533A\u9593\u306E\u524D = \u6700\u521D\u306E\u70B9;
9963
+ let \u533A\u9593\u306E\u5F8C = \u6700\u521D\u306E\u70B9;
9964
+ for (const \u70B9 of \u63CF\u753B\u70B9.slice(1)) {
9965
+ \u533A\u9593\u306E\u5F8C = \u70B9;
9966
+ if (\u70B9.\u3053\u3053\u307E\u3067\u306E\u9577\u3055 >= \u7C92\u307E\u3067\u306E\u9577\u3055) break;
9967
+ \u533A\u9593\u306E\u524D = \u70B9;
9968
+ }
9969
+ const \u533A\u9593\u306E\u59CB\u3081 = \u533A\u9593\u306E\u524D.\u3053\u3053\u307E\u3067\u306E\u9577\u3055;
9970
+ const \u533A\u9593\u306E\u9577\u3055 = \u533A\u9593\u306E\u5F8C.\u3053\u3053\u307E\u3067\u306E\u9577\u3055 - \u533A\u9593\u306E\u59CB\u3081;
9971
+ 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;
9972
+ \u7C92\u306E\u4F4D\u7F6E = {
9973
+ x: \u533A\u9593\u306E\u524D.x + (\u533A\u9593\u306E\u5F8C.x - \u533A\u9593\u306E\u524D.x) * \u533A\u9593\u306E\u9032\u307F,
9974
+ y: \u533A\u9593\u306E\u524D.y + (\u533A\u9593\u306E\u5F8C.y - \u533A\u9593\u306E\u524D.y) * \u533A\u9593\u306E\u9032\u307F
9975
+ };
9976
+ }
9977
+ const gridTicks = scale.ticks.map((value) => ({ y: yAt(value), value }));
9978
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
9979
+ /* @__PURE__ */ jsxRuntime.jsx(
9980
+ "rect",
9981
+ {
9982
+ "data-cdl-role": "node-body",
9983
+ x: 0,
9984
+ y: 0,
9985
+ width: node.w,
9986
+ height: node.h,
9987
+ rx: 16,
9988
+ fill: "var(--cdl-node-fill, #ffffff)",
9989
+ stroke: "var(--cdl-divider, #d4d4d8)",
9990
+ strokeWidth: active ? 1.5 : 1
9991
+ }
9992
+ ),
9993
+ gridTicks.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
9994
+ /* @__PURE__ */ jsxRuntime.jsx(
9995
+ "line",
9996
+ {
9997
+ x1: PAD_LEFT2,
9998
+ y1: t.y,
9999
+ x2: PAD_LEFT2 + canvasW,
10000
+ y2: t.y,
10001
+ stroke: "var(--cdl-divider, #d4d4d8)",
10002
+ strokeWidth: 0.75,
10003
+ strokeDasharray: "3 3",
10004
+ opacity: 0.65
10005
+ }
10006
+ ),
10007
+ /* @__PURE__ */ jsxRuntime.jsx(
10008
+ "text",
10009
+ {
10010
+ x: PAD_LEFT2 - 8,
10011
+ y: t.y + 4,
10012
+ fontSize: 11,
10013
+ textAnchor: "end",
10014
+ fill: "var(--cdl-text-dim, #5a6270)",
10015
+ children: \u6570\u3092\u66F8\u304F(t.value)
10016
+ }
10017
+ )
10018
+ ] }, `grid-${i}`)),
10019
+ node.chartFillUnder && data.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10020
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10021
+ "linearGradient",
10022
+ {
10023
+ id: `chart-line-fill-${node.id}`,
10024
+ gradientUnits: "userSpaceOnUse",
10025
+ x1: 0,
10026
+ y1: plotTop,
10027
+ x2: 0,
10028
+ y2: plotBottom,
10029
+ children: [
10030
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: "var(--cdl-tone-accent, #2d6a8f)", stopOpacity: 0.22 }),
10031
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: "var(--cdl-tone-accent, #2d6a8f)", stopOpacity: 0 })
10032
+ ]
10033
+ }
10034
+ ) }),
10035
+ /* @__PURE__ */ jsxRuntime.jsx(
10036
+ "path",
10037
+ {
10038
+ "data-cdl-role": "chart-line-fill-under",
10039
+ d: `M ${xAt(0)} ${plotBottom} L ${points.replaceAll(",", " ")} L ${xAt(data.length - 1)} ${plotBottom} Z`,
10040
+ fill: `url(#chart-line-fill-${node.id})`,
10041
+ stroke: "none"
10042
+ }
10043
+ )
10044
+ ] }),
10045
+ data.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
10046
+ "polyline",
10047
+ {
10048
+ "data-cdl-role": "chart-line",
10049
+ points,
10050
+ fill: "none",
10051
+ stroke: "var(--cdl-tone-accent, #2d6a8f)",
10052
+ strokeWidth: active ? 3 : 2,
10053
+ strokeLinejoin: "round",
10054
+ strokeLinecap: "round",
10055
+ ...\u4F38\u3070\u3059dash(drawing, \u4F38\u3073)
10056
+ }
10057
+ ),
10058
+ \u7C92\u306E\u4F4D\u7F6E && /* @__PURE__ */ jsxRuntime.jsx(
10059
+ "circle",
10060
+ {
10061
+ "data-cdl-role": "chart-line-trace",
10062
+ cx: \u7C92\u306E\u4F4D\u7F6E.x,
10063
+ cy: \u7C92\u306E\u4F4D\u7F6E.y,
10064
+ r: 4.5,
10065
+ fill: "var(--cdl-now)"
10066
+ }
10067
+ ),
10068
+ \u63CF\u753B\u70B9.map(({ datum: d, x: cx, y: cy, \u3053\u3053\u307E\u3067\u306E\u9577\u3055 }, idx) => {
10069
+ const prev = data[idx - 1]?.value;
10070
+ const next = data[idx + 1]?.value;
10071
+ const isValley = (prev === void 0 || d.value <= prev) && (next === void 0 || d.value <= next);
10072
+ const labelAbove = !isValley;
10073
+ const labelY = labelAbove ? cy - 12 : cy + 18;
10074
+ 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;
10075
+ const \u51FA\u3059 = !drawing || (!\u7C92\u3092\u8D70\u3089\u305B\u308B || \u6BB5\u306E\u9032\u307F >= 0.55) && \u5230\u7740\u5F8C >= 0;
10076
+ const \u5149\u308B = drawing && \u51FA\u3059 && \u5230\u7740\u5F8C < \u5230\u7740\u7A93;
10077
+ const \u5149\u306E\u9032\u307F = \u5149\u308B ? \u5230\u7740\u5F8C / \u5230\u7740\u7A93 : 1;
10078
+ let \u70B9\u3068\u5024;
10079
+ if (\u51FA\u3059) {
10080
+ const \u5149\u306E\u534A\u5F84 = 6 + 16 * \u5149\u306E\u9032\u307F;
10081
+ const \u5024 = /* @__PURE__ */ jsxRuntime.jsx(
10082
+ "text",
10083
+ {
10084
+ "data-cdl-role": "chart-line-value",
10085
+ x: cx,
10086
+ y: labelY,
10087
+ fontSize: 11,
10088
+ fontWeight: 600,
10089
+ textAnchor: "middle",
10090
+ fill: "var(--cdl-text, #1a1f2a)",
10091
+ children: \u6570\u3092\u66F8\u304F(d.value)
10092
+ }
10093
+ );
10094
+ \u70B9\u3068\u5024 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10095
+ \u5149\u308B && // marker の `circle` を数える利用側へ混ぜず、専用 role の等径 ellipse として輪を出す。
10096
+ /* @__PURE__ */ jsxRuntime.jsx(
10097
+ "ellipse",
10098
+ {
10099
+ "data-cdl-role": "chart-line-arrival-ring",
10100
+ cx,
10101
+ cy,
10102
+ rx: \u5149\u306E\u534A\u5F84,
10103
+ ry: \u5149\u306E\u534A\u5F84,
10104
+ fill: "none",
10105
+ stroke: "var(--cdl-now)",
10106
+ strokeWidth: 2,
10107
+ opacity: 0.85 * (1 - \u5149\u306E\u9032\u307F)
10108
+ }
10109
+ ),
10110
+ /* @__PURE__ */ jsxRuntime.jsx(
10111
+ "circle",
10112
+ {
10113
+ cx,
10114
+ cy,
10115
+ r: 5,
10116
+ fill: "var(--cdl-node-fill, #ffffff)",
10117
+ stroke: \u5149\u308B ? "var(--cdl-now)" : "var(--cdl-tone-accent, #2d6a8f)",
10118
+ strokeWidth: 2.5
10119
+ }
10120
+ ),
10121
+ /* @__PURE__ */ jsxRuntime.jsx(
10122
+ "circle",
10123
+ {
10124
+ cx,
10125
+ cy,
10126
+ r: 2.5,
10127
+ fill: \u5149\u308B ? "var(--cdl-now)" : "var(--cdl-tone-accent, #2d6a8f)"
10128
+ }
10129
+ ),
10130
+ node.chartValueRise && \u5149\u308B ? /* @__PURE__ */ jsxRuntime.jsx(
10131
+ "g",
10132
+ {
10133
+ "data-cdl-role": "chart-line-value-rise",
10134
+ transform: `translate(0 ${8 * (1 - \u5149\u306E\u9032\u307F)})`,
10135
+ children: \u5024
10136
+ }
10137
+ ) : \u5024
10138
+ ] });
10139
+ }
10140
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-unresolved": d.unresolved ? "true" : void 0, children: [
10141
+ \u70B9\u3068\u5024,
10142
+ /* @__PURE__ */ jsxRuntime.jsx(
10143
+ "text",
10144
+ {
10145
+ x: cx,
10146
+ y: PAD_TOP2 + canvasH + 20,
10147
+ fontSize: 12,
10148
+ textAnchor: "middle",
10149
+ fill: "var(--cdl-text-dim, #5a6270)",
10150
+ children: d.label
10151
+ }
10152
+ )
10153
+ ] }, `pt-${idx}`);
10154
+ })
10155
+ ] });
10156
+ }
10157
+
10158
+ // src/kinds/draw-ratio.ts
10159
+ var DRAW_RATIO_DEFAULT = 1;
10160
+ function \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio) {
10161
+ if (ratio === void 0) return DRAW_RATIO_DEFAULT;
10162
+ if (!Number.isFinite(ratio)) return DRAW_RATIO_DEFAULT;
10163
+ if (ratio <= 0 || ratio > 1) return DRAW_RATIO_DEFAULT;
10164
+ return ratio;
10165
+ }
10166
+ function \u63CF\u304F\u9032\u307F\u306B\u76F4\u3059(progress, ratio) {
10167
+ const \u5272\u5408 = \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio);
10168
+ if (\u5272\u5408 === DRAW_RATIO_DEFAULT) return progress;
10169
+ if (!Number.isFinite(progress)) return progress;
10170
+ return Math.min(1, progress / \u5272\u5408);
10171
+ }
10172
+
10173
+ // src/layout/lifeline.ts
10174
+ function lifelineStartYs(nodes) {
10175
+ const topmost = /* @__PURE__ */ new Map();
10176
+ for (const n of nodes) {
10177
+ const cur = topmost.get(n.lane);
10178
+ if (cur === void 0 || n.cy < cur.cy) topmost.set(n.lane, n);
10179
+ }
10180
+ const starts = /* @__PURE__ */ new Map();
10181
+ for (const [laneId, n] of topmost) starts.set(laneId, n.cy + n.h / 2);
10182
+ return starts;
10183
+ }
10184
+ function uniformLifelineEndY(lanes, nodes, starts = lifelineStartYs(nodes)) {
10185
+ const lifelineLanes = lanes.filter((l) => l.lifeline);
10186
+ let deepestStart = Number.NEGATIVE_INFINITY;
10187
+ for (const lane of lifelineLanes) {
10188
+ const start = starts.get(lane.id);
10189
+ if (start !== void 0) deepestStart = Math.max(deepestStart, start);
10190
+ }
10191
+ const footerTops = lifelineFooterNodes(lanes, nodes).map((f) => footerShapeDrawTop(f)).filter((top) => top > deepestStart);
10192
+ if (footerTops.length > 0) return Math.min(...footerTops);
10193
+ return lifelineLanes[0] ? lifelineLanes[0].y + lifelineLanes[0].height : 0;
10194
+ }
9890
10195
 
9891
10196
  // src/render/edge-head.ts
10197
+ var EDGE_HEAD_MUTED_MARKER_ID = "cdl-arrow-muted";
9892
10198
  var EDGE_HEAD_SHAPE = {
9893
10199
  // 何も描かない端。 marker 自体を出さないので `d` は読まれない
9894
10200
  none: { d: "", w: 10, h: 10, refX: 0, filled: false },
@@ -9919,6 +10225,11 @@ function edgeHeadMarkerId(tone, head, small, fill = EDGE_HEAD_FILL_DEFAULT) {
9919
10225
  const \u5857 = fill === EDGE_HEAD_FILL_DEFAULT || !EDGE_HEAD_SHAPE[head].filled ? "" : `-${fill}`;
9920
10226
  return head === EDGE_HEAD_DEFAULT && \u5857 === "" ? `cdl-arrow-${tone}${\u5C0F}` : `cdl-arrow-${tone}-${head}${\u5857}${\u5C0F}`;
9921
10227
  }
10228
+ function edgeHeadMarkerName(tone, head, small, fill) {
10229
+ const \u5B9F\u969B\u306E\u5F62 = head ?? EDGE_HEAD_DEFAULT;
10230
+ if (\u5B9F\u969B\u306E\u5F62 === "none") return void 0;
10231
+ return hasTone(tone) ? edgeHeadMarkerId(tone, \u5B9F\u969B\u306E\u5F62, small, fill ?? EDGE_HEAD_FILL_DEFAULT) : EDGE_HEAD_MUTED_MARKER_ID;
10232
+ }
9922
10233
  function edgeHeadPaint(head, fill, color) {
9923
10234
  const \u5F62 = EDGE_HEAD_SHAPE[head];
9924
10235
  if (!\u5F62.filled) return { fill: "none", stroke: color, strokeWidth: 1.6 };
@@ -9947,13 +10258,8 @@ function CdlEdgeView({
9947
10258
  stateValues
9948
10259
  }) {
9949
10260
  const color = edgeColor(edge);
9950
- const \u7AEF\u306E\u540D\u524D = (h, f) => {
9951
- const \u5F62 = h ?? EDGE_HEAD_DEFAULT;
9952
- if (\u5F62 === "none") return void 0;
9953
- return hasTone(edge.tone) ? edgeHeadMarkerId(edge.tone, \u5F62, !active, f ?? EDGE_HEAD_FILL_DEFAULT) : "cdl-arrow-muted";
9954
- };
9955
- const marker = \u7AEF\u306E\u540D\u524D(edge.head, edge.headFill);
9956
- const tailMarker = edge.tailHead === void 0 ? void 0 : \u7AEF\u306E\u540D\u524D(edge.tailHead, edge.tailHeadFill);
10261
+ const marker = edgeHeadMarkerName(edge.tone, edge.head, !active, edge.headFill);
10262
+ const tailMarker = edge.tailHead === void 0 ? void 0 : edgeHeadMarkerName(edge.tone, edge.tailHead, !active, edge.tailHeadFill);
9957
10263
  const style = edge.style ?? "solid";
9958
10264
  const isDotted = style === "dotted-flow";
9959
10265
  const isPassThrough = isDotted && Boolean(edge.dThrough);
@@ -11526,191 +11832,6 @@ function interpolateColor(template, stateValues, fallback) {
11526
11832
  if (!template) return fallback;
11527
11833
  return interpolate(template, stateValues);
11528
11834
  }
11529
- function ChartLineNode({
11530
- node,
11531
- active,
11532
- stateValues = {},
11533
- drawing = false,
11534
- progress = 1
11535
- }) {
11536
- const x0 = node.cx - node.w / 2;
11537
- const y0 = node.cy - node.h / 2;
11538
- const data = resolveChartData(node.chartData ?? [], stateValues);
11539
- const PAD_TOP2 = 36;
11540
- const PAD_RIGHT2 = 40;
11541
- const PAD_BOTTOM2 = 56;
11542
- const PAD_LEFT2 = 72;
11543
- const canvasW = node.w - PAD_LEFT2 - PAD_RIGHT2;
11544
- const canvasH = node.h - PAD_TOP2 - PAD_BOTTOM2;
11545
- const values = data.map((d) => d.value);
11546
- const vMin = values.length > 0 ? Math.min(...values) : 0;
11547
- const vMax = values.length > 0 ? Math.max(...values) : 1;
11548
- const vRange = vMax - vMin || 1;
11549
- const LABEL_ROOM = 20;
11550
- const plotTop = PAD_TOP2 + LABEL_ROOM;
11551
- const plotH = Math.max(canvasH - LABEL_ROOM * 2, 1);
11552
- const xAt = (idx) => PAD_LEFT2 + (data.length <= 1 ? canvasW / 2 : canvasW * idx / (data.length - 1));
11553
- const yAt = (v) => plotTop + plotH - (v - vMin) / vRange * plotH;
11554
- const points = data.map((d, idx) => `${xAt(idx)},${yAt(d.value)}`).join(" ");
11555
- const \u70B9\u307E\u3067\u306E\u9577\u3055 = [];
11556
- let \u7DDA\u306E\u5168\u9577 = 0;
11557
- let \u524D\u306E\u70B9;
11558
- for (const [idx, datum] of data.entries()) {
11559
- const \u4ECA\u306E\u70B9 = { x: xAt(idx), y: yAt(datum.value) };
11560
- if (\u524D\u306E\u70B9) {
11561
- \u7DDA\u306E\u5168\u9577 += Math.hypot(\u4ECA\u306E\u70B9.x - \u524D\u306E\u70B9.x, \u4ECA\u306E\u70B9.y - \u524D\u306E\u70B9.y);
11562
- }
11563
- \u70B9\u307E\u3067\u306E\u9577\u3055.push(\u7DDA\u306E\u5168\u9577);
11564
- \u524D\u306E\u70B9 = \u4ECA\u306E\u70B9;
11565
- }
11566
- const \u4F38\u3073 = \u9032\u307F\u3092\u7573\u3080(drawing, progress);
11567
- const \u7DDA\u306E\u5148\u304C\u5C4A\u3044\u305F = (idx) => {
11568
- if (!drawing) return true;
11569
- if (data.length <= 1) return true;
11570
- if (\u7DDA\u306E\u5168\u9577 === 0) return true;
11571
- return \u4F38\u3073 >= (\u70B9\u307E\u3067\u306E\u9577\u3055[idx] ?? 0) / \u7DDA\u306E\u5168\u9577;
11572
- };
11573
- const gridCount = 4;
11574
- const gridTicks = Array.from({ length: gridCount + 1 }, (_, i) => {
11575
- const v = vMin + vRange * i / gridCount;
11576
- return { y: yAt(v), value: v };
11577
- });
11578
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x0} ${y0})`, children: [
11579
- /* @__PURE__ */ jsxRuntime.jsx(
11580
- "rect",
11581
- {
11582
- "data-cdl-role": "node-body",
11583
- x: 0,
11584
- y: 0,
11585
- width: node.w,
11586
- height: node.h,
11587
- rx: 16,
11588
- fill: "var(--cdl-node-fill, #ffffff)",
11589
- stroke: active ? "var(--cdl-tone-accent, #2d6a8f)" : "var(--cdl-divider, #d4d4d8)",
11590
- strokeWidth: active ? 3 : 1.25
11591
- }
11592
- ),
11593
- gridTicks.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
11594
- /* @__PURE__ */ jsxRuntime.jsx(
11595
- "line",
11596
- {
11597
- x1: PAD_LEFT2,
11598
- y1: t.y,
11599
- x2: PAD_LEFT2 + canvasW,
11600
- y2: t.y,
11601
- stroke: "var(--cdl-divider, #d4d4d8)",
11602
- strokeWidth: 0.75,
11603
- strokeDasharray: "3 3",
11604
- opacity: 0.65
11605
- }
11606
- ),
11607
- /* @__PURE__ */ jsxRuntime.jsx(
11608
- "text",
11609
- {
11610
- x: PAD_LEFT2 - 8,
11611
- y: t.y + 4,
11612
- fontSize: 11,
11613
- textAnchor: "end",
11614
- fill: "var(--cdl-text-dim, #5a6270)",
11615
- children: Math.round(t.value)
11616
- }
11617
- )
11618
- ] }, `grid-${i}`)),
11619
- /* @__PURE__ */ jsxRuntime.jsx(
11620
- "line",
11621
- {
11622
- x1: PAD_LEFT2,
11623
- y1: plotTop + plotH,
11624
- x2: PAD_LEFT2 + canvasW,
11625
- y2: plotTop + plotH,
11626
- stroke: "var(--cdl-text-mute, #8a8678)",
11627
- strokeWidth: 1.25
11628
- }
11629
- ),
11630
- /* @__PURE__ */ jsxRuntime.jsx(
11631
- "line",
11632
- {
11633
- x1: PAD_LEFT2,
11634
- y1: plotTop,
11635
- x2: PAD_LEFT2,
11636
- y2: plotTop + plotH,
11637
- stroke: "var(--cdl-text-mute, #8a8678)",
11638
- strokeWidth: 1.25
11639
- }
11640
- ),
11641
- data.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
11642
- "polyline",
11643
- {
11644
- "data-cdl-role": "chart-line",
11645
- points,
11646
- fill: "none",
11647
- stroke: "var(--cdl-tone-accent, #2d6a8f)",
11648
- strokeWidth: 2.5,
11649
- strokeLinejoin: "round",
11650
- strokeLinecap: "round",
11651
- ...\u4F38\u3070\u3059dash(drawing, \u4F38\u3073)
11652
- }
11653
- ),
11654
- data.map((d, idx) => {
11655
- const cx = xAt(idx);
11656
- const cy = yAt(d.value);
11657
- const prev = idx > 0 ? data[idx - 1].value : void 0;
11658
- const next = idx < data.length - 1 ? data[idx + 1].value : void 0;
11659
- const isValley = (prev === void 0 || d.value <= prev) && (next === void 0 || d.value <= next);
11660
- const labelAbove = !isValley;
11661
- const labelY = labelAbove ? cy - 12 : cy + 18;
11662
- const \u51FA\u3059 = \u7DDA\u306E\u5148\u304C\u5C4A\u3044\u305F(idx);
11663
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-unresolved": d.unresolved ? "true" : void 0, children: [
11664
- \u51FA\u3059 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11665
- /* @__PURE__ */ jsxRuntime.jsx(
11666
- "circle",
11667
- {
11668
- cx,
11669
- cy,
11670
- r: 5,
11671
- fill: "var(--cdl-node-fill, #ffffff)",
11672
- stroke: "var(--cdl-tone-accent, #2d6a8f)",
11673
- strokeWidth: 2.5
11674
- }
11675
- ),
11676
- /* @__PURE__ */ jsxRuntime.jsx(
11677
- "circle",
11678
- {
11679
- cx,
11680
- cy,
11681
- r: 2.5,
11682
- fill: "var(--cdl-tone-accent, #2d6a8f)"
11683
- }
11684
- ),
11685
- /* @__PURE__ */ jsxRuntime.jsx(
11686
- "text",
11687
- {
11688
- "data-cdl-role": "chart-line-value",
11689
- x: cx,
11690
- y: labelY,
11691
- fontSize: 11,
11692
- fontWeight: 600,
11693
- textAnchor: "middle",
11694
- fill: "var(--cdl-text, #1a1f2a)",
11695
- children: d.value.toLocaleString()
11696
- }
11697
- )
11698
- ] }),
11699
- /* @__PURE__ */ jsxRuntime.jsx(
11700
- "text",
11701
- {
11702
- x: cx,
11703
- y: PAD_TOP2 + canvasH + 20,
11704
- fontSize: 12,
11705
- textAnchor: "middle",
11706
- fill: "var(--cdl-text-dim, #5a6270)",
11707
- children: d.label
11708
- }
11709
- )
11710
- ] }, `pt-${idx}`);
11711
- })
11712
- ] });
11713
- }
11714
11835
  function ChartPieNode({
11715
11836
  node,
11716
11837
  active,
@@ -17221,7 +17342,8 @@ function CdlNodeView({
17221
17342
  drawing = false,
17222
17343
  progress,
17223
17344
  stateValues,
17224
- currentPhaseId
17345
+ currentPhaseId,
17346
+ chartLineScale
17225
17347
  }) {
17226
17348
  const value = node.value ? interpolate(node.value, stateValues) : void 0;
17227
17349
  const rows = (node.rows ?? []).map((r) => interpolate(r, stateValues));
@@ -17277,6 +17399,7 @@ function CdlNodeView({
17277
17399
  node: resolvedNode,
17278
17400
  active,
17279
17401
  stateValues,
17402
+ scale: chartLineScale,
17280
17403
  drawing,
17281
17404
  progress
17282
17405
  }
@@ -17518,44 +17641,6 @@ function CdlNodeView({
17518
17641
  }
17519
17642
  );
17520
17643
  }
17521
-
17522
- // src/layout/lifeline.ts
17523
- function lifelineStartYs(nodes) {
17524
- const topmost = /* @__PURE__ */ new Map();
17525
- for (const n of nodes) {
17526
- const cur = topmost.get(n.lane);
17527
- if (cur === void 0 || n.cy < cur.cy) topmost.set(n.lane, n);
17528
- }
17529
- const starts = /* @__PURE__ */ new Map();
17530
- for (const [laneId, n] of topmost) starts.set(laneId, n.cy + n.h / 2);
17531
- return starts;
17532
- }
17533
- function uniformLifelineEndY(lanes, nodes, starts = lifelineStartYs(nodes)) {
17534
- const lifelineLanes = lanes.filter((l) => l.lifeline);
17535
- let deepestStart = Number.NEGATIVE_INFINITY;
17536
- for (const lane of lifelineLanes) {
17537
- const start = starts.get(lane.id);
17538
- if (start !== void 0) deepestStart = Math.max(deepestStart, start);
17539
- }
17540
- const footerTops = lifelineFooterNodes(lanes, nodes).map((f) => footerShapeDrawTop(f)).filter((top) => top > deepestStart);
17541
- if (footerTops.length > 0) return Math.min(...footerTops);
17542
- return lifelineLanes[0] ? lifelineLanes[0].y + lifelineLanes[0].height : 0;
17543
- }
17544
-
17545
- // src/kinds/draw-ratio.ts
17546
- var DRAW_RATIO_DEFAULT = 1;
17547
- function \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio) {
17548
- if (ratio === void 0) return DRAW_RATIO_DEFAULT;
17549
- if (!Number.isFinite(ratio)) return DRAW_RATIO_DEFAULT;
17550
- if (ratio <= 0 || ratio > 1) return DRAW_RATIO_DEFAULT;
17551
- return ratio;
17552
- }
17553
- function \u63CF\u304F\u9032\u307F\u306B\u76F4\u3059(progress, ratio) {
17554
- const \u5272\u5408 = \u63CF\u304F\u5272\u5408\u3092\u6B63\u3059(ratio);
17555
- if (\u5272\u5408 === DRAW_RATIO_DEFAULT) return progress;
17556
- if (!Number.isFinite(progress)) return progress;
17557
- return Math.min(1, progress / \u5272\u5408);
17558
- }
17559
17644
  function CdlStage({
17560
17645
  laid,
17561
17646
  currentPhase,
@@ -17597,6 +17682,26 @@ function CdlStage({
17597
17682
  };
17598
17683
  }, [laid.phases, currentPhase, laid.edgeReveal]);
17599
17684
  const drawSet = new Set(currentPhase?.draw ?? []);
17685
+ const chartLineScales = react.useMemo(() => {
17686
+ const nodes = laid.nodes.filter((node) => node.kind === "chart-line");
17687
+ if (nodes.length === 0) return /* @__PURE__ */ new Map();
17688
+ const frames = [
17689
+ // phase index -1 はどの段にも入る前の初期値。
17690
+ computeStateValues(laid, -1, 0),
17691
+ ...laid.phases.flatMap((_, phaseIndex) => [
17692
+ computeStateValues(laid, phaseIndex, 0),
17693
+ computeStateValues(laid, phaseIndex, 1)
17694
+ ])
17695
+ ];
17696
+ const scales = /* @__PURE__ */ new Map();
17697
+ for (const node of nodes) {
17698
+ const values = frames.flatMap(
17699
+ (stateValues2) => resolveChartData(node.chartData ?? [], stateValues2).map((datum) => datum.value)
17700
+ );
17701
+ scales.set(node.id, \u6298\u308C\u7DDA\u306E\u76EE\u76DB(values));
17702
+ }
17703
+ return scales;
17704
+ }, [laid]);
17600
17705
  const \u63CF\u304F\u9032\u307F = \u63CF\u304F\u9032\u307F\u306B\u76F4\u3059(progress, currentPhase?.drawRatio);
17601
17706
  const { lifelineStarts, uniformFooterTop } = react.useMemo(() => {
17602
17707
  const starts = lifelineStartYs(laid.nodes);
@@ -17605,6 +17710,63 @@ function CdlStage({
17605
17710
  uniformFooterTop: uniformLifelineEndY(laid.lanes, laid.nodes, starts)
17606
17711
  };
17607
17712
  }, [laid]);
17713
+ const edgeHeadMarkers = react.useMemo(() => {
17714
+ const referenced = /* @__PURE__ */ new Set();
17715
+ const add = (tone, head, fill) => {
17716
+ for (const small of [false, true]) {
17717
+ const id = edgeHeadMarkerName(tone, head, small, fill);
17718
+ if (id !== void 0) referenced.add(id);
17719
+ }
17720
+ };
17721
+ for (const edge of laid.edges) {
17722
+ add(edge.tone, edge.head, edge.headFill);
17723
+ if (edge.tailHead !== void 0) add(edge.tone, edge.tailHead, edge.tailHeadFill);
17724
+ }
17725
+ return Object.entries(TONE).flatMap(
17726
+ ([tone, color]) => [
17727
+ [false, 14],
17728
+ [true, 10]
17729
+ ].flatMap(
17730
+ ([small, size]) => EDGE_HEADS.flatMap(
17731
+ (head) => EDGE_HEAD_FILLS.map((fill) => {
17732
+ const \u5F62 = EDGE_HEAD_SHAPE[head];
17733
+ const id = edgeHeadMarkerId(tone, head, small, fill);
17734
+ if (!referenced.has(id) || \u5F62.d === "") return null;
17735
+ if (fill !== EDGE_HEAD_FILL_DEFAULT && !\u5F62.filled) return null;
17736
+ const \u5857 = edgeHeadPaint(head, fill, color);
17737
+ return /* @__PURE__ */ jsxRuntime.jsx(
17738
+ "marker",
17739
+ {
17740
+ id,
17741
+ viewBox: `0 0 ${\u5F62.w} ${\u5F62.h}`,
17742
+ refX: \u5F62.refX,
17743
+ refY: \u5F62.h / 2,
17744
+ markerWidth: size * (\u5F62.scale ?? 1) * \u5F62.w / \u5F62.h,
17745
+ markerHeight: size * (\u5F62.scale ?? 1),
17746
+ markerUnits: "userSpaceOnUse",
17747
+ orient: "auto-start-reverse",
17748
+ children: /* @__PURE__ */ jsxRuntime.jsx(
17749
+ "path",
17750
+ {
17751
+ "data-cdl-role": "edge-arrowhead",
17752
+ "data-cdl-edge-head": head,
17753
+ "data-cdl-edge-head-fill": fill,
17754
+ d: \u5F62.d,
17755
+ fill: \u5857.fill,
17756
+ stroke: \u5857.stroke,
17757
+ strokeWidth: \u5857.strokeWidth,
17758
+ strokeLinecap: \u5857.strokeWidth === void 0 ? void 0 : "round",
17759
+ strokeLinejoin: \u5857.strokeWidth === void 0 ? void 0 : "round"
17760
+ }
17761
+ )
17762
+ },
17763
+ id
17764
+ );
17765
+ })
17766
+ )
17767
+ )
17768
+ );
17769
+ }, [laid]);
17608
17770
  const diagramScale = laid.diagramScale ?? 1;
17609
17771
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: compact ? "px-3 py-3" : "px-6 py-6", style: compact ? void 0 : { minHeight: 460 }, children: [
17610
17772
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -17623,55 +17785,11 @@ function CdlStage({
17623
17785
  "data-cdl-type": laid.type,
17624
17786
  children: [
17625
17787
  /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
17626
- Object.entries(TONE).flatMap(
17627
- ([tone, color]) => [["", 14], ["-sm", 10]].flatMap(
17628
- ([suffix, size]) => EDGE_HEADS.flatMap(
17629
- (head) => (
17630
- // 塗り方は形と別の軸 (#578)。 塗らない形では 2 つが同じ名前に畳まれるので、
17631
- // `edgeHeadMarkerId` が返す名前で重複を外す
17632
- EDGE_HEAD_FILLS.map((fill) => {
17633
- const \u5F62 = EDGE_HEAD_SHAPE[head];
17634
- const id = edgeHeadMarkerId(tone, head, suffix === "-sm", fill);
17635
- if (\u5F62.d === "") return null;
17636
- if (fill !== EDGE_HEAD_FILL_DEFAULT && !\u5F62.filled) return null;
17637
- const \u5857 = edgeHeadPaint(head, fill, color);
17638
- return /* @__PURE__ */ jsxRuntime.jsx(
17639
- "marker",
17640
- {
17641
- id,
17642
- viewBox: `0 0 ${\u5F62.w} ${\u5F62.h}`,
17643
- refX: \u5F62.refX,
17644
- refY: \u5F62.h / 2,
17645
- markerWidth: size * (\u5F62.scale ?? 1) * \u5F62.w / \u5F62.h,
17646
- markerHeight: size * (\u5F62.scale ?? 1),
17647
- markerUnits: "userSpaceOnUse",
17648
- orient: "auto-start-reverse",
17649
- children: /* @__PURE__ */ jsxRuntime.jsx(
17650
- "path",
17651
- {
17652
- "data-cdl-role": "edge-arrowhead",
17653
- "data-cdl-edge-head": head,
17654
- "data-cdl-edge-head-fill": fill,
17655
- d: \u5F62.d,
17656
- fill: \u5857.fill,
17657
- stroke: \u5857.stroke,
17658
- strokeWidth: \u5857.strokeWidth,
17659
- strokeLinecap: \u5857.strokeWidth === void 0 ? void 0 : "round",
17660
- strokeLinejoin: \u5857.strokeWidth === void 0 ? void 0 : "round"
17661
- }
17662
- )
17663
- },
17664
- id
17665
- );
17666
- })
17667
- )
17668
- )
17669
- )
17670
- ),
17788
+ edgeHeadMarkers,
17671
17789
  /* @__PURE__ */ jsxRuntime.jsx(
17672
17790
  "marker",
17673
17791
  {
17674
- id: "cdl-arrow-muted",
17792
+ id: EDGE_HEAD_MUTED_MARKER_ID,
17675
17793
  viewBox: "0 0 10 10",
17676
17794
  refX: "9",
17677
17795
  refY: "5",
@@ -17778,7 +17896,8 @@ function CdlStage({
17778
17896
  drawing: \u63CF\u304F,
17779
17897
  progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
17780
17898
  stateValues,
17781
- currentPhaseId: currentPhase?.id
17899
+ currentPhaseId: currentPhase?.id,
17900
+ chartLineScale: chartLineScales.get(node.id)
17782
17901
  }
17783
17902
  );
17784
17903
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: view }, node.id);