@tetrascience-npm/tetrascience-react-ui 0.6.0-beta.96.1 → 0.6.0-beta.97.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.
@@ -1,45 +1,45 @@
1
- import { jsxs as P, jsx as X } from "react/jsx-runtime";
2
- import L from "plotly.js-dist";
3
- import { useRef as U, useMemo as i, useEffect as V } from "react";
4
- import { useChartTooltip as Y } from "../ChartTooltip/ChartTooltip.js";
5
- import { usePlotlyTheme as j } from "../../../hooks/use-plotly-theme.js";
6
- import { seriesColor as G } from "../../../utils/colors.js";
7
- const K = ({
1
+ import { jsxs as X, jsx as B } from "react/jsx-runtime";
2
+ import P from "plotly.js-dist";
3
+ import { useRef as O, useMemo as s, useEffect as U } from "react";
4
+ import { useChartTooltip as V } from "../ChartTooltip/ChartTooltip.js";
5
+ import { usePlotlyTheme as G } from "../../../hooks/use-plotly-theme.js";
6
+ import { seriesColor as Y } from "../../../utils/colors.js";
7
+ const j = 60, T = 30, Q = ({
8
8
  dataSeries: a,
9
- width: k = 1e3,
10
- height: w = 600,
11
- xRange: g,
12
- yRange: s,
9
+ width: w = 1e3,
10
+ height: b = 600,
11
+ xRange: d,
12
+ yRange: i,
13
13
  variant: p = "group",
14
- xTitle: d = "Columns",
15
- yTitle: y = "Rows",
16
- title: b = "Bar Graph",
17
- barWidth: C = 24,
18
- xTickText: u
14
+ xTitle: y = "Columns",
15
+ yTitle: M = "Rows",
16
+ title: u,
17
+ barWidth: _ = 24,
18
+ xTickText: h
19
19
  }) => {
20
- const c = U(null), r = j(), { bindTooltip: E, tooltipElement: B } = Y({ xLabel: d, yLabel: y }), { yMin: I, yMax: _ } = i(() => {
20
+ const c = O(null), r = G(), { bindTooltip: E, tooltipElement: z } = V({ xLabel: y, yLabel: M }), { yMin: I, yMax: C } = s(() => {
21
21
  let t = Number.MAX_VALUE, o = Number.MIN_VALUE, n = Number.MAX_VALUE, e = Number.MIN_VALUE;
22
- a.forEach((A) => {
23
- A.x.forEach((m) => {
22
+ a.forEach((v) => {
23
+ v.x.forEach((m) => {
24
24
  t = Math.min(t, m), o = Math.max(o, m);
25
- }), A.y.forEach((m) => {
25
+ }), v.y.forEach((m) => {
26
26
  n = Math.min(n, m), e = Math.max(e, m);
27
27
  });
28
28
  });
29
- const l = (o - t) * 0.1, h = (e - n) * 0.1;
29
+ const l = (o - t) * 0.1, g = (e - n) * 0.1;
30
30
  return {
31
31
  xMin: t - l,
32
32
  xMax: o + l,
33
- yMin: p === "stack" ? 0 : n - h,
34
- yMax: e + h
33
+ yMin: p === "stack" ? 0 : n - g,
34
+ yMax: e + g
35
35
  };
36
- }, [a, p]), f = i(
37
- () => s || [I, _],
38
- [s, I, _]
39
- ), M = i(
36
+ }, [a, p]), f = s(
37
+ () => i || [I, C],
38
+ [i, I, C]
39
+ ), x = s(
40
40
  () => [...new Set(a.flatMap((t) => t.x))].sort((t, o) => t - o),
41
41
  [a]
42
- ), v = !!u && u.length === M.length, N = i(() => {
42
+ ), N = !!h && h.length === x.length, A = s(() => {
43
43
  const t = f[1] - f[0];
44
44
  let o = Math.pow(10, Math.floor(Math.log10(t)));
45
45
  t / o > 10 && (o = o * 2), t / o < 4 && (o = o / 2);
@@ -48,7 +48,7 @@ const K = ({
48
48
  for (; e <= f[1]; )
49
49
  n.push(e), e += o;
50
50
  return n;
51
- }, [f]), z = i(() => {
51
+ }, [f]), L = s(() => {
52
52
  switch (p) {
53
53
  case "stack":
54
54
  return "stack";
@@ -57,7 +57,7 @@ const K = ({
57
57
  default:
58
58
  return "group";
59
59
  }
60
- }, [p]), x = i(
60
+ }, [p]), k = s(
61
61
  () => ({
62
62
  tickcolor: r.tickColor,
63
63
  ticklen: 12,
@@ -76,42 +76,50 @@ const K = ({
76
76
  }),
77
77
  [r]
78
78
  );
79
- return V(() => {
79
+ return U(() => {
80
80
  if (!c.current) return;
81
- const t = a.map((l, h) => ({
81
+ const t = a.map((l, g) => ({
82
82
  x: l.x,
83
83
  y: l.y,
84
84
  type: "bar",
85
85
  name: l.name,
86
86
  hoverinfo: "none",
87
87
  marker: {
88
- color: G(h, l.color)
88
+ color: Y(g, l.color)
89
89
  },
90
- width: C,
90
+ width: _,
91
91
  error_y: l.error_y
92
92
  })), o = {
93
- title: {
94
- text: b,
95
- font: {
96
- size: 32,
97
- family: "Inter, sans-serif",
98
- color: r.textColor
93
+ ...u ? {
94
+ title: {
95
+ text: u,
96
+ font: {
97
+ size: 32,
98
+ family: "Inter, sans-serif",
99
+ color: r.textColor
100
+ }
99
101
  }
102
+ } : {},
103
+ width: w,
104
+ height: b,
105
+ margin: {
106
+ l: 80,
107
+ r: 30,
108
+ b: 80,
109
+ t: u ? j : T,
110
+ pad: 0
100
111
  },
101
- width: k,
102
- height: w,
103
- margin: { l: 80, r: 30, b: 80, t: 60, pad: 0 },
104
112
  paper_bgcolor: r.paperBg,
105
113
  plot_bgcolor: r.plotBg,
106
114
  font: {
107
115
  family: "Inter, sans-serif"
108
116
  },
109
- barmode: z,
117
+ barmode: L,
110
118
  bargap: 0.15,
111
119
  dragmode: !1,
112
120
  xaxis: {
113
121
  title: {
114
- text: d,
122
+ text: y,
115
123
  font: {
116
124
  size: 16,
117
125
  color: r.textSecondary,
@@ -121,17 +129,17 @@ const K = ({
121
129
  standoff: 32
122
130
  },
123
131
  gridcolor: r.gridColor,
124
- range: g,
125
- autorange: !g,
132
+ range: d,
133
+ autorange: !d,
126
134
  tickmode: "array",
127
- tickvals: M,
128
- ...v ? { ticktext: u } : {},
135
+ tickvals: x,
136
+ ...N ? { ticktext: h } : {},
129
137
  showgrid: !0,
130
- ...x
138
+ ...k
131
139
  },
132
140
  yaxis: {
133
141
  title: {
134
- text: y,
142
+ text: M,
135
143
  font: {
136
144
  size: 16,
137
145
  color: r.textSecondary,
@@ -141,12 +149,12 @@ const K = ({
141
149
  standoff: 30
142
150
  },
143
151
  gridcolor: r.gridColor,
144
- range: s,
145
- autorange: !s,
152
+ range: i,
153
+ autorange: !i,
146
154
  tickmode: "array",
147
- tickvals: N,
155
+ tickvals: A,
148
156
  showgrid: !0,
149
- ...x
157
+ ...k
150
158
  },
151
159
  legend: {
152
160
  x: 0.5,
@@ -167,17 +175,17 @@ const K = ({
167
175
  displayModeBar: !1,
168
176
  displaylogo: !1
169
177
  };
170
- L.newPlot(c.current, t, o, n), E(c.current);
178
+ P.newPlot(c.current, t, o, n), E(c.current);
171
179
  const e = c.current;
172
180
  return () => {
173
- e && L.purge(e);
181
+ e && P.purge(e);
174
182
  };
175
- }, [a, k, w, g, s, d, y, b, C, z, x, M, N, v, u, r, E]), /* @__PURE__ */ P("div", { className: "bar-graph-container relative", children: [
176
- /* @__PURE__ */ X("div", { ref: c, style: { width: "100%", height: "100%" } }),
177
- B
183
+ }, [a, w, b, d, i, y, M, u, _, L, k, x, A, N, h, r, E]), /* @__PURE__ */ X("div", { className: "bar-graph-container relative", children: [
184
+ /* @__PURE__ */ B("div", { ref: c, style: { width: "100%", height: "100%" } }),
185
+ z
178
186
  ] });
179
187
  };
180
188
  export {
181
- K as BarGraph
189
+ Q as BarGraph
182
190
  };
183
191
  //# sourceMappingURL=BarGraph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BarGraph.js","sources":["../../../../src/components/charts/BarGraph/BarGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface BarDataSeries {\n x: number[];\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n error_y?: {\n type: \"data\";\n array: number[];\n visible: boolean;\n };\n}\n\ntype BarGraphVariant = \"group\" | \"stack\" | \"overlay\";\n\ninterface BarGraphProps {\n dataSeries: BarDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: BarGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n barWidth?: number;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive bar positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n}\n\nconst BarGraph: React.FC<BarGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"group\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Bar Graph\",\n barWidth = 24,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n const { yMin, yMax } = useMemo(() => {\n let minX = Number.MAX_VALUE;\n let maxX = Number.MIN_VALUE;\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.x.forEach((x) => {\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n });\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const xPadding = (maxX - minX) * 0.1;\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n xMin: minX - xPadding,\n xMax: maxX + xPadding,\n yMin: variant === \"stack\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xTicks.length;\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const barMode = useMemo((): \"group\" | \"stack\" | \"overlay\" => {\n switch (variant) {\n case \"stack\":\n return \"stack\";\n case \"overlay\":\n return \"overlay\";\n case \"group\":\n default:\n return \"group\";\n }\n }, [variant]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const data = dataSeries.map((series, index) => ({\n x: series.x,\n y: series.y,\n type: \"bar\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color: seriesColor(index, series.color),\n },\n width: barWidth,\n error_y: series.error_y,\n }));\n\n const layout = {\n title: {\n text: title,\n font: {\n size: 32,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n },\n width,\n height,\n margin: { l: 80, r: 30, b: 80, t: 60, pad: 0 },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n barmode: barMode,\n bargap: 0.15,\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 32,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n tickmode: \"array\" as const,\n tickvals: xTicks,\n ...(useCategoricalX ? { ticktext: xTickText } : {}),\n showgrid: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 30,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n ...tickOptions,\n },\n legend: {\n x: 0.5,\n y: -0.2,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n orientation: \"h\" as const,\n font: {\n size: 16,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n },\n },\n showlegend: dataSeries.length > 1,\n };\n\n const config = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n // Cleanup function\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [dataSeries, width, height, xRange, yRange, xTitle, yTitle, title, barWidth, barMode, tickOptions, xTicks, yTicks, useCategoricalX, xTickText, theme, bindTooltip]);\n\n return (\n <div className=\"bar-graph-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { BarGraph };\nexport type { BarDataSeries, BarGraphVariant, BarGraphProps };\n"],"names":["BarGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","barWidth","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","xTicks","s","a","b","useCategoricalX","yTicks","range","step","ticks","current","barMode","tickOptions","useEffect","data","index","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"BarGraph.js","sources":["../../../../src/components/charts/BarGraph/BarGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface BarDataSeries {\n x: number[];\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n error_y?: {\n type: \"data\";\n array: number[];\n visible: boolean;\n };\n}\n\ntype BarGraphVariant = \"group\" | \"stack\" | \"overlay\";\n\n/** Top margin reserving room for the 32px title; reduced when no title is set */\nconst TITLE_MARGIN_TOP = 60;\nconst NO_TITLE_MARGIN_TOP = 30;\n\ninterface BarGraphProps {\n dataSeries: BarDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: BarGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n barWidth?: number;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive bar positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n}\n\nconst BarGraph: React.FC<BarGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"group\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title,\n barWidth = 24,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n const { yMin, yMax } = useMemo(() => {\n let minX = Number.MAX_VALUE;\n let maxX = Number.MIN_VALUE;\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.x.forEach((x) => {\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n });\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const xPadding = (maxX - minX) * 0.1;\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n xMin: minX - xPadding,\n xMax: maxX + xPadding,\n yMin: variant === \"stack\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xTicks.length;\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const barMode = useMemo((): \"group\" | \"stack\" | \"overlay\" => {\n switch (variant) {\n case \"stack\":\n return \"stack\";\n case \"overlay\":\n return \"overlay\";\n case \"group\":\n default:\n return \"group\";\n }\n }, [variant]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const data = dataSeries.map((series, index) => ({\n x: series.x,\n y: series.y,\n type: \"bar\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color: seriesColor(index, series.color),\n },\n width: barWidth,\n error_y: series.error_y,\n }));\n\n const layout = {\n ...(title\n ? {\n title: {\n text: title,\n font: {\n size: 32,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n },\n }\n : {}),\n width,\n height,\n margin: {\n l: 80,\n r: 30,\n b: 80,\n t: title ? TITLE_MARGIN_TOP : NO_TITLE_MARGIN_TOP,\n pad: 0,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n barmode: barMode,\n bargap: 0.15,\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 32,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n tickmode: \"array\" as const,\n tickvals: xTicks,\n ...(useCategoricalX ? { ticktext: xTickText } : {}),\n showgrid: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 30,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n ...tickOptions,\n },\n legend: {\n x: 0.5,\n y: -0.2,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n orientation: \"h\" as const,\n font: {\n size: 16,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n },\n },\n showlegend: dataSeries.length > 1,\n };\n\n const config = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n // Cleanup function\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [dataSeries, width, height, xRange, yRange, xTitle, yTitle, title, barWidth, barMode, tickOptions, xTicks, yTicks, useCategoricalX, xTickText, theme, bindTooltip]);\n\n return (\n <div className=\"bar-graph-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { BarGraph };\nexport type { BarDataSeries, BarGraphVariant, BarGraphProps };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","BarGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","barWidth","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","xTicks","s","a","b","useCategoricalX","yTicks","range","step","ticks","current","barMode","tickOptions","useEffect","data","index","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("react/jsx-runtime"),P=require("plotly.js-dist"),l=require("react"),A=require("../ChartTooltip/ChartTooltip.cjs"),X=require("../../../hooks/use-plotly-theme.cjs"),j=require("../../../utils/colors.cjs"),U=({dataSeries:i,width:b=1e3,height:w=600,xRange:g,yRange:u,variant:m="lines",xTitle:M="Columns",yTitle:x="Rows",title:C="Line Graph",xTickText:p})=>{const f=l.useRef(null),o=X.usePlotlyTheme(),{bindTooltip:E,tooltipElement:q}=A.useChartTooltip({xLabel:M,yLabel:x}),{yMin:_,yMax:L}=l.useMemo(()=>{let t=Number.MAX_VALUE,e=Number.MIN_VALUE,s=Number.MAX_VALUE,r=Number.MIN_VALUE;i.forEach(c=>{c.x.forEach(h=>{t=Math.min(t,h),e=Math.max(e,h)}),c.y.forEach(h=>{s=Math.min(s,h),r=Math.max(r,h)})});const n=(e-t)*.1,y=(r-s)*.1;return{xMin:t-n,xMax:e+n,yMin:s-y,yMax:r+y}},[i]),a=l.useMemo(()=>u||[_,L],[u,_,L]),z=l.useMemo(()=>{const t=a[1]-a[0];let e=Math.pow(10,Math.floor(Math.log10(t)));t/e>10&&(e=e*2),t/e<4&&(e=e/2);const s=[];let r=Math.ceil(a[0]/e)*e;for(;r<=a[1];)s.push(r),r+=e;return s},[a]),d=l.useMemo(()=>[...new Set(i.flatMap(t=>t.x))].sort((t,e)=>t-e),[i]),I=!!p&&p.length===d.length,v=l.useMemo(()=>{switch(m){case"lines+markers":case"lines+markers+error_bars":return"lines+markers";default:return"lines"}},[m]),k=l.useMemo(()=>({tickcolor:o.tickColor,ticklen:12,tickwidth:1,ticks:"outside",tickfont:{size:16,color:o.textColor,family:"Inter, sans-serif",weight:400},linecolor:o.lineColor,linewidth:1,position:0,zeroline:!1}),[o]);return l.useEffect(()=>{if(!f.current)return;const t=i.map((n,y)=>{const c=j.seriesColor(y,n.color);return{x:n.x,y:n.y,type:"scatter",mode:v,name:n.name,hoverinfo:"none",line:{color:c,width:1.5},marker:m==="lines"?{opacity:0}:{color:c,size:8,symbol:n.symbol||"triangle-up"},error_y:m==="lines+markers+error_bars"?n.error_y||{type:"data",array:n.y.map(()=>10),visible:!0,color:c,thickness:1,width:5}:void 0}}),e={title:{text:C,font:{size:32,family:"Inter, sans-serif",color:o.textColor}},width:b,height:w,margin:{l:80,r:30,b:80,t:60,pad:10},paper_bgcolor:o.paperBg,plot_bgcolor:o.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:M,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:32},gridcolor:o.gridColor,range:g,autorange:!g,tickmode:"array",tickvals:d,ticktext:I?p:d.map(String),showgrid:!0,...k},yaxis:{title:{text:x,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:30},gridcolor:o.gridColor,range:u,autorange:!u,tickmode:"array",tickvals:z,showgrid:!0,...k},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:16,color:o.legendColor,family:"Inter, sans-serif",weight:500}},showlegend:!0},s={responsive:!0,displayModeBar:!1,displaylogo:!1};P.newPlot(f.current,t,e,s),E(f.current);const r=f.current;return()=>{r&&P.purge(r)}},[i,b,w,g,u,M,x,C,v,k,d,z,I,p,a,m,o,E]),N.jsxs("div",{className:"relative size-full",children:[N.jsx("div",{ref:f,style:{width:"100%",height:"100%"}}),q]})};exports.LineGraph=U;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const z=require("react/jsx-runtime"),A=require("plotly.js-dist"),l=require("react"),q=require("../ChartTooltip/ChartTooltip.cjs"),O=require("../../../hooks/use-plotly-theme.cjs"),X=require("../../../utils/colors.cjs"),j=60,G=30,T=({dataSeries:i,width:w=1e3,height:_=600,xRange:M,yRange:u,variant:m="lines",xTitle:x="Columns",yTitle:k="Rows",title:d,xTickText:p})=>{const f=l.useRef(null),t=O.usePlotlyTheme(),{bindTooltip:C,tooltipElement:v}=q.useChartTooltip({xLabel:x,yLabel:k}),{yMin:E,yMax:I}=l.useMemo(()=>{let o=Number.MAX_VALUE,e=Number.MIN_VALUE,s=Number.MAX_VALUE,r=Number.MIN_VALUE;i.forEach(c=>{c.x.forEach(h=>{o=Math.min(o,h),e=Math.max(e,h)}),c.y.forEach(h=>{s=Math.min(s,h),r=Math.max(r,h)})});const n=(e-o)*.1,g=(r-s)*.1;return{xMin:o-n,xMax:e+n,yMin:s-g,yMax:r+g}},[i]),a=l.useMemo(()=>u||[E,I],[u,E,I]),L=l.useMemo(()=>{const o=a[1]-a[0];let e=Math.pow(10,Math.floor(Math.log10(o)));o/e>10&&(e=e*2),o/e<4&&(e=e/2);const s=[];let r=Math.ceil(a[0]/e)*e;for(;r<=a[1];)s.push(r),r+=e;return s},[a]),y=l.useMemo(()=>[...new Set(i.flatMap(o=>o.x))].sort((o,e)=>o-e),[i]),N=!!p&&p.length===y.length,P=l.useMemo(()=>{switch(m){case"lines+markers":case"lines+markers+error_bars":return"lines+markers";default:return"lines"}},[m]),b=l.useMemo(()=>({tickcolor:t.tickColor,ticklen:12,tickwidth:1,ticks:"outside",tickfont:{size:16,color:t.textColor,family:"Inter, sans-serif",weight:400},linecolor:t.lineColor,linewidth:1,position:0,zeroline:!1}),[t]);return l.useEffect(()=>{if(!f.current)return;const o=i.map((n,g)=>{const c=X.seriesColor(g,n.color);return{x:n.x,y:n.y,type:"scatter",mode:P,name:n.name,hoverinfo:"none",line:{color:c,width:1.5},marker:m==="lines"?{opacity:0}:{color:c,size:8,symbol:n.symbol||"triangle-up"},error_y:m==="lines+markers+error_bars"?n.error_y||{type:"data",array:n.y.map(()=>10),visible:!0,color:c,thickness:1,width:5}:void 0}}),e={...d?{title:{text:d,font:{size:32,family:"Inter, sans-serif",color:t.textColor}}}:{},width:w,height:_,margin:{l:80,r:30,b:80,t:d?j:G,pad:10},paper_bgcolor:t.paperBg,plot_bgcolor:t.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:x,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:32},gridcolor:t.gridColor,range:M,autorange:!M,tickmode:"array",tickvals:y,ticktext:N?p:y.map(String),showgrid:!0,...b},yaxis:{title:{text:k,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:30},gridcolor:t.gridColor,range:u,autorange:!u,tickmode:"array",tickvals:L,showgrid:!0,...b},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:16,color:t.legendColor,family:"Inter, sans-serif",weight:500}},showlegend:!0},s={responsive:!0,displayModeBar:!1,displaylogo:!1};A.newPlot(f.current,o,e,s),C(f.current);const r=f.current;return()=>{r&&A.purge(r)}},[i,w,_,M,u,x,k,d,P,b,y,L,N,p,a,m,t,C]),z.jsxs("div",{className:"relative size-full",children:[z.jsx("div",{ref:f,style:{width:"100%",height:"100%"}}),v]})};exports.LineGraph=T;
2
2
  //# sourceMappingURL=LineGraph.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"LineGraph.cjs","sources":["../../../../src/components/charts/LineGraph/LineGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ntype MarkerSymbol =\n | \"circle\"\n | \"circle-open\"\n | \"circle-dot\"\n | \"circle-open-dot\"\n | \"square\"\n | \"square-open\"\n | \"square-dot\"\n | \"square-open-dot\"\n | \"diamond\"\n | \"diamond-open\"\n | \"diamond-dot\"\n | \"diamond-open-dot\"\n | \"cross\"\n | \"cross-open\"\n | \"cross-dot\"\n | \"cross-open-dot\"\n | \"x\"\n | \"x-open\"\n | \"x-dot\"\n | \"x-open-dot\"\n | \"triangle-up\"\n | \"triangle-up-open\"\n | \"triangle-up-dot\"\n | \"triangle-up-open-dot\"\n | \"triangle-down\"\n | \"triangle-down-open\"\n | \"triangle-down-dot\"\n | \"triangle-down-open-dot\"\n | \"triangle-left\"\n | \"triangle-left-open\"\n | \"triangle-left-dot\"\n | \"triangle-left-open-dot\"\n | \"triangle-right\"\n | \"triangle-right-open\"\n | \"triangle-right-dot\"\n | \"triangle-right-open-dot\"\n | \"triangle-ne\"\n | \"triangle-ne-open\"\n | \"triangle-ne-dot\"\n | \"triangle-ne-open-dot\"\n | \"triangle-se\"\n | \"triangle-se-open\"\n | \"triangle-se-dot\"\n | \"triangle-se-open-dot\"\n | \"triangle-sw\"\n | \"triangle-sw-open\"\n | \"triangle-sw-dot\"\n | \"triangle-sw-open-dot\"\n | \"triangle-nw\"\n | \"triangle-nw-open\"\n | \"triangle-nw-dot\"\n | \"triangle-nw-open-dot\"\n | \"pentagon\"\n | \"pentagon-open\"\n | \"pentagon-dot\"\n | \"pentagon-open-dot\"\n | \"hexagon\"\n | \"hexagon-open\"\n | \"hexagon-dot\"\n | \"hexagon-open-dot\"\n | \"hexagon2\"\n | \"hexagon2-open\"\n | \"hexagon2-dot\"\n | \"hexagon2-open-dot\"\n | \"octagon\"\n | \"octagon-open\"\n | \"octagon-dot\"\n | \"octagon-open-dot\"\n | \"star\"\n | \"star-open\"\n | \"star-dot\"\n | \"star-open-dot\"\n | \"hexagram\"\n | \"hexagram-open\"\n | \"hexagram-dot\"\n | \"hexagram-open-dot\"\n | \"star-triangle-up\"\n | \"star-triangle-up-open\"\n | \"star-triangle-up-dot\"\n | \"star-triangle-up-open-dot\"\n | \"star-triangle-down\"\n | \"star-triangle-down-open\"\n | \"star-triangle-down-dot\"\n | \"star-triangle-down-open-dot\"\n | \"star-square\"\n | \"star-square-open\"\n | \"star-square-dot\"\n | \"star-square-open-dot\"\n | \"star-diamond\"\n | \"star-diamond-open\"\n | \"star-diamond-dot\"\n | \"star-diamond-open-dot\"\n | \"diamond-tall\"\n | \"diamond-tall-open\"\n | \"diamond-tall-dot\"\n | \"diamond-tall-open-dot\"\n | \"diamond-wide\"\n | \"diamond-wide-open\"\n | \"diamond-wide-dot\"\n | \"diamond-wide-open-dot\"\n | \"hourglass\"\n | \"hourglass-open\"\n | \"bowtie\"\n | \"bowtie-open\"\n | \"circle-cross\"\n | \"circle-cross-open\"\n | \"circle-x\"\n | \"circle-x-open\"\n | \"square-cross\"\n | \"square-cross-open\"\n | \"square-x\"\n | \"square-x-open\"\n | \"diamond-cross\"\n | \"diamond-cross-open\"\n | \"diamond-x\"\n | \"diamond-x-open\"\n | \"cross-thin\"\n | \"cross-thin-open\"\n | \"x-thin\"\n | \"x-thin-open\"\n | \"asterisk\"\n | \"asterisk-open\"\n | \"hash\"\n | \"hash-open\"\n | \"hash-dot\"\n | \"hash-open-dot\"\n | \"y-up\"\n | \"y-up-open\"\n | \"y-down\"\n | \"y-down-open\"\n | \"y-left\"\n | \"y-left-open\"\n | \"y-right\"\n | \"y-right-open\"\n | \"line-ew\"\n | \"line-ew-open\"\n | \"line-ns\"\n | \"line-ns-open\"\n | \"line-ne\"\n | \"line-ne-open\"\n | \"line-nw\"\n | \"line-nw-open\"\n | \"arrow\"\n | \"arrow-open\"\n | \"arrow-wide\"\n | \"arrow-wide-open\";\n\ninterface LineDataSeries {\n x: number[];\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n symbol?: MarkerSymbol;\n error_y?: {\n type: \"data\";\n array: number[];\n visible: boolean;\n };\n}\n\ntype LineGraphVariant = \"lines\" | \"lines+markers\" | \"lines+markers+error_bars\";\n\ntype LineGraphProps = {\n dataSeries: LineDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: LineGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive line positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n};\n\nconst LineGraph: React.FC<LineGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"lines\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Line Graph\",\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n const { yMin, yMax } = useMemo(() => {\n let minX = Number.MAX_VALUE;\n let maxX = Number.MIN_VALUE;\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.x.forEach((x) => {\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n });\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const xPadding = (maxX - minX) * 0.1;\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n xMin: minX - xPadding,\n xMax: maxX + xPadding,\n yMin: minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const xTicks = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xTicks.length;\n\n const mode = useMemo((): \"lines\" | \"lines+markers\" => {\n switch (variant) {\n case \"lines+markers\":\n case \"lines+markers+error_bars\":\n return \"lines+markers\";\n default:\n return \"lines\";\n }\n }, [variant]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const plotData = dataSeries.map((series, index) => {\n const color = seriesColor(index, series.color);\n return {\n x: series.x,\n y: series.y,\n type: \"scatter\" as const,\n mode: mode,\n name: series.name,\n hoverinfo: \"none\" as const,\n line: {\n color,\n width: 1.5,\n },\n marker:\n variant === \"lines\"\n ? { opacity: 0 }\n : {\n color,\n size: 8,\n symbol: series.symbol || \"triangle-up\",\n },\n error_y:\n variant === \"lines+markers+error_bars\"\n ? series.error_y || {\n type: \"data\" as const,\n array: series.y.map(() => 10),\n visible: true,\n color,\n thickness: 1,\n width: 5,\n }\n : undefined,\n };\n });\n\n const layout = {\n title: {\n text: title,\n font: {\n size: 32,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n },\n width,\n height,\n margin: { l: 80, r: 30, b: 80, t: 60, pad: 10 },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 32,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n tickmode: \"array\" as const,\n tickvals: xTicks,\n ticktext: useCategoricalX ? xTickText : xTicks.map(String),\n showgrid: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 30,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n ...tickOptions,\n },\n legend: {\n x: 0.5,\n y: -0.2,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n orientation: \"h\" as const,\n font: {\n size: 16,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n },\n },\n showlegend: true,\n };\n\n const config = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, plotData, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [dataSeries, width, height, xRange, yRange, xTitle, yTitle, title, mode, tickOptions, xTicks, yTicks, useCategoricalX, xTickText, effectiveYRange, variant, theme, bindTooltip]);\n\n return (\n <div className=\"relative size-full\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { LineGraph };\nexport type { LineDataSeries, LineGraphVariant, LineGraphProps, MarkerSymbol };\n"],"names":["LineGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","yTicks","range","step","ticks","current","xTicks","s","a","b","useCategoricalX","mode","tickOptions","useEffect","plotData","index","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"LineGraph.cjs","sources":["../../../../src/components/charts/LineGraph/LineGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ntype MarkerSymbol =\n | \"circle\"\n | \"circle-open\"\n | \"circle-dot\"\n | \"circle-open-dot\"\n | \"square\"\n | \"square-open\"\n | \"square-dot\"\n | \"square-open-dot\"\n | \"diamond\"\n | \"diamond-open\"\n | \"diamond-dot\"\n | \"diamond-open-dot\"\n | \"cross\"\n | \"cross-open\"\n | \"cross-dot\"\n | \"cross-open-dot\"\n | \"x\"\n | \"x-open\"\n | \"x-dot\"\n | \"x-open-dot\"\n | \"triangle-up\"\n | \"triangle-up-open\"\n | \"triangle-up-dot\"\n | \"triangle-up-open-dot\"\n | \"triangle-down\"\n | \"triangle-down-open\"\n | \"triangle-down-dot\"\n | \"triangle-down-open-dot\"\n | \"triangle-left\"\n | \"triangle-left-open\"\n | \"triangle-left-dot\"\n | \"triangle-left-open-dot\"\n | \"triangle-right\"\n | \"triangle-right-open\"\n | \"triangle-right-dot\"\n | \"triangle-right-open-dot\"\n | \"triangle-ne\"\n | \"triangle-ne-open\"\n | \"triangle-ne-dot\"\n | \"triangle-ne-open-dot\"\n | \"triangle-se\"\n | \"triangle-se-open\"\n | \"triangle-se-dot\"\n | \"triangle-se-open-dot\"\n | \"triangle-sw\"\n | \"triangle-sw-open\"\n | \"triangle-sw-dot\"\n | \"triangle-sw-open-dot\"\n | \"triangle-nw\"\n | \"triangle-nw-open\"\n | \"triangle-nw-dot\"\n | \"triangle-nw-open-dot\"\n | \"pentagon\"\n | \"pentagon-open\"\n | \"pentagon-dot\"\n | \"pentagon-open-dot\"\n | \"hexagon\"\n | \"hexagon-open\"\n | \"hexagon-dot\"\n | \"hexagon-open-dot\"\n | \"hexagon2\"\n | \"hexagon2-open\"\n | \"hexagon2-dot\"\n | \"hexagon2-open-dot\"\n | \"octagon\"\n | \"octagon-open\"\n | \"octagon-dot\"\n | \"octagon-open-dot\"\n | \"star\"\n | \"star-open\"\n | \"star-dot\"\n | \"star-open-dot\"\n | \"hexagram\"\n | \"hexagram-open\"\n | \"hexagram-dot\"\n | \"hexagram-open-dot\"\n | \"star-triangle-up\"\n | \"star-triangle-up-open\"\n | \"star-triangle-up-dot\"\n | \"star-triangle-up-open-dot\"\n | \"star-triangle-down\"\n | \"star-triangle-down-open\"\n | \"star-triangle-down-dot\"\n | \"star-triangle-down-open-dot\"\n | \"star-square\"\n | \"star-square-open\"\n | \"star-square-dot\"\n | \"star-square-open-dot\"\n | \"star-diamond\"\n | \"star-diamond-open\"\n | \"star-diamond-dot\"\n | \"star-diamond-open-dot\"\n | \"diamond-tall\"\n | \"diamond-tall-open\"\n | \"diamond-tall-dot\"\n | \"diamond-tall-open-dot\"\n | \"diamond-wide\"\n | \"diamond-wide-open\"\n | \"diamond-wide-dot\"\n | \"diamond-wide-open-dot\"\n | \"hourglass\"\n | \"hourglass-open\"\n | \"bowtie\"\n | \"bowtie-open\"\n | \"circle-cross\"\n | \"circle-cross-open\"\n | \"circle-x\"\n | \"circle-x-open\"\n | \"square-cross\"\n | \"square-cross-open\"\n | \"square-x\"\n | \"square-x-open\"\n | \"diamond-cross\"\n | \"diamond-cross-open\"\n | \"diamond-x\"\n | \"diamond-x-open\"\n | \"cross-thin\"\n | \"cross-thin-open\"\n | \"x-thin\"\n | \"x-thin-open\"\n | \"asterisk\"\n | \"asterisk-open\"\n | \"hash\"\n | \"hash-open\"\n | \"hash-dot\"\n | \"hash-open-dot\"\n | \"y-up\"\n | \"y-up-open\"\n | \"y-down\"\n | \"y-down-open\"\n | \"y-left\"\n | \"y-left-open\"\n | \"y-right\"\n | \"y-right-open\"\n | \"line-ew\"\n | \"line-ew-open\"\n | \"line-ns\"\n | \"line-ns-open\"\n | \"line-ne\"\n | \"line-ne-open\"\n | \"line-nw\"\n | \"line-nw-open\"\n | \"arrow\"\n | \"arrow-open\"\n | \"arrow-wide\"\n | \"arrow-wide-open\";\n\ninterface LineDataSeries {\n x: number[];\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n symbol?: MarkerSymbol;\n error_y?: {\n type: \"data\";\n array: number[];\n visible: boolean;\n };\n}\n\ntype LineGraphVariant = \"lines\" | \"lines+markers\" | \"lines+markers+error_bars\";\n\n/** Top margin reserving room for the 32px title; reduced when no title is set */\nconst TITLE_MARGIN_TOP = 60;\nconst NO_TITLE_MARGIN_TOP = 30;\n\ntype LineGraphProps = {\n dataSeries: LineDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: LineGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive line positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n};\n\nconst LineGraph: React.FC<LineGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"lines\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n const { yMin, yMax } = useMemo(() => {\n let minX = Number.MAX_VALUE;\n let maxX = Number.MIN_VALUE;\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.x.forEach((x) => {\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n });\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const xPadding = (maxX - minX) * 0.1;\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n xMin: minX - xPadding,\n xMax: maxX + xPadding,\n yMin: minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const xTicks = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xTicks.length;\n\n const mode = useMemo((): \"lines\" | \"lines+markers\" => {\n switch (variant) {\n case \"lines+markers\":\n case \"lines+markers+error_bars\":\n return \"lines+markers\";\n default:\n return \"lines\";\n }\n }, [variant]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const plotData = dataSeries.map((series, index) => {\n const color = seriesColor(index, series.color);\n return {\n x: series.x,\n y: series.y,\n type: \"scatter\" as const,\n mode: mode,\n name: series.name,\n hoverinfo: \"none\" as const,\n line: {\n color,\n width: 1.5,\n },\n marker:\n variant === \"lines\"\n ? { opacity: 0 }\n : {\n color,\n size: 8,\n symbol: series.symbol || \"triangle-up\",\n },\n error_y:\n variant === \"lines+markers+error_bars\"\n ? series.error_y || {\n type: \"data\" as const,\n array: series.y.map(() => 10),\n visible: true,\n color,\n thickness: 1,\n width: 5,\n }\n : undefined,\n };\n });\n\n const layout = {\n ...(title\n ? {\n title: {\n text: title,\n font: {\n size: 32,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n },\n }\n : {}),\n width,\n height,\n margin: {\n l: 80,\n r: 30,\n b: 80,\n t: title ? TITLE_MARGIN_TOP : NO_TITLE_MARGIN_TOP,\n pad: 10,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 32,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n tickmode: \"array\" as const,\n tickvals: xTicks,\n ticktext: useCategoricalX ? xTickText : xTicks.map(String),\n showgrid: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 30,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n ...tickOptions,\n },\n legend: {\n x: 0.5,\n y: -0.2,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n orientation: \"h\" as const,\n font: {\n size: 16,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n },\n },\n showlegend: true,\n };\n\n const config = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, plotData, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [dataSeries, width, height, xRange, yRange, xTitle, yTitle, title, mode, tickOptions, xTicks, yTicks, useCategoricalX, xTickText, effectiveYRange, variant, theme, bindTooltip]);\n\n return (\n <div className=\"relative size-full\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { LineGraph };\nexport type { LineDataSeries, LineGraphVariant, LineGraphProps, MarkerSymbol };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","LineGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","yTicks","range","step","ticks","current","xTicks","s","a","b","useCategoricalX","mode","tickOptions","useEffect","plotData","index","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"0SA6KMA,EAAmB,GACnBC,EAAsB,GAqBtBC,EAAsC,CAAC,CAC3C,WAAAC,EACA,MAAAC,EAAQ,IACR,OAAAC,EAAS,IACT,OAAAC,EACA,OAAAC,EACA,QAAAC,EAAU,QACV,OAAAC,EAAS,UACT,OAAAC,EAAS,OACT,MAAAC,EACA,UAAAC,CACF,IAAM,CACJ,MAAMC,EAAUC,EAAAA,OAAuB,IAAI,EACrCC,EAAQC,EAAAA,eAAA,EACR,CAAE,YAAAC,EAAa,eAAAC,CAAA,EAAmBC,EAAAA,gBAAgB,CAAE,OAAQV,EAAQ,OAAQC,EAAQ,EAEpF,CAAE,KAAAU,EAAM,KAAAC,CAAA,EAASC,EAAAA,QAAQ,IAAM,CACnC,IAAIC,EAAO,OAAO,UACdC,EAAO,OAAO,UACdC,EAAO,OAAO,UACdC,EAAO,OAAO,UAElBvB,EAAW,QAASwB,GAAW,CAC7BA,EAAO,EAAE,QAASC,GAAM,CACtBL,EAAO,KAAK,IAAIA,EAAMK,CAAC,EACvBJ,EAAO,KAAK,IAAIA,EAAMI,CAAC,CACzB,CAAC,EACDD,EAAO,EAAE,QAASE,GAAM,CACtBJ,EAAO,KAAK,IAAIA,EAAMI,CAAC,EACvBH,EAAO,KAAK,IAAIA,EAAMG,CAAC,CACzB,CAAC,CACH,CAAC,EAED,MAAMC,GAAYN,EAAOD,GAAQ,GAC3BQ,GAAYL,EAAOD,GAAQ,GAEjC,MAAO,CACL,KAAMF,EAAOO,EACb,KAAMN,EAAOM,EACb,KAAML,EAAOM,EACb,KAAML,EAAOK,CAAA,CAEjB,EAAG,CAAC5B,CAAU,CAAC,EAET6B,EAAkBV,EAAAA,QACtB,IAAMf,GAAU,CAACa,EAAMC,CAAI,EAC3B,CAACd,EAAQa,EAAMC,CAAI,CAAA,EAGfY,EAASX,EAAAA,QAAQ,IAAM,CAC3B,MAAMY,EAAQF,EAAgB,CAAC,EAAIA,EAAgB,CAAC,EACpD,IAAIG,EAAO,KAAK,IAAI,GAAI,KAAK,MAAM,KAAK,MAAMD,CAAK,CAAC,CAAC,EAEjDA,EAAQC,EAAO,KAAIA,EAAOA,EAAO,GACjCD,EAAQC,EAAO,IAAGA,EAAOA,EAAO,GAEpC,MAAMC,EAAQ,CAAA,EACd,IAAIC,EAAU,KAAK,KAAKL,EAAgB,CAAC,EAAIG,CAAI,EAAIA,EACrD,KAAOE,GAAWL,EAAgB,CAAC,GACjCI,EAAM,KAAKC,CAAO,EAClBA,GAAWF,EAEb,OAAOC,CACT,EAAG,CAACJ,CAAe,CAAC,EAEdM,EAAShB,EAAAA,QACb,IAAM,CAAC,GAAG,IAAI,IAAInB,EAAW,QAASoC,GAAMA,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAACC,EAAGC,IAAMD,EAAIC,CAAC,EACvE,CAACtC,CAAU,CAAA,EAKPuC,EAAkB,CAAC,CAAC9B,GAAaA,EAAU,SAAW0B,EAAO,OAE7DK,EAAOrB,EAAAA,QAAQ,IAAiC,CACpD,OAAQd,EAAA,CACN,IAAK,gBACL,IAAK,2BACH,MAAO,gBACT,QACE,MAAO,OAAA,CAEb,EAAG,CAACA,CAAO,CAAC,EAENoC,EAActB,EAAAA,QAClB,KAAO,CACL,UAAWP,EAAM,UACjB,QAAS,GACT,UAAW,EACX,MAAO,UACP,SAAU,CACR,KAAM,GACN,MAAOA,EAAM,UACb,OAAQ,oBACR,OAAQ,GAAA,EAEV,UAAWA,EAAM,UACjB,UAAW,EACX,SAAU,EACV,SAAU,EAAA,GAEZ,CAACA,CAAK,CAAA,EAGR8B,OAAAA,EAAAA,UAAU,IAAM,CACd,GAAI,CAAChC,EAAQ,QAAS,OAEtB,MAAMiC,EAAW3C,EAAW,IAAI,CAACwB,EAAQoB,IAAU,CACjD,MAAMC,EAAQC,EAAAA,YAAYF,EAAOpB,EAAO,KAAK,EAC7C,MAAO,CACL,EAAGA,EAAO,EACV,EAAGA,EAAO,EACV,KAAM,UACN,KAAAgB,EACA,KAAMhB,EAAO,KACb,UAAW,OACX,KAAM,CACJ,MAAAqB,EACA,MAAO,GAAA,EAET,OACExC,IAAY,QACR,CAAE,QAAS,GACX,CACE,MAAAwC,EACA,KAAM,EACN,OAAQrB,EAAO,QAAU,aAAA,EAEjC,QACEnB,IAAY,2BACRmB,EAAO,SAAW,CAChB,KAAM,OACN,MAAOA,EAAO,EAAE,IAAI,IAAM,EAAE,EAC5B,QAAS,GACT,MAAAqB,EACA,UAAW,EACX,MAAO,CAAA,EAET,MAAA,CAEV,CAAC,EAEKE,EAAS,CACb,GAAIvC,EACA,CACE,MAAO,CACL,KAAMA,EACN,KAAM,CACJ,KAAM,GACN,OAAQ,oBACR,MAAOI,EAAM,SAAA,CACf,CACF,EAEF,CAAA,EACJ,MAAAX,EACA,OAAAC,EACA,OAAQ,CACN,EAAG,GACH,EAAG,GACH,EAAG,GACH,EAAGM,EAAQX,EAAmBC,EAC9B,IAAK,EAAA,EAEP,cAAec,EAAM,QACrB,aAAcA,EAAM,OACpB,KAAM,CACJ,OAAQ,mBAAA,EAEV,SAAU,GACV,MAAO,CACL,MAAO,CACL,KAAMN,EACN,KAAM,CACJ,KAAM,GACN,MAAOM,EAAM,cACb,OAAQ,oBACR,OAAQ,GAAA,EAEV,SAAU,EAAA,EAEZ,UAAWA,EAAM,UACjB,MAAOT,EACP,UAAW,CAACA,EACZ,SAAU,QACV,SAAUgC,EACV,SAAUI,EAAkB9B,EAAY0B,EAAO,IAAI,MAAM,EACzD,SAAU,GACV,GAAGM,CAAA,EAEL,MAAO,CACL,MAAO,CACL,KAAMlC,EACN,KAAM,CACJ,KAAM,GACN,MAAOK,EAAM,cACb,OAAQ,oBACR,OAAQ,GAAA,EAEV,SAAU,EAAA,EAEZ,UAAWA,EAAM,UACjB,MAAOR,EACP,UAAW,CAACA,EACZ,SAAU,QACV,SAAU0B,EACV,SAAU,GACV,GAAGW,CAAA,EAEL,OAAQ,CACN,EAAG,GACH,EAAG,IACH,QAAS,SACT,QAAS,MACT,YAAa,IACb,KAAM,CACJ,KAAM,GACN,MAAO7B,EAAM,YACb,OAAQ,oBACR,OAAQ,GAAA,CACV,EAEF,WAAY,EAAA,EAGRoC,EAAS,CACb,WAAY,GACZ,eAAgB,GAChB,YAAa,EAAA,EAGfC,EAAO,QAAQvC,EAAQ,QAASiC,EAAUI,EAAQC,CAAM,EACxDlC,EAAYJ,EAAQ,OAAO,EAG3B,MAAMwC,EAAcxC,EAAQ,QAE5B,MAAO,IAAM,CACPwC,GACFD,EAAO,MAAMC,CAAW,CAE5B,CACF,EAAG,CAAClD,EAAYC,EAAOC,EAAQC,EAAQC,EAAQE,EAAQC,EAAQC,EAAOgC,EAAMC,EAAaN,EAAQL,EAAQS,EAAiB9B,EAAWoB,EAAiBxB,EAASO,EAAOE,CAAW,CAAC,EAGhLqC,EAAAA,KAAC,MAAA,CAAI,UAAU,qBACb,SAAA,CAAAC,EAAAA,IAAC,MAAA,CAAI,IAAK1C,EAAS,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAA,CAAO,CAAG,EAC5DK,CAAA,EACH,CAEJ"}
@@ -1,53 +1,53 @@
1
- import { jsxs as P, jsx as X } from "react/jsx-runtime";
2
- import v from "plotly.js-dist";
3
- import { useRef as U, useMemo as c, useEffect as V } from "react";
4
- import { useChartTooltip as B } from "../ChartTooltip/ChartTooltip.js";
5
- import { usePlotlyTheme as Y } from "../../../hooks/use-plotly-theme.js";
6
- import { seriesColor as j } from "../../../utils/colors.js";
7
- const J = ({
8
- dataSeries: i,
9
- width: w = 1e3,
10
- height: b = 600,
11
- xRange: g,
1
+ import { jsxs as v, jsx as X } from "react/jsx-runtime";
2
+ import A from "plotly.js-dist";
3
+ import { useRef as O, useMemo as c, useEffect as U } from "react";
4
+ import { useChartTooltip as V } from "../ChartTooltip/ChartTooltip.js";
5
+ import { usePlotlyTheme as B } from "../../../hooks/use-plotly-theme.js";
6
+ import { seriesColor as G } from "../../../utils/colors.js";
7
+ const Y = 60, j = 30, K = ({
8
+ dataSeries: s,
9
+ width: b = 1e3,
10
+ height: _ = 600,
11
+ xRange: M,
12
12
  yRange: m,
13
13
  variant: f = "lines",
14
14
  xTitle: x = "Columns",
15
- yTitle: M = "Rows",
16
- title: C = "Line Graph",
17
- xTickText: h
15
+ yTitle: k = "Rows",
16
+ title: h,
17
+ xTickText: d
18
18
  }) => {
19
- const p = U(null), r = Y(), { bindTooltip: E, tooltipElement: A } = B({ xLabel: x, yLabel: M }), { yMin: _, yMax: z } = c(() => {
20
- let o = Number.MAX_VALUE, t = Number.MIN_VALUE, l = Number.MAX_VALUE, e = Number.MIN_VALUE;
21
- i.forEach((a) => {
19
+ const p = O(null), r = B(), { bindTooltip: E, tooltipElement: P } = V({ xLabel: x, yLabel: k }), { yMin: I, yMax: C } = c(() => {
20
+ let t = Number.MAX_VALUE, o = Number.MIN_VALUE, l = Number.MAX_VALUE, e = Number.MIN_VALUE;
21
+ s.forEach((a) => {
22
22
  a.x.forEach((u) => {
23
- o = Math.min(o, u), t = Math.max(t, u);
23
+ t = Math.min(t, u), o = Math.max(o, u);
24
24
  }), a.y.forEach((u) => {
25
25
  l = Math.min(l, u), e = Math.max(e, u);
26
26
  });
27
27
  });
28
- const n = (t - o) * 0.1, y = (e - l) * 0.1;
28
+ const n = (o - t) * 0.1, g = (e - l) * 0.1;
29
29
  return {
30
- xMin: o - n,
31
- xMax: t + n,
32
- yMin: l - y,
33
- yMax: e + y
30
+ xMin: t - n,
31
+ xMax: o + n,
32
+ yMin: l - g,
33
+ yMax: e + g
34
34
  };
35
- }, [i]), s = c(
36
- () => m || [_, z],
37
- [m, _, z]
38
- ), I = c(() => {
39
- const o = s[1] - s[0];
40
- let t = Math.pow(10, Math.floor(Math.log10(o)));
41
- o / t > 10 && (t = t * 2), o / t < 4 && (t = t / 2);
35
+ }, [s]), i = c(
36
+ () => m || [I, C],
37
+ [m, I, C]
38
+ ), N = c(() => {
39
+ const t = i[1] - i[0];
40
+ let o = Math.pow(10, Math.floor(Math.log10(t)));
41
+ t / o > 10 && (o = o * 2), t / o < 4 && (o = o / 2);
42
42
  const l = [];
43
- let e = Math.ceil(s[0] / t) * t;
44
- for (; e <= s[1]; )
45
- l.push(e), e += t;
43
+ let e = Math.ceil(i[0] / o) * o;
44
+ for (; e <= i[1]; )
45
+ l.push(e), e += o;
46
46
  return l;
47
- }, [s]), d = c(
48
- () => [...new Set(i.flatMap((o) => o.x))].sort((o, t) => o - t),
49
- [i]
50
- ), L = !!h && h.length === d.length, N = c(() => {
47
+ }, [i]), y = c(
48
+ () => [...new Set(s.flatMap((t) => t.x))].sort((t, o) => t - o),
49
+ [s]
50
+ ), L = !!d && d.length === y.length, z = c(() => {
51
51
  switch (f) {
52
52
  case "lines+markers":
53
53
  case "lines+markers+error_bars":
@@ -55,7 +55,7 @@ const J = ({
55
55
  default:
56
56
  return "lines";
57
57
  }
58
- }, [f]), k = c(
58
+ }, [f]), w = c(
59
59
  () => ({
60
60
  tickcolor: r.tickColor,
61
61
  ticklen: 12,
@@ -74,15 +74,15 @@ const J = ({
74
74
  }),
75
75
  [r]
76
76
  );
77
- return V(() => {
77
+ return U(() => {
78
78
  if (!p.current) return;
79
- const o = i.map((n, y) => {
80
- const a = j(y, n.color);
79
+ const t = s.map((n, g) => {
80
+ const a = G(g, n.color);
81
81
  return {
82
82
  x: n.x,
83
83
  y: n.y,
84
84
  type: "scatter",
85
- mode: N,
85
+ mode: z,
86
86
  name: n.name,
87
87
  hoverinfo: "none",
88
88
  line: {
@@ -103,18 +103,26 @@ const J = ({
103
103
  width: 5
104
104
  } : void 0
105
105
  };
106
- }), t = {
107
- title: {
108
- text: C,
109
- font: {
110
- size: 32,
111
- family: "Inter, sans-serif",
112
- color: r.textColor
106
+ }), o = {
107
+ ...h ? {
108
+ title: {
109
+ text: h,
110
+ font: {
111
+ size: 32,
112
+ family: "Inter, sans-serif",
113
+ color: r.textColor
114
+ }
113
115
  }
116
+ } : {},
117
+ width: b,
118
+ height: _,
119
+ margin: {
120
+ l: 80,
121
+ r: 30,
122
+ b: 80,
123
+ t: h ? Y : j,
124
+ pad: 10
114
125
  },
115
- width: w,
116
- height: b,
117
- margin: { l: 80, r: 30, b: 80, t: 60, pad: 10 },
118
126
  paper_bgcolor: r.paperBg,
119
127
  plot_bgcolor: r.plotBg,
120
128
  font: {
@@ -133,17 +141,17 @@ const J = ({
133
141
  standoff: 32
134
142
  },
135
143
  gridcolor: r.gridColor,
136
- range: g,
137
- autorange: !g,
144
+ range: M,
145
+ autorange: !M,
138
146
  tickmode: "array",
139
- tickvals: d,
140
- ticktext: L ? h : d.map(String),
147
+ tickvals: y,
148
+ ticktext: L ? d : y.map(String),
141
149
  showgrid: !0,
142
- ...k
150
+ ...w
143
151
  },
144
152
  yaxis: {
145
153
  title: {
146
- text: M,
154
+ text: k,
147
155
  font: {
148
156
  size: 16,
149
157
  color: r.textSecondary,
@@ -156,9 +164,9 @@ const J = ({
156
164
  range: m,
157
165
  autorange: !m,
158
166
  tickmode: "array",
159
- tickvals: I,
167
+ tickvals: N,
160
168
  showgrid: !0,
161
- ...k
169
+ ...w
162
170
  },
163
171
  legend: {
164
172
  x: 0.5,
@@ -179,17 +187,17 @@ const J = ({
179
187
  displayModeBar: !1,
180
188
  displaylogo: !1
181
189
  };
182
- v.newPlot(p.current, o, t, l), E(p.current);
190
+ A.newPlot(p.current, t, o, l), E(p.current);
183
191
  const e = p.current;
184
192
  return () => {
185
- e && v.purge(e);
193
+ e && A.purge(e);
186
194
  };
187
- }, [i, w, b, g, m, x, M, C, N, k, d, I, L, h, s, f, r, E]), /* @__PURE__ */ P("div", { className: "relative size-full", children: [
195
+ }, [s, b, _, M, m, x, k, h, z, w, y, N, L, d, i, f, r, E]), /* @__PURE__ */ v("div", { className: "relative size-full", children: [
188
196
  /* @__PURE__ */ X("div", { ref: p, style: { width: "100%", height: "100%" } }),
189
- A
197
+ P
190
198
  ] });
191
199
  };
192
200
  export {
193
- J as LineGraph
201
+ K as LineGraph
194
202
  };
195
203
  //# sourceMappingURL=LineGraph.js.map