@tetrascience-npm/tetrascience-react-ui 0.6.0-beta.82.1 → 0.6.0-beta.84.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.
Files changed (87) hide show
  1. package/dist/components/charts/AreaGraph/AreaGraph.cjs +1 -1
  2. package/dist/components/charts/AreaGraph/AreaGraph.cjs.map +1 -1
  3. package/dist/components/charts/AreaGraph/AreaGraph.js +132 -98
  4. package/dist/components/charts/AreaGraph/AreaGraph.js.map +1 -1
  5. package/dist/components/charts/BarGraph/BarGraph.cjs +1 -1
  6. package/dist/components/charts/BarGraph/BarGraph.cjs.map +1 -1
  7. package/dist/components/charts/BarGraph/BarGraph.js +63 -57
  8. package/dist/components/charts/BarGraph/BarGraph.js.map +1 -1
  9. package/dist/components/charts/Boxplot/Boxplot.cjs +1 -1
  10. package/dist/components/charts/Boxplot/Boxplot.cjs.map +1 -1
  11. package/dist/components/charts/Boxplot/Boxplot.js +83 -74
  12. package/dist/components/charts/Boxplot/Boxplot.js.map +1 -1
  13. package/dist/components/charts/ChartTooltip/ChartTooltip.cjs +2 -0
  14. package/dist/components/charts/ChartTooltip/ChartTooltip.cjs.map +1 -0
  15. package/dist/components/charts/ChartTooltip/ChartTooltip.js +163 -0
  16. package/dist/components/charts/ChartTooltip/ChartTooltip.js.map +1 -0
  17. package/dist/components/charts/ChartTooltip/lines.cjs +2 -0
  18. package/dist/components/charts/ChartTooltip/lines.cjs.map +1 -0
  19. package/dist/components/charts/ChartTooltip/lines.js +29 -0
  20. package/dist/components/charts/ChartTooltip/lines.js.map +1 -0
  21. package/dist/components/charts/Chromatogram/Chromatogram.cjs +1 -1
  22. package/dist/components/charts/Chromatogram/Chromatogram.cjs.map +1 -1
  23. package/dist/components/charts/Chromatogram/Chromatogram.js +75 -61
  24. package/dist/components/charts/Chromatogram/Chromatogram.js.map +1 -1
  25. package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs +1 -1
  26. package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs.map +1 -1
  27. package/dist/components/charts/ChromatogramChart/ChromatogramChart.js +116 -108
  28. package/dist/components/charts/ChromatogramChart/ChromatogramChart.js.map +1 -1
  29. package/dist/components/charts/ChromatogramChart/annotations.cjs +1 -1
  30. package/dist/components/charts/ChromatogramChart/annotations.cjs.map +1 -1
  31. package/dist/components/charts/ChromatogramChart/annotations.js +32 -32
  32. package/dist/components/charts/ChromatogramChart/annotations.js.map +1 -1
  33. package/dist/components/charts/ChromatogramChart/boundaryMarkers.cjs +1 -1
  34. package/dist/components/charts/ChromatogramChart/boundaryMarkers.cjs.map +1 -1
  35. package/dist/components/charts/ChromatogramChart/boundaryMarkers.js +6 -6
  36. package/dist/components/charts/ChromatogramChart/boundaryMarkers.js.map +1 -1
  37. package/dist/components/charts/ChromatogramChart/constants.cjs +1 -1
  38. package/dist/components/charts/ChromatogramChart/constants.cjs.map +1 -1
  39. package/dist/components/charts/ChromatogramChart/constants.js +11 -5
  40. package/dist/components/charts/ChromatogramChart/constants.js.map +1 -1
  41. package/dist/components/charts/ChromatogramChart/dataProcessing.cjs +1 -1
  42. package/dist/components/charts/ChromatogramChart/dataProcessing.cjs.map +1 -1
  43. package/dist/components/charts/ChromatogramChart/dataProcessing.js +38 -49
  44. package/dist/components/charts/ChromatogramChart/dataProcessing.js.map +1 -1
  45. package/dist/components/charts/DotPlot/DotPlot.cjs +1 -1
  46. package/dist/components/charts/DotPlot/DotPlot.cjs.map +1 -1
  47. package/dist/components/charts/DotPlot/DotPlot.js +57 -63
  48. package/dist/components/charts/DotPlot/DotPlot.js.map +1 -1
  49. package/dist/components/charts/Histogram/Histogram.cjs +1 -1
  50. package/dist/components/charts/Histogram/Histogram.cjs.map +1 -1
  51. package/dist/components/charts/Histogram/Histogram.js +98 -104
  52. package/dist/components/charts/Histogram/Histogram.js.map +1 -1
  53. package/dist/components/charts/LineGraph/LineGraph.cjs +1 -1
  54. package/dist/components/charts/LineGraph/LineGraph.cjs.map +1 -1
  55. package/dist/components/charts/LineGraph/LineGraph.js +97 -88
  56. package/dist/components/charts/LineGraph/LineGraph.js.map +1 -1
  57. package/dist/components/charts/PieChart/PieChart.cjs +1 -1
  58. package/dist/components/charts/PieChart/PieChart.cjs.map +1 -1
  59. package/dist/components/charts/PieChart/PieChart.js +65 -68
  60. package/dist/components/charts/PieChart/PieChart.js.map +1 -1
  61. package/dist/components/charts/PlateMap/PlateMap.cjs +1 -1
  62. package/dist/components/charts/PlateMap/PlateMap.cjs.map +1 -1
  63. package/dist/components/charts/PlateMap/PlateMap.js +271 -256
  64. package/dist/components/charts/PlateMap/PlateMap.js.map +1 -1
  65. package/dist/components/charts/PlateMap/constants.cjs +1 -1
  66. package/dist/components/charts/PlateMap/constants.cjs.map +1 -1
  67. package/dist/components/charts/PlateMap/constants.js +20 -29
  68. package/dist/components/charts/PlateMap/constants.js.map +1 -1
  69. package/dist/components/charts/ScatterGraph/ScatterGraph.cjs +1 -1
  70. package/dist/components/charts/ScatterGraph/ScatterGraph.cjs.map +1 -1
  71. package/dist/components/charts/ScatterGraph/ScatterGraph.js +113 -89
  72. package/dist/components/charts/ScatterGraph/ScatterGraph.js.map +1 -1
  73. package/dist/hooks/use-plotly-theme.cjs +1 -1
  74. package/dist/hooks/use-plotly-theme.cjs.map +1 -1
  75. package/dist/hooks/use-plotly-theme.js +4 -2
  76. package/dist/hooks/use-plotly-theme.js.map +1 -1
  77. package/dist/index.cjs +1 -1
  78. package/dist/index.css +1 -1
  79. package/dist/index.d.ts +156 -76
  80. package/dist/index.js +587 -581
  81. package/dist/index.js.map +1 -1
  82. package/dist/index.tailwind.css +1 -1
  83. package/dist/utils/colors.cjs +1 -1
  84. package/dist/utils/colors.cjs.map +1 -1
  85. package/dist/utils/colors.js +38 -93
  86. package/dist/utils/colors.js.map +1 -1
  87. package/package.json +1 -1
@@ -1,52 +1,54 @@
1
- import { jsx as z } from "react/jsx-runtime";
2
- import A from "plotly.js-dist";
3
- import { useRef as v, useMemo as i, useEffect as B } from "react";
4
- import { usePlotlyTheme as P } from "../../../hooks/use-plotly-theme.js";
5
- const Y = ({
1
+ import { jsxs as L, jsx as B } from "react/jsx-runtime";
2
+ import z from "plotly.js-dist";
3
+ import { useRef as P, useMemo as i, useEffect as U } from "react";
4
+ import { useChartTooltip as V } from "../ChartTooltip/ChartTooltip.js";
5
+ import { usePlotlyTheme as X } from "../../../hooks/use-plotly-theme.js";
6
+ import { seriesColor as Y } from "../../../utils/colors.js";
7
+ const F = ({
6
8
  dataSeries: a,
7
- width: g = 1e3,
8
- height: d = 600,
9
- xRange: p,
10
- yRange: c,
11
- variant: m = "group",
12
- xTitle: y = "Columns",
13
- yTitle: x = "Rows",
14
- title: M = "Bar Graph",
15
- barWidth: k = 24
9
+ width: x = 1e3,
10
+ height: M = 600,
11
+ xRange: h,
12
+ yRange: s,
13
+ variant: p = "group",
14
+ xTitle: g = "Columns",
15
+ yTitle: d = "Rows",
16
+ title: k = "Bar Graph",
17
+ barWidth: w = 24
16
18
  }) => {
17
- const u = v(null), t = P(), { yMin: w, yMax: b } = i(() => {
19
+ const c = P(null), t = X(), { bindTooltip: b, tooltipElement: A } = V({ xLabel: g, yLabel: d }), { yMin: C, yMax: E } = i(() => {
18
20
  let r = Number.MAX_VALUE, o = Number.MIN_VALUE, n = Number.MAX_VALUE, e = Number.MIN_VALUE;
19
21
  a.forEach((N) => {
20
- N.x.forEach((f) => {
21
- r = Math.min(r, f), o = Math.max(o, f);
22
- }), N.y.forEach((f) => {
23
- n = Math.min(n, f), e = Math.max(e, f);
22
+ N.x.forEach((m) => {
23
+ r = Math.min(r, m), o = Math.max(o, m);
24
+ }), N.y.forEach((m) => {
25
+ n = Math.min(n, m), e = Math.max(e, m);
24
26
  });
25
27
  });
26
- const l = (o - r) * 0.1, _ = (e - n) * 0.1;
28
+ const l = (o - r) * 0.1, u = (e - n) * 0.1;
27
29
  return {
28
30
  xMin: r - l,
29
31
  xMax: o + l,
30
- yMin: m === "stack" ? 0 : n - _,
31
- yMax: e + _
32
+ yMin: p === "stack" ? 0 : n - u,
33
+ yMax: e + u
32
34
  };
33
- }, [a, m]), s = i(
34
- () => c || [w, b],
35
- [c, w, b]
36
- ), E = i(
35
+ }, [a, p]), f = i(
36
+ () => s || [C, E],
37
+ [s, C, E]
38
+ ), I = i(
37
39
  () => [...new Set(a.flatMap((r) => r.x))],
38
40
  [a]
39
- ), C = i(() => {
40
- const r = s[1] - s[0];
41
+ ), _ = i(() => {
42
+ const r = f[1] - f[0];
41
43
  let o = Math.pow(10, Math.floor(Math.log10(r)));
42
44
  r / o > 10 && (o = o * 2), r / o < 4 && (o = o / 2);
43
45
  const n = [];
44
- let e = Math.ceil(s[0] / o) * o;
45
- for (; e <= s[1]; )
46
+ let e = Math.ceil(f[0] / o) * o;
47
+ for (; e <= f[1]; )
46
48
  n.push(e), e += o;
47
49
  return n;
48
- }, [s]), I = i(() => {
49
- switch (m) {
50
+ }, [f]), v = i(() => {
51
+ switch (p) {
50
52
  case "stack":
51
53
  return "stack";
52
54
  case "overlay":
@@ -54,7 +56,7 @@ const Y = ({
54
56
  default:
55
57
  return "group";
56
58
  }
57
- }, [m]), h = i(
59
+ }, [p]), y = i(
58
60
  () => ({
59
61
  tickcolor: t.tickColor,
60
62
  ticklen: 12,
@@ -73,41 +75,42 @@ const Y = ({
73
75
  }),
74
76
  [t]
75
77
  );
76
- return B(() => {
77
- if (!u.current) return;
78
- const r = a.map((l) => ({
78
+ return U(() => {
79
+ if (!c.current) return;
80
+ const r = a.map((l, u) => ({
79
81
  x: l.x,
80
82
  y: l.y,
81
83
  type: "bar",
82
84
  name: l.name,
85
+ hoverinfo: "none",
83
86
  marker: {
84
- color: l.color
87
+ color: Y(u, l.color)
85
88
  },
86
- width: k,
89
+ width: w,
87
90
  error_y: l.error_y
88
91
  })), o = {
89
92
  title: {
90
- text: M,
93
+ text: k,
91
94
  font: {
92
95
  size: 32,
93
96
  family: "Inter, sans-serif",
94
97
  color: t.textColor
95
98
  }
96
99
  },
97
- width: g,
98
- height: d,
100
+ width: x,
101
+ height: M,
99
102
  margin: { l: 80, r: 30, b: 80, t: 60, pad: 0 },
100
103
  paper_bgcolor: t.paperBg,
101
104
  plot_bgcolor: t.plotBg,
102
105
  font: {
103
106
  family: "Inter, sans-serif"
104
107
  },
105
- barmode: I,
108
+ barmode: v,
106
109
  bargap: 0.15,
107
110
  dragmode: !1,
108
111
  xaxis: {
109
112
  title: {
110
- text: y,
113
+ text: g,
111
114
  font: {
112
115
  size: 16,
113
116
  color: t.textSecondary,
@@ -117,16 +120,16 @@ const Y = ({
117
120
  standoff: 32
118
121
  },
119
122
  gridcolor: t.gridColor,
120
- range: p,
121
- autorange: !p,
123
+ range: h,
124
+ autorange: !h,
122
125
  tickmode: "array",
123
- tickvals: E,
126
+ tickvals: I,
124
127
  showgrid: !0,
125
- ...h
128
+ ...y
126
129
  },
127
130
  yaxis: {
128
131
  title: {
129
- text: x,
132
+ text: d,
130
133
  font: {
131
134
  size: 16,
132
135
  color: t.textSecondary,
@@ -136,12 +139,12 @@ const Y = ({
136
139
  standoff: 30
137
140
  },
138
141
  gridcolor: t.gridColor,
139
- range: c,
140
- autorange: !c,
142
+ range: s,
143
+ autorange: !s,
141
144
  tickmode: "array",
142
- tickvals: C,
145
+ tickvals: _,
143
146
  showgrid: !0,
144
- ...h
147
+ ...y
145
148
  },
146
149
  legend: {
147
150
  x: 0.5,
@@ -162,14 +165,17 @@ const Y = ({
162
165
  displayModeBar: !1,
163
166
  displaylogo: !1
164
167
  };
165
- A.newPlot(u.current, r, o, n);
166
- const e = u.current;
168
+ z.newPlot(c.current, r, o, n), b(c.current);
169
+ const e = c.current;
167
170
  return () => {
168
- e && A.purge(e);
171
+ e && z.purge(e);
169
172
  };
170
- }, [a, g, d, p, c, y, x, M, k, I, h, E, C, t]), /* @__PURE__ */ z("div", { className: "bar-graph-container", children: /* @__PURE__ */ z("div", { ref: u, style: { width: "100%", height: "100%" } }) });
173
+ }, [a, x, M, h, s, g, d, k, w, v, y, I, _, t, b]), /* @__PURE__ */ L("div", { className: "bar-graph-container relative", children: [
174
+ /* @__PURE__ */ B("div", { ref: c, style: { width: "100%", height: "100%" } }),
175
+ A
176
+ ] });
171
177
  };
172
178
  export {
173
- Y as BarGraph
179
+ F as BarGraph
174
180
  };
175
181
  //# 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 { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\n\ninterface BarDataSeries {\n x: number[];\n y: number[];\n name: string;\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\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}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\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))],\n [dataSeries],\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 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) => ({\n x: series.x,\n y: series.y,\n type: \"bar\" as const,\n name: series.name,\n marker: {\n color: 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 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\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, theme]);\n\n return (\n <div className=\"bar-graph-container\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\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","plotRef","useRef","theme","usePlotlyTheme","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","xTicks","s","yTicks","range","step","ticks","current","barMode","tickOptions","useEffect","data","layout","config","Plotly","plotElement","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\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\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}) => {\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))],\n [dataSeries],\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 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 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, 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","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","xTicks","s","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 I=require("react/jsx-runtime"),C=require("plotly.js-dist"),i=require("react"),E=require("../../../hooks/use-plotly-theme.cjs"),P=-1.8,j=({dataSeries:a,width:h=1e3,height:m=600,xRange:u,yRange:c,xTitle:d="Columns",yTitle:g="Rows",title:x="Boxplot",showPoints:y=!1})=>{const f=i.useRef(null),t=E.usePlotlyTheme(),{yMin:M,yMax:w}=i.useMemo(()=>{let r=Number.MAX_VALUE,o=Number.MIN_VALUE;a.forEach(n=>{n.y.forEach(e=>{r=Math.min(r,e),o=Math.max(o,e)})});const l=(o-r)*.1;return{yMin:r-l,yMax:o+l}},[a]),s=i.useMemo(()=>c||[M,w],[c,M,w]),k=i.useMemo(()=>{const r=s[1]-s[0];let o=Math.pow(10,Math.floor(Math.log10(r)));r/o>10&&(o=o*2),r/o<4&&(o=o/2);const l=[];let n=Math.ceil(s[0]/o)*o;for(;n<=s[1];)l.push(n),n+=o;return l},[s]),p=i.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]),b=i.useMemo(()=>({text:x,x:.5,y:.95,xanchor:"center",yanchor:"top",font:{size:32,weight:600,family:"Inter, sans-serif",color:t.textColor,lineheight:1.2,standoff:30}}),[x,t]);return i.useEffect(()=>{if(!f.current)return;const r=a.map(e=>({y:e.y,x:e.x,type:"box",name:e.name,marker:{color:e.color},line:{color:e.color},fillcolor:e.color+"40",boxpoints:y?e.boxpoints||"outliers":!1,jitter:e.jitter||.3,pointpos:e.pointpos||P})),o={width:h,height:m,title:b,margin:{l:80,r:40,b:80,t:80,pad:0},paper_bgcolor:t.paperBg,plot_bgcolor:t.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:d,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:t.gridColor,range:u,autorange:!u,showgrid:!0,...p},yaxis:{title:{text:g,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:t.gridColor,range:c,autorange:!c,tickmode:"array",tickvals:k,showgrid:!0,...p},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:13,color:t.legendColor,family:"Inter, sans-serif",weight:500,lineheight:18}},showlegend:!0},l={responsive:!0,displayModeBar:!1,displaylogo:!1};C.newPlot(f.current,r,o,l);const n=f.current;return()=>{n&&C.purge(n)}},[a,h,m,u,c,s,d,g,y,b,p,k,t]),I.jsx("div",{className:"boxplot-container",children:I.jsx("div",{ref:f,style:{width:"100%",height:"100%"}})})};exports.Boxplot=j;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("react/jsx-runtime"),E=require("plotly.js-dist"),s=require("react"),q=require("../ChartTooltip/ChartTooltip.cjs"),z=require("../../../hooks/use-plotly-theme.cjs"),B=require("../../../utils/colors.cjs"),N=-1.8,O=({dataSeries:u,width:d=1e3,height:y=600,xRange:p,yRange:a,xTitle:h="Columns",yTitle:m="Rows",title:x="Boxplot",showPoints:M=!1})=>{const f=s.useRef(null),t=z.usePlotlyTheme(),{bindTooltip:b,tooltipElement:P}=q.useChartTooltip({xLabel:h,yLabel:m}),{yMin:w,yMax:k}=s.useMemo(()=>{let e=Number.MAX_VALUE,o=Number.MIN_VALUE;u.forEach(n=>{n.y.forEach(r=>{e=Math.min(e,r),o=Math.max(o,r)})});const i=(o-e)*.1;return{yMin:e-i,yMax:o+i}},[u]),c=s.useMemo(()=>a||[w,k],[a,w,k]),C=s.useMemo(()=>{const e=c[1]-c[0];let o=Math.pow(10,Math.floor(Math.log10(e)));e/o>10&&(o=o*2),e/o<4&&(o=o/2);const i=[];let n=Math.ceil(c[0]/o)*o;for(;n<=c[1];)i.push(n),n+=o;return i},[c]),g=s.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]),I=s.useMemo(()=>({text:x,x:.5,y:.95,xanchor:"center",yanchor:"top",font:{size:32,weight:600,family:"Inter, sans-serif",color:t.textColor,lineheight:1.2,standoff:30}}),[x,t]);return s.useEffect(()=>{if(!f.current)return;const e=u.map((r,j)=>{const l=B.seriesColor(j,r.color);return{y:r.y,x:r.x,type:"box",name:r.name,hoverinfo:"none",marker:{color:l},line:{color:l},fillcolor:typeof l=="string"&&l.startsWith("#")&&l.length===7?`${l}40`:l,boxpoints:M?r.boxpoints||"outliers":!1,jitter:r.jitter||.3,pointpos:r.pointpos||N}}),o={width:d,height:y,title:I,margin:{l:80,r:40,b:80,t:80,pad:0},paper_bgcolor:t.paperBg,plot_bgcolor:t.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:h,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:t.gridColor,range:p,autorange:!p,showgrid:!0,...g},yaxis:{title:{text:m,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:t.gridColor,range:a,autorange:!a,tickmode:"array",tickvals:C,showgrid:!0,...g},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:13,color:t.legendColor,family:"Inter, sans-serif",weight:500,lineheight:18}},showlegend:!0},i={responsive:!0,displayModeBar:!1,displaylogo:!1};E.newPlot(f.current,e,o,i),b(f.current);const n=f.current;return()=>{n&&E.purge(n)}},[u,d,y,p,a,c,h,m,M,I,g,C,t,b]),v.jsxs("div",{className:"boxplot-container relative",children:[v.jsx("div",{ref:f,style:{width:"100%",height:"100%"}}),P]})};exports.Boxplot=O;
2
2
  //# sourceMappingURL=Boxplot.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Boxplot.cjs","sources":["../../../../src/components/charts/Boxplot/Boxplot.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\n\n/** Default point position offset from the box edge */\nconst DEFAULT_POINT_POSITION = -1.8;\n\ninterface BoxDataSeries {\n y: number[];\n name: string;\n color: string;\n x?: string[] | number[];\n boxpoints?: \"all\" | \"outliers\" | \"suspectedoutliers\" | false;\n jitter?: number;\n pointpos?: number;\n}\n\ninterface BoxplotProps {\n dataSeries: BoxDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n xTitle?: string;\n yTitle?: string;\n title?: string;\n showPoints?: boolean;\n}\n\nconst Boxplot: React.FC<BoxplotProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Boxplot\",\n showPoints = false,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n\n const { yMin, yMax } = useMemo(() => {\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const yPadding = (maxY - minY) * 0.1;\n\n return {\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 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 const titleOptions = useMemo(\n () => ({\n text: title,\n x: 0.5,\n y: 0.95,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n font: {\n size: 32,\n weight: 600,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n lineheight: 1.2,\n standoff: 30,\n },\n }),\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const data = dataSeries.map((series) => ({\n y: series.y,\n x: series.x,\n type: \"box\" as const,\n name: series.name,\n marker: {\n color: series.color,\n },\n line: {\n color: series.color,\n },\n fillcolor: series.color + \"40\", // Add transparency\n boxpoints: showPoints ? series.boxpoints || \"outliers\" : (false as const),\n jitter: series.jitter || 0.3,\n pointpos: series.pointpos || DEFAULT_POINT_POSITION,\n }));\n\n const layout = {\n width,\n height: height,\n title: titleOptions,\n margin: { l: 80, r: 40, b: 80, t: 80, pad: 0 },\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: 15,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\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: 15,\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: 13,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n lineheight: 18,\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, data, layout, config);\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, effectiveYRange, xTitle, yTitle, showPoints, titleOptions, tickOptions, yTicks, theme]);\n\n return (\n <div className=\"boxplot-container\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n </div>\n );\n};\n\nexport { Boxplot };\nexport type { BoxDataSeries, BoxplotProps };\n"],"names":["DEFAULT_POINT_POSITION","Boxplot","dataSeries","width","height","xRange","yRange","xTitle","yTitle","title","showPoints","plotRef","useRef","theme","usePlotlyTheme","yMin","yMax","useMemo","minY","maxY","series","y","yPadding","effectiveYRange","yTicks","range","step","ticks","current","tickOptions","titleOptions","useEffect","data","layout","config","Plotly","plotElement","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Boxplot.cjs","sources":["../../../../src/components/charts/Boxplot/Boxplot.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\n/** Default point position offset from the box edge */\nconst DEFAULT_POINT_POSITION = -1.8;\n\ninterface BoxDataSeries {\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n x?: string[] | number[];\n boxpoints?: \"all\" | \"outliers\" | \"suspectedoutliers\" | false;\n jitter?: number;\n pointpos?: number;\n}\n\ninterface BoxplotProps {\n dataSeries: BoxDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n xTitle?: string;\n yTitle?: string;\n title?: string;\n showPoints?: boolean;\n}\n\nconst Boxplot: React.FC<BoxplotProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Boxplot\",\n showPoints = false,\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 minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const yPadding = (maxY - minY) * 0.1;\n\n return {\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 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 const titleOptions = useMemo(\n () => ({\n text: title,\n x: 0.5,\n y: 0.95,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n font: {\n size: 32,\n weight: 600,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n lineheight: 1.2,\n standoff: 30,\n },\n }),\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const data = dataSeries.map((series, index) => {\n const color = seriesColor(index, series.color);\n return {\n y: series.y,\n x: series.x,\n type: \"box\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color,\n },\n line: {\n color,\n },\n fillcolor:\n typeof color === \"string\" && color.startsWith(\"#\") && color.length === 7\n ? `${color}40`\n : color, // Add transparency for hex colors only\n boxpoints: showPoints\n ? series.boxpoints || \"outliers\"\n : (false as const),\n jitter: series.jitter || 0.3,\n pointpos: series.pointpos || DEFAULT_POINT_POSITION,\n };\n });\n\n const layout = {\n width,\n height: height,\n title: titleOptions,\n margin: { l: 80, r: 40, b: 80, t: 80, pad: 0 },\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: 15,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\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: 15,\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: 13,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n lineheight: 18,\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, 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, effectiveYRange, xTitle, yTitle, showPoints, titleOptions, tickOptions, yTicks, theme, bindTooltip]);\n\n return (\n <div className=\"boxplot-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { Boxplot };\nexport type { BoxDataSeries, BoxplotProps };\n"],"names":["DEFAULT_POINT_POSITION","Boxplot","dataSeries","width","height","xRange","yRange","xTitle","yTitle","title","showPoints","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minY","maxY","series","y","yPadding","effectiveYRange","yTicks","range","step","ticks","current","tickOptions","titleOptions","useEffect","data","index","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
@@ -1,43 +1,45 @@
1
- import { jsx as b } from "react/jsx-runtime";
2
- import C from "plotly.js-dist";
3
- import { useRef as E, useMemo as s, useEffect as z } from "react";
4
- import { usePlotlyTheme as N } from "../../../hooks/use-plotly-theme.js";
5
- const _ = -1.8, A = ({
6
- dataSeries: a,
7
- width: h = 1e3,
8
- height: u = 600,
9
- xRange: p,
10
- yRange: c,
11
- xTitle: d = "Columns",
12
- yTitle: g = "Rows",
13
- title: x = "Boxplot",
14
- showPoints: y = !1
1
+ import { jsxs as N, jsx as _ } from "react/jsx-runtime";
2
+ import E from "plotly.js-dist";
3
+ import { useRef as B, useMemo as f, useEffect as L } from "react";
4
+ import { useChartTooltip as O } from "../ChartTooltip/ChartTooltip.js";
5
+ import { usePlotlyTheme as P } from "../../../hooks/use-plotly-theme.js";
6
+ import { seriesColor as j } from "../../../utils/colors.js";
7
+ const A = -1.8, W = ({
8
+ dataSeries: p,
9
+ width: d = 1e3,
10
+ height: x = 600,
11
+ xRange: m,
12
+ yRange: a,
13
+ xTitle: h = "Columns",
14
+ yTitle: u = "Rows",
15
+ title: y = "Boxplot",
16
+ showPoints: M = !1
15
17
  }) => {
16
- const f = E(null), t = N(), { yMin: M, yMax: w } = s(() => {
17
- let r = Number.MAX_VALUE, o = Number.MIN_VALUE;
18
- a.forEach((n) => {
19
- n.y.forEach((e) => {
20
- r = Math.min(r, e), o = Math.max(o, e);
18
+ const c = B(null), t = P(), { bindTooltip: w, tooltipElement: v } = O({ xLabel: h, yLabel: u }), { yMin: b, yMax: k } = f(() => {
19
+ let e = Number.MAX_VALUE, o = Number.MIN_VALUE;
20
+ p.forEach((n) => {
21
+ n.y.forEach((r) => {
22
+ e = Math.min(e, r), o = Math.max(o, r);
21
23
  });
22
24
  });
23
- const l = (o - r) * 0.1;
25
+ const i = (o - e) * 0.1;
24
26
  return {
25
- yMin: r - l,
26
- yMax: o + l
27
+ yMin: e - i,
28
+ yMax: o + i
27
29
  };
28
- }, [a]), i = s(
29
- () => c || [M, w],
30
- [c, M, w]
31
- ), k = s(() => {
32
- const r = i[1] - i[0];
33
- let o = Math.pow(10, Math.floor(Math.log10(r)));
34
- r / o > 10 && (o = o * 2), r / o < 4 && (o = o / 2);
35
- const l = [];
36
- let n = Math.ceil(i[0] / o) * o;
37
- for (; n <= i[1]; )
38
- l.push(n), n += o;
39
- return l;
40
- }, [i]), m = s(
30
+ }, [p]), s = f(
31
+ () => a || [b, k],
32
+ [a, b, k]
33
+ ), C = f(() => {
34
+ const e = s[1] - s[0];
35
+ let o = Math.pow(10, Math.floor(Math.log10(e)));
36
+ e / o > 10 && (o = o * 2), e / o < 4 && (o = o / 2);
37
+ const i = [];
38
+ let n = Math.ceil(s[0] / o) * o;
39
+ for (; n <= s[1]; )
40
+ i.push(n), n += o;
41
+ return i;
42
+ }, [s]), g = f(
41
43
  () => ({
42
44
  tickcolor: t.tickColor,
43
45
  ticklen: 12,
@@ -55,9 +57,9 @@ const _ = -1.8, A = ({
55
57
  zeroline: !1
56
58
  }),
57
59
  [t]
58
- ), I = s(
60
+ ), I = f(
59
61
  () => ({
60
- text: x,
62
+ text: y,
61
63
  x: 0.5,
62
64
  y: 0.95,
63
65
  xanchor: "center",
@@ -71,29 +73,33 @@ const _ = -1.8, A = ({
71
73
  standoff: 30
72
74
  }
73
75
  }),
74
- [x, t]
76
+ [y, t]
75
77
  );
76
- return z(() => {
77
- if (!f.current) return;
78
- const r = a.map((e) => ({
79
- y: e.y,
80
- x: e.x,
81
- type: "box",
82
- name: e.name,
83
- marker: {
84
- color: e.color
85
- },
86
- line: {
87
- color: e.color
88
- },
89
- fillcolor: e.color + "40",
90
- // Add transparency
91
- boxpoints: y ? e.boxpoints || "outliers" : !1,
92
- jitter: e.jitter || 0.3,
93
- pointpos: e.pointpos || _
94
- })), o = {
95
- width: h,
96
- height: u,
78
+ return L(() => {
79
+ if (!c.current) return;
80
+ const e = p.map((r, z) => {
81
+ const l = j(z, r.color);
82
+ return {
83
+ y: r.y,
84
+ x: r.x,
85
+ type: "box",
86
+ name: r.name,
87
+ hoverinfo: "none",
88
+ marker: {
89
+ color: l
90
+ },
91
+ line: {
92
+ color: l
93
+ },
94
+ fillcolor: typeof l == "string" && l.startsWith("#") && l.length === 7 ? `${l}40` : l,
95
+ // Add transparency for hex colors only
96
+ boxpoints: M ? r.boxpoints || "outliers" : !1,
97
+ jitter: r.jitter || 0.3,
98
+ pointpos: r.pointpos || A
99
+ };
100
+ }), o = {
101
+ width: d,
102
+ height: x,
97
103
  title: I,
98
104
  margin: { l: 80, r: 40, b: 80, t: 80, pad: 0 },
99
105
  paper_bgcolor: t.paperBg,
@@ -104,7 +110,7 @@ const _ = -1.8, A = ({
104
110
  dragmode: !1,
105
111
  xaxis: {
106
112
  title: {
107
- text: d,
113
+ text: h,
108
114
  font: {
109
115
  size: 16,
110
116
  color: t.textSecondary,
@@ -114,14 +120,14 @@ const _ = -1.8, A = ({
114
120
  standoff: 15
115
121
  },
116
122
  gridcolor: t.gridColor,
117
- range: p,
118
- autorange: !p,
123
+ range: m,
124
+ autorange: !m,
119
125
  showgrid: !0,
120
- ...m
126
+ ...g
121
127
  },
122
128
  yaxis: {
123
129
  title: {
124
- text: g,
130
+ text: u,
125
131
  font: {
126
132
  size: 16,
127
133
  color: t.textSecondary,
@@ -131,12 +137,12 @@ const _ = -1.8, A = ({
131
137
  standoff: 15
132
138
  },
133
139
  gridcolor: t.gridColor,
134
- range: c,
135
- autorange: !c,
140
+ range: a,
141
+ autorange: !a,
136
142
  tickmode: "array",
137
- tickvals: k,
143
+ tickvals: C,
138
144
  showgrid: !0,
139
- ...m
145
+ ...g
140
146
  },
141
147
  legend: {
142
148
  x: 0.5,
@@ -153,19 +159,22 @@ const _ = -1.8, A = ({
153
159
  }
154
160
  },
155
161
  showlegend: !0
156
- }, l = {
162
+ }, i = {
157
163
  responsive: !0,
158
164
  displayModeBar: !1,
159
165
  displaylogo: !1
160
166
  };
161
- C.newPlot(f.current, r, o, l);
162
- const n = f.current;
167
+ E.newPlot(c.current, e, o, i), w(c.current);
168
+ const n = c.current;
163
169
  return () => {
164
- n && C.purge(n);
170
+ n && E.purge(n);
165
171
  };
166
- }, [a, h, u, p, c, i, d, g, y, I, m, k, t]), /* @__PURE__ */ b("div", { className: "boxplot-container", children: /* @__PURE__ */ b("div", { ref: f, style: { width: "100%", height: "100%" } }) });
172
+ }, [p, d, x, m, a, s, h, u, M, I, g, C, t, w]), /* @__PURE__ */ N("div", { className: "boxplot-container relative", children: [
173
+ /* @__PURE__ */ _("div", { ref: c, style: { width: "100%", height: "100%" } }),
174
+ v
175
+ ] });
167
176
  };
168
177
  export {
169
- A as Boxplot
178
+ W as Boxplot
170
179
  };
171
180
  //# sourceMappingURL=Boxplot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Boxplot.js","sources":["../../../../src/components/charts/Boxplot/Boxplot.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\n\n/** Default point position offset from the box edge */\nconst DEFAULT_POINT_POSITION = -1.8;\n\ninterface BoxDataSeries {\n y: number[];\n name: string;\n color: string;\n x?: string[] | number[];\n boxpoints?: \"all\" | \"outliers\" | \"suspectedoutliers\" | false;\n jitter?: number;\n pointpos?: number;\n}\n\ninterface BoxplotProps {\n dataSeries: BoxDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n xTitle?: string;\n yTitle?: string;\n title?: string;\n showPoints?: boolean;\n}\n\nconst Boxplot: React.FC<BoxplotProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Boxplot\",\n showPoints = false,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n\n const { yMin, yMax } = useMemo(() => {\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const yPadding = (maxY - minY) * 0.1;\n\n return {\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 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 const titleOptions = useMemo(\n () => ({\n text: title,\n x: 0.5,\n y: 0.95,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n font: {\n size: 32,\n weight: 600,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n lineheight: 1.2,\n standoff: 30,\n },\n }),\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const data = dataSeries.map((series) => ({\n y: series.y,\n x: series.x,\n type: \"box\" as const,\n name: series.name,\n marker: {\n color: series.color,\n },\n line: {\n color: series.color,\n },\n fillcolor: series.color + \"40\", // Add transparency\n boxpoints: showPoints ? series.boxpoints || \"outliers\" : (false as const),\n jitter: series.jitter || 0.3,\n pointpos: series.pointpos || DEFAULT_POINT_POSITION,\n }));\n\n const layout = {\n width,\n height: height,\n title: titleOptions,\n margin: { l: 80, r: 40, b: 80, t: 80, pad: 0 },\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: 15,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\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: 15,\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: 13,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n lineheight: 18,\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, data, layout, config);\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, effectiveYRange, xTitle, yTitle, showPoints, titleOptions, tickOptions, yTicks, theme]);\n\n return (\n <div className=\"boxplot-container\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n </div>\n );\n};\n\nexport { Boxplot };\nexport type { BoxDataSeries, BoxplotProps };\n"],"names":["DEFAULT_POINT_POSITION","Boxplot","dataSeries","width","height","xRange","yRange","xTitle","yTitle","title","showPoints","plotRef","useRef","theme","usePlotlyTheme","yMin","yMax","useMemo","minY","maxY","series","y","yPadding","effectiveYRange","yTicks","range","step","ticks","current","tickOptions","titleOptions","useEffect","data","layout","config","Plotly","plotElement","jsx"],"mappings":";;;;AAMA,MAAMA,IAAyB,MAwBzBC,IAAkC,CAAC;AAAA,EACvC,YAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC,IAAS;AAAA,EACT,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,QAAAC,IAAS;AAAA,EACT,OAAAC,IAAQ;AAAA,EACR,YAAAC,IAAa;AACf,MAAM;AACJ,QAAMC,IAAUC,EAAuB,IAAI,GACrCC,IAAQC,EAAA,GAER,EAAE,MAAAC,GAAM,MAAAC,EAAA,IAASC,EAAQ,MAAM;AACnC,QAAIC,IAAO,OAAO,WACdC,IAAO,OAAO;AAElB,IAAAjB,EAAW,QAAQ,CAACkB,MAAW;AAC7B,MAAAA,EAAO,EAAE,QAAQ,CAACC,MAAM;AACtB,QAAAH,IAAO,KAAK,IAAIA,GAAMG,CAAC,GACvBF,IAAO,KAAK,IAAIA,GAAME,CAAC;AAAA,MACzB,CAAC;AAAA,IACH,CAAC;AAED,UAAMC,KAAYH,IAAOD,KAAQ;AAEjC,WAAO;AAAA,MACL,MAAMA,IAAOI;AAAA,MACb,MAAMH,IAAOG;AAAA,IAAA;AAAA,EAEjB,GAAG,CAACpB,CAAU,CAAC,GAETqB,IAAkBN;AAAA,IACtB,MAAMX,KAAU,CAACS,GAAMC,CAAI;AAAA,IAC3B,CAACV,GAAQS,GAAMC,CAAI;AAAA,EAAA,GAGfQ,IAASP,EAAQ,MAAM;AAC3B,UAAMQ,IAAQF,EAAgB,CAAC,IAAIA,EAAgB,CAAC;AACpD,QAAIG,IAAO,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK,MAAMD,CAAK,CAAC,CAAC;AAErD,IAAIA,IAAQC,IAAO,OAAIA,IAAOA,IAAO,IACjCD,IAAQC,IAAO,MAAGA,IAAOA,IAAO;AAEpC,UAAMC,IAAQ,CAAA;AACd,QAAIC,IAAU,KAAK,KAAKL,EAAgB,CAAC,IAAIG,CAAI,IAAIA;AACrD,WAAOE,KAAWL,EAAgB,CAAC;AACjC,MAAAI,EAAM,KAAKC,CAAO,GAClBA,KAAWF;AAEb,WAAOC;AAAA,EACT,GAAG,CAACJ,CAAe,CAAC,GAEdM,IAAcZ;AAAA,IAClB,OAAO;AAAA,MACL,WAAWJ,EAAM;AAAA,MACjB,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU;AAAA,QACR,MAAM;AAAA,QACN,OAAOA,EAAM;AAAA,QACb,QAAQ;AAAA,QACR,QAAQ;AAAA,MAAA;AAAA,MAEV,WAAWA,EAAM;AAAA,MACjB,WAAW;AAAA,MACX,UAAU;AAAA,MACV,UAAU;AAAA,IAAA;AAAA,IAEZ,CAACA,CAAK;AAAA,EAAA,GAGFiB,IAAeb;AAAA,IACnB,OAAO;AAAA,MACL,MAAMR;AAAA,MACN,GAAG;AAAA,MACH,GAAG;AAAA,MACH,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,OAAOI,EAAM;AAAA,QACb,YAAY;AAAA,QACZ,UAAU;AAAA,MAAA;AAAA,IACZ;AAAA,IAEF,CAACJ,GAAOI,CAAK;AAAA,EAAA;AAGf,SAAAkB,EAAU,MAAM;AACd,QAAI,CAACpB,EAAQ,QAAS;AAEtB,UAAMqB,IAAO9B,EAAW,IAAI,CAACkB,OAAY;AAAA,MACvC,GAAGA,EAAO;AAAA,MACV,GAAGA,EAAO;AAAA,MACV,MAAM;AAAA,MACN,MAAMA,EAAO;AAAA,MACb,QAAQ;AAAA,QACN,OAAOA,EAAO;AAAA,MAAA;AAAA,MAEhB,MAAM;AAAA,QACJ,OAAOA,EAAO;AAAA,MAAA;AAAA,MAEhB,WAAWA,EAAO,QAAQ;AAAA;AAAA,MAC1B,WAAWV,IAAaU,EAAO,aAAa,aAAc;AAAA,MAC1D,QAAQA,EAAO,UAAU;AAAA,MACzB,UAAUA,EAAO,YAAYpB;AAAA,IAAA,EAC7B,GAEIiC,IAAS;AAAA,MACb,OAAA9B;AAAA,MACA,QAAAC;AAAA,MACA,OAAO0B;AAAA,MACP,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK,EAAA;AAAA,MAC3C,eAAejB,EAAM;AAAA,MACrB,cAAcA,EAAM;AAAA,MACpB,MAAM;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,MAEV,UAAU;AAAA,MACV,OAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAMN;AAAA,UACN,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAOM,EAAM;AAAA,YACb,QAAQ;AAAA,YACR,QAAQ;AAAA,UAAA;AAAA,UAEV,UAAU;AAAA,QAAA;AAAA,QAEZ,WAAWA,EAAM;AAAA,QACjB,OAAOR;AAAA,QACP,WAAW,CAACA;AAAA,QACZ,UAAU;AAAA,QACV,GAAGwB;AAAA,MAAA;AAAA,MAEL,OAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAMrB;AAAA,UACN,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAOK,EAAM;AAAA,YACb,QAAQ;AAAA,YACR,QAAQ;AAAA,UAAA;AAAA,UAEV,UAAU;AAAA,QAAA;AAAA,QAEZ,WAAWA,EAAM;AAAA,QACjB,OAAOP;AAAA,QACP,WAAW,CAACA;AAAA,QACZ,UAAU;AAAA,QACV,UAAUkB;AAAA,QACV,UAAU;AAAA,QACV,GAAGK;AAAA,MAAA;AAAA,MAEL,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,GAAG;AAAA,QACH,SAAS;AAAA,QACT,SAAS;AAAA,QACT,aAAa;AAAA,QACb,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,OAAOhB,EAAM;AAAA,UACb,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,YAAY;AAAA,QAAA;AAAA,MACd;AAAA,MAEF,YAAY;AAAA,IAAA,GAGRqB,IAAS;AAAA,MACb,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,IAAA;AAGf,IAAAC,EAAO,QAAQxB,EAAQ,SAASqB,GAAMC,GAAQC,CAAM;AAGpD,UAAME,IAAczB,EAAQ;AAG5B,WAAO,MAAM;AACX,MAAIyB,KACFD,EAAO,MAAMC,CAAW;AAAA,IAE5B;AAAA,EACF,GAAG,CAAClC,GAAYC,GAAOC,GAAQC,GAAQC,GAAQiB,GAAiBhB,GAAQC,GAAQE,GAAYoB,GAAcD,GAAaL,GAAQX,CAAK,CAAC,GAGnI,gBAAAwB,EAAC,OAAA,EAAI,WAAU,qBACb,4BAAC,OAAA,EAAI,KAAK1B,GAAS,OAAO,EAAE,OAAO,QAAQ,QAAQ,OAAA,GAAU,GAC/D;AAEJ;"}
1
+ {"version":3,"file":"Boxplot.js","sources":["../../../../src/components/charts/Boxplot/Boxplot.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\n/** Default point position offset from the box edge */\nconst DEFAULT_POINT_POSITION = -1.8;\n\ninterface BoxDataSeries {\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n x?: string[] | number[];\n boxpoints?: \"all\" | \"outliers\" | \"suspectedoutliers\" | false;\n jitter?: number;\n pointpos?: number;\n}\n\ninterface BoxplotProps {\n dataSeries: BoxDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n xTitle?: string;\n yTitle?: string;\n title?: string;\n showPoints?: boolean;\n}\n\nconst Boxplot: React.FC<BoxplotProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Boxplot\",\n showPoints = false,\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 minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const yPadding = (maxY - minY) * 0.1;\n\n return {\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 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 const titleOptions = useMemo(\n () => ({\n text: title,\n x: 0.5,\n y: 0.95,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n font: {\n size: 32,\n weight: 600,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n lineheight: 1.2,\n standoff: 30,\n },\n }),\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const data = dataSeries.map((series, index) => {\n const color = seriesColor(index, series.color);\n return {\n y: series.y,\n x: series.x,\n type: \"box\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color,\n },\n line: {\n color,\n },\n fillcolor:\n typeof color === \"string\" && color.startsWith(\"#\") && color.length === 7\n ? `${color}40`\n : color, // Add transparency for hex colors only\n boxpoints: showPoints\n ? series.boxpoints || \"outliers\"\n : (false as const),\n jitter: series.jitter || 0.3,\n pointpos: series.pointpos || DEFAULT_POINT_POSITION,\n };\n });\n\n const layout = {\n width,\n height: height,\n title: titleOptions,\n margin: { l: 80, r: 40, b: 80, t: 80, pad: 0 },\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: 15,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\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: 15,\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: 13,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n lineheight: 18,\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, 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, effectiveYRange, xTitle, yTitle, showPoints, titleOptions, tickOptions, yTicks, theme, bindTooltip]);\n\n return (\n <div className=\"boxplot-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { Boxplot };\nexport type { BoxDataSeries, BoxplotProps };\n"],"names":["DEFAULT_POINT_POSITION","Boxplot","dataSeries","width","height","xRange","yRange","xTitle","yTitle","title","showPoints","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minY","maxY","series","y","yPadding","effectiveYRange","yTicks","range","step","ticks","current","tickOptions","titleOptions","useEffect","data","index","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("react/jsx-runtime"),j=require("plotly.js-dist"),u=require("react"),O=require("react-dom"),A=require("./lines.cjs"),L=require("../../../lib/utils.cjs"),X=20,q=150,H=200,y=8,W=10,I={top:"bottom",bottom:"top",left:"right",right:"left"},z={top:{wrapper:"-translate-x-1/2 -translate-y-[calc(100%+10px)]",arrow:"-bottom-1 left-1/2 -translate-x-1/2"},bottom:{wrapper:"-translate-x-1/2 translate-y-[10px]",arrow:"-top-1 left-1/2 -translate-x-1/2"},left:{wrapper:"-translate-y-1/2 -translate-x-[calc(100%+10px)]",arrow:"-right-1 top-1/2 -translate-y-1/2"},right:{wrapper:"-translate-y-1/2 translate-x-[10px]",arrow:"-left-1 top-1/2 -translate-y-1/2"}},k=(t,o,n,r)=>{const e=y,s=W,i={top:o.top-s-r>=e,bottom:o.top+s+r<=window.innerHeight-e,left:o.left-s-n>=e,right:o.left+s+n<=window.innerWidth-e};return!i[t]&&i[I[t]]?I[t]:t};function N({anchor:t,bubbleRef:o}){const n=u.useRef(null),r=t?.side??"top",[e,s]=u.useState(r),i=u.useCallback(l=>{n.current=l,typeof o=="function"?o(l):o&&(o.current=l)},[o]);if(u.useLayoutEffect(()=>{const l=n.current;if(!t||!l)return;const c=k(r,t,l.offsetWidth,l.offsetHeight);s(x=>x===c?x:c)},[t,r]),!t)return null;const p=z[e];return O.createPortal(m.jsx("div",{"data-slot":"chart-tooltip-anchor",className:"pointer-events-none fixed z-50",style:{left:t.left,top:t.top},children:m.jsx("div",{ref:i,className:L.cn("w-max",p.wrapper),children:m.jsxs("div",{role:"tooltip","data-slot":"tooltip-content","data-side":e,className:L.cn("relative w-fit max-w-xs rounded-md bg-foreground px-3 py-1.5 text-xs text-background",t.closing?"animate-out fade-out zoom-out-95 fill-mode-forwards":"animate-in fade-in-0 zoom-in-95"),children:[t.lines.map((l,c)=>m.jsx("div",{children:l},`${c}-${l}`)),m.jsx("span",{"aria-hidden":!0,className:L.cn("absolute size-2.5 rotate-45 rounded-[2px] bg-foreground",p.arrow)})]})})}),document.body)}const G=(t,o,n,r)=>{const e=n/2,s=Math.min(Math.max(t,e+y),window.innerWidth-e-y),i=Math.min(Math.max(o,r+10+y),window.innerHeight-y);return{left:s,top:i}};function Y(t={}){const[o,n]=u.useState(null),r=u.useRef(void 0),e=u.useRef(t);e.current=t;const s=u.useRef(null),i=u.useRef(null),p=u.useRef(null);return{bindTooltip:u.useCallback(c=>{if(!c)return;p.current?.(),p.current=null,n(null),i.current=null,j.relayout(c,{hoverdistance:e.current.hoverDistance??X});const x=c,M=(a,f,w)=>{const T=s.current,{left:v,top:R}=G(f,w,T?.offsetWidth??0,T?.offsetHeight??0);n({left:v,top:R,lines:a,side:e.current.side})};x.on("plotly_hover",a=>{const f=a.points??[],{getLines:w,xLabel:T,yLabel:v,followCursor:R}=e.current,g=w?w(f):A.chartTooltipLines(f,{xLabel:T,yLabel:v});if(g.length===0)return;clearTimeout(r.current);const h=a.event;if(R){i.current=g,M(g,h?.clientX??0,h?.clientY??0);return}const b=f[0],d=b?.bbox;let E=0,S=0;if(d){const C=c.getBoundingClientRect();E=C.left+(d.x0+d.x1)/2;const _=b?.yaxis;d.y0===d.y1&&typeof b?.y=="number"&&typeof _?.l2p=="function"&&typeof _._offset=="number"?S=C.top+_._offset+_.l2p(b.y):S=C.top+Math.min(d.y0,d.y1)}else h&&(E=h.clientX,S=h.clientY);n({left:E,top:S,lines:g,side:e.current.side})});const P=a=>{if(!e.current.followCursor)return;const f=i.current;f&&M(f,a.clientX,a.clientY)};c.addEventListener("mousemove",P),p.current=()=>c.removeEventListener("mousemove",P),x.on("plotly_unhover",()=>{clearTimeout(r.current),i.current=null,r.current=setTimeout(()=>{n(a=>a&&{...a,closing:!0}),r.current=setTimeout(()=>n(null),H)},q)})},[]),tooltipElement:m.jsx(N,{anchor:o,bubbleRef:s})}}exports.chartTooltipLines=A.chartTooltipLines;exports.ChartTooltip=N;exports.useChartTooltip=Y;
2
+ //# sourceMappingURL=ChartTooltip.cjs.map