@tetrascience-npm/tetrascience-react-ui 0.6.0-beta.82.1 → 0.6.0-beta.83.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 (70) 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 +79 -75
  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 +37 -36
  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 +84 -80
  12. package/dist/components/charts/Boxplot/Boxplot.js.map +1 -1
  13. package/dist/components/charts/Chromatogram/Chromatogram.cjs +1 -1
  14. package/dist/components/charts/Chromatogram/Chromatogram.cjs.map +1 -1
  15. package/dist/components/charts/Chromatogram/Chromatogram.js +51 -46
  16. package/dist/components/charts/Chromatogram/Chromatogram.js.map +1 -1
  17. package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs +1 -1
  18. package/dist/components/charts/ChromatogramChart/ChromatogramChart.cjs.map +1 -1
  19. package/dist/components/charts/ChromatogramChart/ChromatogramChart.js +47 -47
  20. package/dist/components/charts/ChromatogramChart/ChromatogramChart.js.map +1 -1
  21. package/dist/components/charts/ChromatogramChart/annotations.cjs +1 -1
  22. package/dist/components/charts/ChromatogramChart/annotations.cjs.map +1 -1
  23. package/dist/components/charts/ChromatogramChart/annotations.js +32 -32
  24. package/dist/components/charts/ChromatogramChart/annotations.js.map +1 -1
  25. package/dist/components/charts/ChromatogramChart/boundaryMarkers.cjs +1 -1
  26. package/dist/components/charts/ChromatogramChart/boundaryMarkers.cjs.map +1 -1
  27. package/dist/components/charts/ChromatogramChart/boundaryMarkers.js +6 -6
  28. package/dist/components/charts/ChromatogramChart/boundaryMarkers.js.map +1 -1
  29. package/dist/components/charts/ChromatogramChart/constants.cjs +1 -1
  30. package/dist/components/charts/ChromatogramChart/constants.cjs.map +1 -1
  31. package/dist/components/charts/ChromatogramChart/constants.js +11 -5
  32. package/dist/components/charts/ChromatogramChart/constants.js.map +1 -1
  33. package/dist/components/charts/DotPlot/DotPlot.cjs +1 -1
  34. package/dist/components/charts/DotPlot/DotPlot.cjs.map +1 -1
  35. package/dist/components/charts/DotPlot/DotPlot.js +49 -59
  36. package/dist/components/charts/DotPlot/DotPlot.js.map +1 -1
  37. package/dist/components/charts/Histogram/Histogram.cjs +1 -1
  38. package/dist/components/charts/Histogram/Histogram.cjs.map +1 -1
  39. package/dist/components/charts/Histogram/Histogram.js +53 -63
  40. package/dist/components/charts/Histogram/Histogram.js.map +1 -1
  41. package/dist/components/charts/LineGraph/LineGraph.cjs +1 -1
  42. package/dist/components/charts/LineGraph/LineGraph.cjs.map +1 -1
  43. package/dist/components/charts/LineGraph/LineGraph.js +87 -83
  44. package/dist/components/charts/LineGraph/LineGraph.js.map +1 -1
  45. package/dist/components/charts/PieChart/PieChart.cjs +1 -1
  46. package/dist/components/charts/PieChart/PieChart.cjs.map +1 -1
  47. package/dist/components/charts/PieChart/PieChart.js +41 -48
  48. package/dist/components/charts/PieChart/PieChart.js.map +1 -1
  49. package/dist/components/charts/PlateMap/constants.cjs +1 -1
  50. package/dist/components/charts/PlateMap/constants.cjs.map +1 -1
  51. package/dist/components/charts/PlateMap/constants.js +20 -29
  52. package/dist/components/charts/PlateMap/constants.js.map +1 -1
  53. package/dist/components/charts/ScatterGraph/ScatterGraph.cjs +1 -1
  54. package/dist/components/charts/ScatterGraph/ScatterGraph.cjs.map +1 -1
  55. package/dist/components/charts/ScatterGraph/ScatterGraph.js +40 -39
  56. package/dist/components/charts/ScatterGraph/ScatterGraph.js.map +1 -1
  57. package/dist/hooks/use-plotly-theme.cjs +1 -1
  58. package/dist/hooks/use-plotly-theme.cjs.map +1 -1
  59. package/dist/hooks/use-plotly-theme.js +4 -2
  60. package/dist/hooks/use-plotly-theme.js.map +1 -1
  61. package/dist/index.cjs +1 -1
  62. package/dist/index.css +1 -1
  63. package/dist/index.d.ts +26 -76
  64. package/dist/index.js +37 -36
  65. package/dist/index.tailwind.css +1 -1
  66. package/dist/utils/colors.cjs +1 -1
  67. package/dist/utils/colors.cjs.map +1 -1
  68. package/dist/utils/colors.js +38 -93
  69. package/dist/utils/colors.js.map +1 -1
  70. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Histogram.js","sources":["../../../../src/components/charts/Histogram/Histogram.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { COLORS } from \"@/utils/colors\";\nimport \"./Histogram.scss\";\n\n/** Exponent coefficient for normal distribution calculation */\nconst NORMAL_DISTRIBUTION_EXPONENT_COEFF = -0.5;\n\ninterface HistogramDataSeries {\n x: number[];\n name: string;\n color?: string;\n autobinx?: boolean;\n xbins?: {\n start: number;\n end: number;\n size: number;\n };\n opacity?: number;\n showDistributionLine?: boolean;\n lineWidth?: number;\n}\n\ntype HistogramProps = {\n dataSeries: HistogramDataSeries | HistogramDataSeries[];\n width?: number;\n height?: number;\n title?: string;\n xTitle?: string;\n yTitle?: string;\n bargap?: number;\n showDistributionLine?: boolean;\n};\n\nconst calculateMean = (data: number[]): number => {\n const sum = data.reduce((acc, val) => acc + val, 0);\n return sum / data.length;\n};\n\nconst calculateStdDev = (data: number[], mean: number): number => {\n const squaredDiffs = data.map((value) => Math.pow(value - mean, 2));\n const variance =\n squaredDiffs.reduce((acc, val) => acc + val, 0) / data.length;\n return Math.sqrt(variance);\n};\n\nconst generateNormalDistributionPoints = (\n mean: number,\n stdDev: number,\n start: number,\n end: number,\n points = 100\n): { x: number[]; y: number[] } => {\n const xValues: number[] = [];\n const yValues: number[] = [];\n\n const step = (end - start) / (points - 1);\n\n for (let i = 0; i < points; i++) {\n const x = start + i * step;\n xValues.push(x);\n\n const exponent = NORMAL_DISTRIBUTION_EXPONENT_COEFF * Math.pow((x - mean) / stdDev, 2);\n const y = (1 / (stdDev * Math.sqrt(2 * Math.PI))) * Math.exp(exponent);\n yValues.push(y);\n }\n\n return { x: xValues, y: yValues };\n};\n\nconst scaleDistributionCurve = (\n yValues: number[],\n histogramData: number[],\n bins: { start: number; end: number; size: number }\n): number[] => {\n const binCount = Math.ceil((bins.end - bins.start) / bins.size);\n const binFrequencies = Array(binCount).fill(0);\n\n histogramData.forEach((value) => {\n if (value >= bins.start && value <= bins.end) {\n const binIndex = Math.floor((value - bins.start) / bins.size);\n binFrequencies[binIndex]++;\n }\n });\n\n const maxBinFrequency = Math.max(...binFrequencies);\n const maxCurveValue = Math.max(...yValues);\n\n const scaleFactor = maxBinFrequency / maxCurveValue;\n\n return yValues.map((y) => y * scaleFactor);\n};\n\nconst Histogram: React.FC<HistogramProps> = ({\n dataSeries,\n width = 480,\n height = 480,\n title = \"Histogram\",\n xTitle = \"X Axis\",\n yTitle = \"Frequency\",\n bargap = 0.2,\n showDistributionLine = false,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const seriesArray = useMemo(\n () => (Array.isArray(dataSeries) ? dataSeries : [dataSeries]),\n [dataSeries],\n );\n const effectiveBarMode = useMemo<\n \"stack\" | \"group\" | \"overlay\" | \"relative\" | undefined\n >(() => (seriesArray.length > 1 ? \"stack\" : undefined), [seriesArray.length]);\n\n const defaultColors = useMemo(\n () => [\n COLORS.ORANGE,\n COLORS.RED,\n COLORS.BLUE,\n COLORS.GREEN,\n COLORS.PURPLE,\n COLORS.YELLOW,\n ],\n [],\n );\n\n const seriesWithColors = useMemo(() => {\n return seriesArray.map((series, index) => {\n const hasDistributionLine =\n typeof series.showDistributionLine === \"undefined\"\n ? showDistributionLine\n : series.showDistributionLine;\n\n return {\n ...series,\n color: series.color || defaultColors[index % defaultColors.length],\n opacity: hasDistributionLine ? 0.5 : series.opacity || 1,\n showDistributionLine: hasDistributionLine,\n lineWidth: series.lineWidth || 3,\n };\n });\n }, [seriesArray, showDistributionLine, defaultColors]);\n\n const gridColor = theme.gridColor;\n\n const histogramData = useMemo(\n () =>\n seriesWithColors.map((series) => ({\n type: \"histogram\" as const,\n x: series.x,\n name: series.name,\n marker: {\n color: series.color,\n line: {\n color: theme.paperBg,\n width: 1,\n },\n opacity: series.opacity,\n },\n autobinx: series.autobinx,\n xbins: series.xbins,\n hovertemplate: `${xTitle}: %{x}<br>${yTitle}: %{y}<extra>${series.name}</extra>`,\n })),\n [seriesWithColors, xTitle, yTitle, theme],\n );\n\n const distributionLines = useMemo(\n () =>\n seriesWithColors\n .filter((series) => series.showDistributionLine)\n .map((series) => {\n const mean = calculateMean(series.x);\n const stdDev = calculateStdDev(series.x, mean);\n\n const min = Math.min(...series.x);\n const max = Math.max(...series.x);\n const range = max - min;\n const start = min - range * 0.1;\n const end = max + range * 0.1;\n\n const bins = series.xbins || {\n start: start,\n end: end,\n size: range / 10,\n };\n\n const curvePoints = generateNormalDistributionPoints(\n mean,\n stdDev,\n start,\n end,\n 100,\n );\n\n const scaledYValues = scaleDistributionCurve(\n curvePoints.y,\n series.x,\n bins,\n );\n\n return {\n type: \"scatter\" as const,\n x: curvePoints.x,\n y: scaledYValues,\n mode: \"lines\" as const,\n name: `${series.name} Distribution`,\n line: {\n color: series.color,\n width: series.lineWidth,\n },\n hoverinfo: \"none\" as const,\n };\n }),\n [seriesWithColors],\n );\n\n const plotData = useMemo(\n () => [...histogramData, ...distributionLines],\n [histogramData, distributionLines],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const layout = {\n width,\n height,\n font: {\n family: \"Inter, sans-serif\",\n },\n showlegend: false,\n margin: { l: 90, r: 40, b: 80, t: 40 },\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: 20,\n },\n gridcolor: gridColor,\n tickcolor: theme.tickColor,\n ticklen: 8,\n tickwidth: 1,\n ticks: \"outside\" as const,\n linecolor: theme.lineColor,\n linewidth: 1,\n zeroline: false,\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: 20,\n },\n gridcolor: gridColor,\n tickcolor: theme.tickColor,\n ticklen: 8,\n tickwidth: 1,\n ticks: \"outside\" as const,\n linecolor: theme.lineColor,\n linewidth: 1,\n zeroline: false,\n rangemode: \"tozero\" as const,\n },\n barmode: effectiveBarMode,\n bargap: bargap,\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\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\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [width, height, xTitle, yTitle, bargap, plotData, effectiveBarMode, gridColor, theme]);\n\n const ChartLegend: React.FC<{\n series: Array<{ name: string; color: string }>;\n }> = ({ series }) => {\n const items = series.map((item, i) => (\n <React.Fragment key={item.name}>\n <div className=\"legend-item\">\n <span className=\"color-box\" style={{ background: item.color }} />\n {item.name}\n {i < series.length - 1 && <span className=\"divider\" />}\n </div>\n </React.Fragment>\n ));\n\n const rows = [];\n const rowSize = 6;\n for (let i = 0; i < items.length; i += rowSize) {\n rows.push(\n <div className=\"legend-row\" key={i}>\n {items.slice(i, i + rowSize)}\n </div>\n );\n }\n\n return <div className=\"legend-container\">{rows}</div>;\n };\n\n return (\n <div className=\"histogram-container\" style={{ width: width }}>\n <div className=\"chart-container\">\n {title && (\n <div className=\"title-container\">\n <h2 className=\"title\">{title}</h2>\n </div>\n )}\n <div\n ref={plotRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n margin: \"0\",\n }}\n />\n <ChartLegend series={seriesWithColors} />\n </div>\n </div>\n );\n};\n\nexport { Histogram };\nexport type { HistogramDataSeries, HistogramProps };\n"],"names":["NORMAL_DISTRIBUTION_EXPONENT_COEFF","calculateMean","data","acc","val","calculateStdDev","mean","variance","value","generateNormalDistributionPoints","stdDev","start","end","points","xValues","yValues","step","i","x","exponent","y","scaleDistributionCurve","histogramData","bins","binCount","binFrequencies","binIndex","maxBinFrequency","maxCurveValue","scaleFactor","Histogram","dataSeries","width","height","title","xTitle","yTitle","bargap","showDistributionLine","plotRef","useRef","theme","usePlotlyTheme","seriesArray","useMemo","effectiveBarMode","defaultColors","COLORS","seriesWithColors","series","index","hasDistributionLine","gridColor","distributionLines","min","max","range","curvePoints","scaledYValues","plotData","useEffect","layout","config","Plotly","plotElement","jsx","jsxs","items","item","React","rows","rowSize"],"mappings":"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"}
1
+ {"version":3,"file":"Histogram.js","sources":["../../../../src/components/charts/Histogram/Histogram.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { CHART_COLORS } from \"@/utils/colors\";\nimport \"./Histogram.scss\";\n\n/** Exponent coefficient for normal distribution calculation */\nconst NORMAL_DISTRIBUTION_EXPONENT_COEFF = -0.5;\n\ninterface HistogramDataSeries {\n x: number[];\n name: string;\n color?: string;\n autobinx?: boolean;\n xbins?: {\n start: number;\n end: number;\n size: number;\n };\n opacity?: number;\n showDistributionLine?: boolean;\n lineWidth?: number;\n}\n\ntype HistogramProps = {\n dataSeries: HistogramDataSeries | HistogramDataSeries[];\n width?: number;\n height?: number;\n title?: string;\n xTitle?: string;\n yTitle?: string;\n bargap?: number;\n showDistributionLine?: boolean;\n};\n\nconst calculateMean = (data: number[]): number => {\n const sum = data.reduce((acc, val) => acc + val, 0);\n return sum / data.length;\n};\n\nconst calculateStdDev = (data: number[], mean: number): number => {\n const squaredDiffs = data.map((value) => Math.pow(value - mean, 2));\n const variance =\n squaredDiffs.reduce((acc, val) => acc + val, 0) / data.length;\n return Math.sqrt(variance);\n};\n\nconst generateNormalDistributionPoints = (\n mean: number,\n stdDev: number,\n start: number,\n end: number,\n points = 100\n): { x: number[]; y: number[] } => {\n const xValues: number[] = [];\n const yValues: number[] = [];\n\n const step = (end - start) / (points - 1);\n\n for (let i = 0; i < points; i++) {\n const x = start + i * step;\n xValues.push(x);\n\n const exponent = NORMAL_DISTRIBUTION_EXPONENT_COEFF * Math.pow((x - mean) / stdDev, 2);\n const y = (1 / (stdDev * Math.sqrt(2 * Math.PI))) * Math.exp(exponent);\n yValues.push(y);\n }\n\n return { x: xValues, y: yValues };\n};\n\nconst scaleDistributionCurve = (\n yValues: number[],\n histogramData: number[],\n bins: { start: number; end: number; size: number }\n): number[] => {\n const binCount = Math.ceil((bins.end - bins.start) / bins.size);\n const binFrequencies = Array(binCount).fill(0);\n\n histogramData.forEach((value) => {\n if (value >= bins.start && value <= bins.end) {\n const binIndex = Math.floor((value - bins.start) / bins.size);\n binFrequencies[binIndex]++;\n }\n });\n\n const maxBinFrequency = Math.max(...binFrequencies);\n const maxCurveValue = Math.max(...yValues);\n\n const scaleFactor = maxBinFrequency / maxCurveValue;\n\n return yValues.map((y) => y * scaleFactor);\n};\n\nconst Histogram: React.FC<HistogramProps> = ({\n dataSeries,\n width = 480,\n height = 480,\n title = \"Histogram\",\n xTitle = \"X Axis\",\n yTitle = \"Frequency\",\n bargap = 0.2,\n showDistributionLine = false,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const seriesArray = useMemo(\n () => (Array.isArray(dataSeries) ? dataSeries : [dataSeries]),\n [dataSeries],\n );\n const effectiveBarMode = useMemo<\n \"stack\" | \"group\" | \"overlay\" | \"relative\" | undefined\n >(() => (seriesArray.length > 1 ? \"stack\" : undefined), [seriesArray.length]);\n\n const defaultColors = CHART_COLORS;\n\n const seriesWithColors = useMemo(() => {\n return seriesArray.map((series, index) => {\n const hasDistributionLine =\n typeof series.showDistributionLine === \"undefined\"\n ? showDistributionLine\n : series.showDistributionLine;\n\n return {\n ...series,\n color: series.color || defaultColors[index % defaultColors.length],\n opacity: hasDistributionLine ? 0.5 : series.opacity || 1,\n showDistributionLine: hasDistributionLine,\n lineWidth: series.lineWidth || 3,\n };\n });\n }, [seriesArray, showDistributionLine, defaultColors]);\n\n const gridColor = theme.gridColor;\n\n const histogramData = useMemo(\n () =>\n seriesWithColors.map((series) => ({\n type: \"histogram\" as const,\n x: series.x,\n name: series.name,\n marker: {\n color: series.color,\n line: {\n color: theme.paperBg,\n width: 1,\n },\n opacity: series.opacity,\n },\n autobinx: series.autobinx,\n xbins: series.xbins,\n hovertemplate: `${xTitle}: %{x}<br>${yTitle}: %{y}<extra>${series.name}</extra>`,\n })),\n [seriesWithColors, xTitle, yTitle, theme],\n );\n\n const distributionLines = useMemo(\n () =>\n seriesWithColors\n .filter((series) => series.showDistributionLine)\n .map((series) => {\n const mean = calculateMean(series.x);\n const stdDev = calculateStdDev(series.x, mean);\n\n const min = Math.min(...series.x);\n const max = Math.max(...series.x);\n const range = max - min;\n const start = min - range * 0.1;\n const end = max + range * 0.1;\n\n const bins = series.xbins || {\n start: start,\n end: end,\n size: range / 10,\n };\n\n const curvePoints = generateNormalDistributionPoints(\n mean,\n stdDev,\n start,\n end,\n 100,\n );\n\n const scaledYValues = scaleDistributionCurve(\n curvePoints.y,\n series.x,\n bins,\n );\n\n return {\n type: \"scatter\" as const,\n x: curvePoints.x,\n y: scaledYValues,\n mode: \"lines\" as const,\n name: `${series.name} Distribution`,\n line: {\n color: series.color,\n width: series.lineWidth,\n },\n hoverinfo: \"none\" as const,\n };\n }),\n [seriesWithColors],\n );\n\n const plotData = useMemo(\n () => [...histogramData, ...distributionLines],\n [histogramData, distributionLines],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const layout = {\n width,\n height,\n font: {\n family: \"Inter, sans-serif\",\n },\n showlegend: false,\n margin: { l: 90, r: 40, b: 80, t: 40 },\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: 20,\n },\n gridcolor: gridColor,\n tickcolor: theme.tickColor,\n ticklen: 8,\n tickwidth: 1,\n ticks: \"outside\" as const,\n linecolor: theme.lineColor,\n linewidth: 1,\n zeroline: false,\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: 20,\n },\n gridcolor: gridColor,\n tickcolor: theme.tickColor,\n ticklen: 8,\n tickwidth: 1,\n ticks: \"outside\" as const,\n linecolor: theme.lineColor,\n linewidth: 1,\n zeroline: false,\n rangemode: \"tozero\" as const,\n },\n barmode: effectiveBarMode,\n bargap: bargap,\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\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\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [width, height, xTitle, yTitle, bargap, plotData, effectiveBarMode, gridColor, theme]);\n\n const ChartLegend: React.FC<{\n series: Array<{ name: string; color: string }>;\n }> = ({ series }) => {\n const items = series.map((item, i) => (\n <React.Fragment key={item.name}>\n <div className=\"legend-item\">\n <span className=\"color-box\" style={{ background: item.color }} />\n {item.name}\n {i < series.length - 1 && <span className=\"divider\" />}\n </div>\n </React.Fragment>\n ));\n\n const rows = [];\n const rowSize = 6;\n for (let i = 0; i < items.length; i += rowSize) {\n rows.push(\n <div className=\"legend-row\" key={i}>\n {items.slice(i, i + rowSize)}\n </div>\n );\n }\n\n return <div className=\"legend-container\">{rows}</div>;\n };\n\n return (\n <div className=\"histogram-container\" style={{ width: width }}>\n <div className=\"chart-container\">\n {title && (\n <div className=\"title-container\">\n <h2 className=\"title\">{title}</h2>\n </div>\n )}\n <div\n ref={plotRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n margin: \"0\",\n }}\n />\n <ChartLegend series={seriesWithColors} />\n </div>\n </div>\n );\n};\n\nexport { Histogram };\nexport type { HistogramDataSeries, HistogramProps };\n"],"names":["NORMAL_DISTRIBUTION_EXPONENT_COEFF","calculateMean","data","acc","val","calculateStdDev","mean","variance","value","generateNormalDistributionPoints","stdDev","start","end","points","xValues","yValues","step","i","x","exponent","y","scaleDistributionCurve","histogramData","bins","binCount","binFrequencies","binIndex","maxBinFrequency","maxCurveValue","scaleFactor","Histogram","dataSeries","width","height","title","xTitle","yTitle","bargap","showDistributionLine","plotRef","useRef","theme","usePlotlyTheme","seriesArray","useMemo","effectiveBarMode","defaultColors","CHART_COLORS","seriesWithColors","series","index","hasDistributionLine","gridColor","distributionLines","min","max","range","curvePoints","scaledYValues","plotData","useEffect","layout","config","Plotly","plotElement","jsx","jsxs","items","item","React","rows","rowSize"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const z=require("react/jsx-runtime"),L=require("plotly.js-dist"),i=require("react"),N=require("../../../hooks/use-plotly-theme.cjs"),P=({dataSeries:s,width:p=1e3,height:g=600,xRange:h,yRange:a,variant:m="lines",xTitle:x="Columns",yTitle:M="Rows",title:k="Line Graph"})=>{const f=i.useRef(null),t=N.usePlotlyTheme(),{yMin:w,yMax:b}=i.useMemo(()=>{let o=Number.MAX_VALUE,e=Number.MIN_VALUE,l=Number.MAX_VALUE,n=Number.MIN_VALUE;s.forEach(I=>{I.x.forEach(u=>{o=Math.min(o,u),e=Math.max(e,u)}),I.y.forEach(u=>{l=Math.min(l,u),n=Math.max(n,u)})});const r=(e-o)*.1,C=(n-l)*.1;return{xMin:o-r,xMax:e+r,yMin:l-C,yMax:n+C}},[s]),c=i.useMemo(()=>a||[w,b],[a,w,b]),_=i.useMemo(()=>{const o=c[1]-c[0];let e=Math.pow(10,Math.floor(Math.log10(o)));o/e>10&&(e=e*2),o/e<4&&(e=e/2);const l=[];let n=Math.ceil(c[0]/e)*e;for(;n<=c[1];)l.push(n),n+=e;return l},[c]),d=i.useMemo(()=>[...new Set(s.flatMap(o=>o.x))],[s]),E=i.useMemo(()=>{switch(m){case"lines+markers":case"lines+markers+error_bars":return"lines+markers";default:return"lines"}},[m]),y=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]);return i.useEffect(()=>{if(!f.current)return;const o=s.map(r=>({x:r.x,y:r.y,type:"scatter",mode:E,name:r.name,line:{color:r.color,width:1.5},marker:m==="lines"?{opacity:0}:{color:r.color,size:8,symbol:r.symbol||"triangle-up"},error_y:m==="lines+markers+error_bars"?r.error_y||{type:"data",array:r.y.map(()=>10),visible:!0,color:r.color,thickness:1,width:5}:void 0})),e={title:{text:k,font:{size:32,family:"Inter, sans-serif",color:t.textColor}},width:p,height:g,margin:{l:80,r:30,b:80,t:60,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:h,autorange:!h,tickmode:"array",tickvals:d,ticktext:d.map(String),showgrid:!0,...y},yaxis:{title:{text:M,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:30},gridcolor:t.gridColor,range:a,autorange:!a,tickmode:"array",tickvals:_,showgrid:!0,...y},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},l={responsive:!0,displayModeBar:!1,displaylogo:!1};L.newPlot(f.current,o,e,l);const n=f.current;return()=>{n&&L.purge(n)}},[s,p,g,h,a,x,M,k,E,y,d,_,c,m,t]),z.jsx("div",{className:"chart-container",children:z.jsx("div",{ref:f,style:{width:"100%",height:"100%"}})})};exports.LineGraph=P;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const z=require("react/jsx-runtime"),L=require("plotly.js-dist"),i=require("react"),N=require("../../../hooks/use-plotly-theme.cjs"),P=require("../../../utils/colors.cjs"),A=({dataSeries:l,width:x=1e3,height:M=600,xRange:y,yRange:u,variant:m="lines",xTitle:k="Columns",yTitle:w="Rows",title:b="Line Graph"})=>{const h=i.useRef(null),t=N.usePlotlyTheme(),{yMin:_,yMax:C}=i.useMemo(()=>{let o=Number.MAX_VALUE,e=Number.MIN_VALUE,s=Number.MAX_VALUE,r=Number.MIN_VALUE;l.forEach(a=>{a.x.forEach(f=>{o=Math.min(o,f),e=Math.max(e,f)}),a.y.forEach(f=>{s=Math.min(s,f),r=Math.max(r,f)})});const n=(e-o)*.1,d=(r-s)*.1;return{xMin:o-n,xMax:e+n,yMin:s-d,yMax:r+d}},[l]),c=i.useMemo(()=>u||[_,C],[u,_,C]),E=i.useMemo(()=>{const o=c[1]-c[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(c[0]/e)*e;for(;r<=c[1];)s.push(r),r+=e;return s},[c]),p=i.useMemo(()=>[...new Set(l.flatMap(o=>o.x))],[l]),I=i.useMemo(()=>{switch(m){case"lines+markers":case"lines+markers+error_bars":return"lines+markers";default:return"lines"}},[m]),g=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]);return i.useEffect(()=>{if(!h.current)return;const o=l.map((n,d)=>{const a=P.seriesColor(d,n.color);return{x:n.x,y:n.y,type:"scatter",mode:I,name:n.name,line:{color:a,width:1.5},marker:m==="lines"?{opacity:0}:{color:a,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:a,thickness:1,width:5}:void 0}}),e={title:{text:b,font:{size:32,family:"Inter, sans-serif",color:t.textColor}},width:x,height:M,margin:{l:80,r:30,b:80,t:60,pad:10},paper_bgcolor:t.paperBg,plot_bgcolor:t.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:k,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:32},gridcolor:t.gridColor,range:y,autorange:!y,tickmode:"array",tickvals:p,ticktext:p.map(String),showgrid:!0,...g},yaxis:{title:{text:w,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:30},gridcolor:t.gridColor,range:u,autorange:!u,tickmode:"array",tickvals:E,showgrid:!0,...g},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};L.newPlot(h.current,o,e,s);const r=h.current;return()=>{r&&L.purge(r)}},[l,x,M,y,u,k,w,b,I,g,p,E,c,m,t]),z.jsx("div",{className:"chart-container",children:z.jsx("div",{ref:h,style:{width:"100%",height:"100%"}})})};exports.LineGraph=A;
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 { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\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 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\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}) => {\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: 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))],\n [dataSeries],\n );\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) => ({\n x: series.x,\n y: series.y,\n type: \"scatter\" as const,\n mode: mode,\n name: series.name,\n line: {\n color: series.color,\n width: 1.5,\n },\n marker:\n variant === \"lines\"\n ? { opacity: 0 }\n : {\n color: series.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: series.color,\n thickness: 1,\n width: 5,\n }\n : undefined,\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: 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\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, effectiveYRange, variant, theme]);\n\n return (\n <div className=\"chart-container\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\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","plotRef","useRef","theme","usePlotlyTheme","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","yTicks","range","step","ticks","current","xTicks","s","mode","tickOptions","useEffect","plotData","layout","config","Plotly","plotElement","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 { 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\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}) => {\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: 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))],\n [dataSeries],\n );\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 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: 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\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, effectiveYRange, variant, theme]);\n\n return (\n <div className=\"chart-container\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\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","plotRef","useRef","theme","usePlotlyTheme","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","yTicks","range","step","ticks","current","xTicks","s","mode","tickOptions","useEffect","plotData","index","color","seriesColor","layout","config","Plotly","plotElement","jsx"],"mappings":"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"}
@@ -1,58 +1,59 @@
1
1
  import { jsx as z } from "react/jsx-runtime";
2
2
  import N from "plotly.js-dist";
3
- import { useRef as A, useMemo as s, useEffect as L } from "react";
3
+ import { useRef as A, useMemo as c, useEffect as L } from "react";
4
4
  import { usePlotlyTheme as P } from "../../../hooks/use-plotly-theme.js";
5
- const B = ({
6
- dataSeries: i,
7
- width: y = 1e3,
8
- height: g = 600,
9
- xRange: p,
10
- yRange: c,
11
- variant: m = "lines",
12
- xTitle: x = "Columns",
13
- yTitle: k = "Rows",
14
- title: M = "Line Graph"
5
+ import { seriesColor as v } from "../../../utils/colors.js";
6
+ const G = ({
7
+ dataSeries: l,
8
+ width: x = 1e3,
9
+ height: k = 600,
10
+ xRange: d,
11
+ yRange: m,
12
+ variant: f = "lines",
13
+ xTitle: M = "Columns",
14
+ yTitle: w = "Rows",
15
+ title: b = "Line Graph"
15
16
  }) => {
16
- const h = A(null), o = P(), { yMin: w, yMax: b } = s(() => {
17
- let r = Number.MAX_VALUE, t = Number.MIN_VALUE, l = Number.MAX_VALUE, n = Number.MIN_VALUE;
18
- i.forEach((I) => {
19
- I.x.forEach((f) => {
20
- r = Math.min(r, f), t = Math.max(t, f);
21
- }), I.y.forEach((f) => {
22
- l = Math.min(l, f), n = Math.max(n, f);
17
+ const h = A(null), o = P(), { yMin: _, yMax: C } = c(() => {
18
+ let r = Number.MAX_VALUE, t = Number.MIN_VALUE, i = Number.MAX_VALUE, e = Number.MIN_VALUE;
19
+ l.forEach((a) => {
20
+ a.x.forEach((p) => {
21
+ r = Math.min(r, p), t = Math.max(t, p);
22
+ }), a.y.forEach((p) => {
23
+ i = Math.min(i, p), e = Math.max(e, p);
23
24
  });
24
25
  });
25
- const e = (t - r) * 0.1, C = (n - l) * 0.1;
26
+ const n = (t - r) * 0.1, u = (e - i) * 0.1;
26
27
  return {
27
- xMin: r - e,
28
- xMax: t + e,
29
- yMin: l - C,
30
- yMax: n + C
28
+ xMin: r - n,
29
+ xMax: t + n,
30
+ yMin: i - u,
31
+ yMax: e + u
31
32
  };
32
- }, [i]), a = s(
33
- () => c || [w, b],
34
- [c, w, b]
35
- ), _ = s(() => {
36
- const r = a[1] - a[0];
33
+ }, [l]), s = c(
34
+ () => m || [_, C],
35
+ [m, _, C]
36
+ ), E = c(() => {
37
+ const r = s[1] - s[0];
37
38
  let t = Math.pow(10, Math.floor(Math.log10(r)));
38
39
  r / t > 10 && (t = t * 2), r / t < 4 && (t = t / 2);
39
- const l = [];
40
- let n = Math.ceil(a[0] / t) * t;
41
- for (; n <= a[1]; )
42
- l.push(n), n += t;
43
- return l;
44
- }, [a]), u = s(
45
- () => [...new Set(i.flatMap((r) => r.x))],
46
- [i]
47
- ), E = s(() => {
48
- switch (m) {
40
+ const i = [];
41
+ let e = Math.ceil(s[0] / t) * t;
42
+ for (; e <= s[1]; )
43
+ i.push(e), e += t;
44
+ return i;
45
+ }, [s]), y = c(
46
+ () => [...new Set(l.flatMap((r) => r.x))],
47
+ [l]
48
+ ), I = c(() => {
49
+ switch (f) {
49
50
  case "lines+markers":
50
51
  case "lines+markers+error_bars":
51
52
  return "lines+markers";
52
53
  default:
53
54
  return "lines";
54
55
  }
55
- }, [m]), d = s(
56
+ }, [f]), g = c(
56
57
  () => ({
57
58
  tickcolor: o.tickColor,
58
59
  ticklen: 12,
@@ -73,40 +74,43 @@ const B = ({
73
74
  );
74
75
  return L(() => {
75
76
  if (!h.current) return;
76
- const r = i.map((e) => ({
77
- x: e.x,
78
- y: e.y,
79
- type: "scatter",
80
- mode: E,
81
- name: e.name,
82
- line: {
83
- color: e.color,
84
- width: 1.5
85
- },
86
- marker: m === "lines" ? { opacity: 0 } : {
87
- color: e.color,
88
- size: 8,
89
- symbol: e.symbol || "triangle-up"
90
- },
91
- error_y: m === "lines+markers+error_bars" ? e.error_y || {
92
- type: "data",
93
- array: e.y.map(() => 10),
94
- visible: !0,
95
- color: e.color,
96
- thickness: 1,
97
- width: 5
98
- } : void 0
99
- })), t = {
77
+ const r = l.map((n, u) => {
78
+ const a = v(u, n.color);
79
+ return {
80
+ x: n.x,
81
+ y: n.y,
82
+ type: "scatter",
83
+ mode: I,
84
+ name: n.name,
85
+ line: {
86
+ color: a,
87
+ width: 1.5
88
+ },
89
+ marker: f === "lines" ? { opacity: 0 } : {
90
+ color: a,
91
+ size: 8,
92
+ symbol: n.symbol || "triangle-up"
93
+ },
94
+ error_y: f === "lines+markers+error_bars" ? n.error_y || {
95
+ type: "data",
96
+ array: n.y.map(() => 10),
97
+ visible: !0,
98
+ color: a,
99
+ thickness: 1,
100
+ width: 5
101
+ } : void 0
102
+ };
103
+ }), t = {
100
104
  title: {
101
- text: M,
105
+ text: b,
102
106
  font: {
103
107
  size: 32,
104
108
  family: "Inter, sans-serif",
105
109
  color: o.textColor
106
110
  }
107
111
  },
108
- width: y,
109
- height: g,
112
+ width: x,
113
+ height: k,
110
114
  margin: { l: 80, r: 30, b: 80, t: 60, pad: 10 },
111
115
  paper_bgcolor: o.paperBg,
112
116
  plot_bgcolor: o.plotBg,
@@ -116,7 +120,7 @@ const B = ({
116
120
  dragmode: !1,
117
121
  xaxis: {
118
122
  title: {
119
- text: x,
123
+ text: M,
120
124
  font: {
121
125
  size: 16,
122
126
  color: o.textSecondary,
@@ -126,17 +130,17 @@ const B = ({
126
130
  standoff: 32
127
131
  },
128
132
  gridcolor: o.gridColor,
129
- range: p,
130
- autorange: !p,
133
+ range: d,
134
+ autorange: !d,
131
135
  tickmode: "array",
132
- tickvals: u,
133
- ticktext: u.map(String),
136
+ tickvals: y,
137
+ ticktext: y.map(String),
134
138
  showgrid: !0,
135
- ...d
139
+ ...g
136
140
  },
137
141
  yaxis: {
138
142
  title: {
139
- text: k,
143
+ text: w,
140
144
  font: {
141
145
  size: 16,
142
146
  color: o.textSecondary,
@@ -146,12 +150,12 @@ const B = ({
146
150
  standoff: 30
147
151
  },
148
152
  gridcolor: o.gridColor,
149
- range: c,
150
- autorange: !c,
153
+ range: m,
154
+ autorange: !m,
151
155
  tickmode: "array",
152
- tickvals: _,
156
+ tickvals: E,
153
157
  showgrid: !0,
154
- ...d
158
+ ...g
155
159
  },
156
160
  legend: {
157
161
  x: 0.5,
@@ -167,19 +171,19 @@ const B = ({
167
171
  }
168
172
  },
169
173
  showlegend: !0
170
- }, l = {
174
+ }, i = {
171
175
  responsive: !0,
172
176
  displayModeBar: !1,
173
177
  displaylogo: !1
174
178
  };
175
- N.newPlot(h.current, r, t, l);
176
- const n = h.current;
179
+ N.newPlot(h.current, r, t, i);
180
+ const e = h.current;
177
181
  return () => {
178
- n && N.purge(n);
182
+ e && N.purge(e);
179
183
  };
180
- }, [i, y, g, p, c, x, k, M, E, d, u, _, a, m, o]), /* @__PURE__ */ z("div", { className: "chart-container", children: /* @__PURE__ */ z("div", { ref: h, style: { width: "100%", height: "100%" } }) });
184
+ }, [l, x, k, d, m, M, w, b, I, g, y, E, s, f, o]), /* @__PURE__ */ z("div", { className: "chart-container", children: /* @__PURE__ */ z("div", { ref: h, style: { width: "100%", height: "100%" } }) });
181
185
  };
182
186
  export {
183
- B as LineGraph
187
+ G as LineGraph
184
188
  };
185
189
  //# sourceMappingURL=LineGraph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LineGraph.js","sources":["../../../../src/components/charts/LineGraph/LineGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\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 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\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}) => {\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: 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))],\n [dataSeries],\n );\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) => ({\n x: series.x,\n y: series.y,\n type: \"scatter\" as const,\n mode: mode,\n name: series.name,\n line: {\n color: series.color,\n width: 1.5,\n },\n marker:\n variant === \"lines\"\n ? { opacity: 0 }\n : {\n color: series.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: series.color,\n thickness: 1,\n width: 5,\n }\n : undefined,\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: 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\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, effectiveYRange, variant, theme]);\n\n return (\n <div className=\"chart-container\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\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","plotRef","useRef","theme","usePlotlyTheme","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","yTicks","range","step","ticks","current","xTicks","s","mode","tickOptions","useEffect","plotData","layout","config","Plotly","plotElement","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"LineGraph.js","sources":["../../../../src/components/charts/LineGraph/LineGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\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\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}) => {\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: 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))],\n [dataSeries],\n );\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 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: 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\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, effectiveYRange, variant, theme]);\n\n return (\n <div className=\"chart-container\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\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","plotRef","useRef","theme","usePlotlyTheme","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","yTicks","range","step","ticks","current","xTicks","s","mode","tickOptions","useEffect","plotData","index","color","seriesColor","layout","config","Plotly","plotElement","jsx"],"mappings":";;;;;AAsLA,MAAMA,IAAsC,CAAC;AAAA,EAC3C,YAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC,IAAS;AAAA,EACT,QAAAC;AAAA,EACA,QAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,QAAAC,IAAS;AAAA,EACT,QAAAC,IAAS;AAAA,EACT,OAAAC,IAAQ;AACV,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,WACdC,IAAO,OAAO,WACdC,IAAO,OAAO;AAElB,IAAAnB,EAAW,QAAQ,CAACoB,MAAW;AAC7B,MAAAA,EAAO,EAAE,QAAQ,CAACC,MAAM;AACtB,QAAAL,IAAO,KAAK,IAAIA,GAAMK,CAAC,GACvBJ,IAAO,KAAK,IAAIA,GAAMI,CAAC;AAAA,MACzB,CAAC,GACDD,EAAO,EAAE,QAAQ,CAACE,MAAM;AACtB,QAAAJ,IAAO,KAAK,IAAIA,GAAMI,CAAC,GACvBH,IAAO,KAAK,IAAIA,GAAMG,CAAC;AAAA,MACzB,CAAC;AAAA,IACH,CAAC;AAED,UAAMC,KAAYN,IAAOD,KAAQ,KAC3BQ,KAAYL,IAAOD,KAAQ;AAEjC,WAAO;AAAA,MACL,MAAMF,IAAOO;AAAA,MACb,MAAMN,IAAOM;AAAA,MACb,MAAML,IAAOM;AAAA,MACb,MAAML,IAAOK;AAAA,IAAA;AAAA,EAEjB,GAAG,CAACxB,CAAU,CAAC,GAETyB,IAAkBV;AAAA,IACtB,MAAMX,KAAU,CAACS,GAAMC,CAAI;AAAA,IAC3B,CAACV,GAAQS,GAAMC,CAAI;AAAA,EAAA,GAGfY,IAASX,EAAQ,MAAM;AAC3B,UAAMY,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,IAAShB;AAAA,IACb,MAAM,CAAC,GAAG,IAAI,IAAIf,EAAW,QAAQ,CAACgC,MAAMA,EAAE,CAAC,CAAC,CAAC;AAAA,IACjD,CAAChC,CAAU;AAAA,EAAA,GAGPiC,IAAOlB,EAAQ,MAAiC;AACpD,YAAQV,GAAA;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IAAA;AAAA,EAEb,GAAG,CAACA,CAAO,CAAC,GAEN6B,IAAcnB;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;AAGR,SAAAwB,EAAU,MAAM;AACd,QAAI,CAAC1B,EAAQ,QAAS;AAEtB,UAAM2B,IAAWpC,EAAW,IAAI,CAACoB,GAAQiB,MAAU;AACjD,YAAMC,IAAQC,EAAYF,GAAOjB,EAAO,KAAK;AAC7C,aAAO;AAAA,QACL,GAAGA,EAAO;AAAA,QACV,GAAGA,EAAO;AAAA,QACV,MAAM;AAAA,QACN,MAAAa;AAAA,QACA,MAAMb,EAAO;AAAA,QACb,MAAM;AAAA,UACJ,OAAAkB;AAAA,UACA,OAAO;AAAA,QAAA;AAAA,QAET,QACEjC,MAAY,UACR,EAAE,SAAS,MACX;AAAA,UACE,OAAAiC;AAAA,UACA,MAAM;AAAA,UACN,QAAQlB,EAAO,UAAU;AAAA,QAAA;AAAA,QAEjC,SACEf,MAAY,6BACRe,EAAO,WAAW;AAAA,UAChB,MAAM;AAAA,UACN,OAAOA,EAAO,EAAE,IAAI,MAAM,EAAE;AAAA,UAC5B,SAAS;AAAA,UACT,OAAAkB;AAAA,UACA,WAAW;AAAA,UACX,OAAO;AAAA,QAAA,IAET;AAAA,MAAA;AAAA,IAEV,CAAC,GAEKE,IAAS;AAAA,MACb,OAAO;AAAA,QACL,MAAMhC;AAAA,QACN,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,OAAOG,EAAM;AAAA,QAAA;AAAA,MACf;AAAA,MAEF,OAAAV;AAAA,MACA,QAAAC;AAAA,MACA,QAAQ,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK,GAAA;AAAA,MAC3C,eAAeS,EAAM;AAAA,MACrB,cAAcA,EAAM;AAAA,MACpB,MAAM;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,MAEV,UAAU;AAAA,MACV,OAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAML;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,OAAOR;AAAA,QACP,WAAW,CAACA;AAAA,QACZ,UAAU;AAAA,QACV,UAAU4B;AAAA,QACV,UAAUA,EAAO,IAAI,MAAM;AAAA,QAC3B,UAAU;AAAA,QACV,GAAGG;AAAA,MAAA;AAAA,MAEL,OAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM3B;AAAA,UACN,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAOI,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,UAAUsB;AAAA,QACV,UAAU;AAAA,QACV,GAAGQ;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,OAAOvB,EAAM;AAAA,UACb,QAAQ;AAAA,UACR,QAAQ;AAAA,QAAA;AAAA,MACV;AAAA,MAEF,YAAY;AAAA,IAAA,GAGR8B,IAAS;AAAA,MACb,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,IAAA;AAGf,IAAAC,EAAO,QAAQjC,EAAQ,SAAS2B,GAAUI,GAAQC,CAAM;AAGxD,UAAME,IAAclC,EAAQ;AAE5B,WAAO,MAAM;AACX,MAAIkC,KACFD,EAAO,MAAMC,CAAW;AAAA,IAE5B;AAAA,EACF,GAAG,CAAC3C,GAAYC,GAAOC,GAAQC,GAAQC,GAAQE,GAAQC,GAAQC,GAAOyB,GAAMC,GAAaH,GAAQL,GAAQD,GAAiBpB,GAASM,CAAK,CAAC,GAGvI,gBAAAiC,EAAC,OAAA,EAAI,WAAU,mBACb,4BAAC,OAAA,EAAI,KAAKnC,GAAS,OAAO,EAAE,OAAO,QAAQ,QAAQ,OAAA,GAAU,GAC/D;AAEJ;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),R=require("plotly.js-dist"),u=require("react"),y=require("../../../hooks/use-plotly-theme.cjs"),t=require("../../../utils/colors.cjs"),b=[t.COLORS.BLUE,t.COLORS.GREEN,t.COLORS.ORANGE,t.COLORS.RED,t.COLORS.YELLOW,t.COLORS.PURPLE],C=({dataSeries:e,width:m=400,height:h=400,title:f="Pie Chart",textInfo:p="percent",hole:x=0,rotation:O=0})=>{const i=u.useRef(null),a=y.usePlotlyTheme(),g=u.useMemo(()=>{if(e.colors&&e.colors.length>=e.labels.length)return e.colors;const s=[...e.colors||[]],r=e.labels.length-s.length;if(r<=0)return s;for(let n=0;n<r;n++)s.push(b[n%b.length]);return s},[e.colors,e.labels.length]);u.useEffect(()=>{if(!i.current)return;const s=[{type:"pie",labels:e.labels,values:e.values,name:e.name,marker:{colors:g},textinfo:p,hoverinfo:"label+text+value",insidetextfont:{size:0,family:"Inter, sans-serif",color:"transparent"},hole:x,rotation:O}],r={width:m,height:h,font:{family:"Inter, sans-serif",color:a.textColor},showlegend:!1,margin:{l:40,r:40,b:40,t:40},paper_bgcolor:a.paperBg,plot_bgcolor:a.plotBg},n={responsive:!0,displayModeBar:!1,displaylogo:!1};R.newPlot(i.current,s,r,n);const c=i.current;return()=>{c&&R.purge(c)}},[g,e.labels,e.name,e.values,m,h,p,x,O,a]);const j=({labels:s,colors:r})=>{const n=s.map((o,v)=>l.jsx(u.Fragment,{children:l.jsxs("div",{className:"legend-item",children:[l.jsx("span",{className:"color-box",style:{background:r[v]}}),o,v<s.length-1&&l.jsx("span",{className:"divider"})]})},o)),c=6,d=[];for(let o=0;o<n.length;o+=c)d.push(l.jsx("div",{className:"legend-row",children:n.slice(o,o+c)},o));return l.jsx("div",{className:"legend-container",children:d})};return l.jsx("div",{className:"card-container",style:{width:m},children:l.jsxs("div",{className:"chart-container",children:[f&&l.jsx("div",{className:"title-container",children:l.jsx("h2",{className:"title",children:f})}),l.jsx("div",{ref:i,style:{width:"100%",height:"100%",margin:"0"}}),l.jsx(j,{labels:e.labels,colors:g})]})})};exports.PieChart=C;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),b=require("plotly.js-dist"),a=require("react"),C=require("../../../hooks/use-plotly-theme.cjs"),N=require("../../../utils/colors.cjs"),j=N.CHART_COLORS,P=({dataSeries:e,width:u=400,height:g=400,title:h="Pie Chart",textInfo:f="percent",hole:p=0,rotation:x=0})=>{const c=a.useRef(null),i=C.usePlotlyTheme(),m=a.useMemo(()=>{if(e.colors&&e.colors.length>=e.labels.length)return e.colors;const s=[...e.colors||[]],r=e.labels.length-s.length;if(r<=0)return s;for(let n=0;n<r;n++)s.push(j[n%j.length]);return s},[e.colors,e.labels.length]);a.useEffect(()=>{if(!c.current)return;const s=[{type:"pie",labels:e.labels,values:e.values,name:e.name,marker:{colors:m},textinfo:f,hoverinfo:"label+text+value",insidetextfont:{size:0,family:"Inter, sans-serif",color:"transparent"},hole:p,rotation:x}],r={width:u,height:g,font:{family:"Inter, sans-serif",color:i.textColor},showlegend:!1,margin:{l:40,r:40,b:40,t:40},paper_bgcolor:i.paperBg,plot_bgcolor:i.plotBg},n={responsive:!0,displayModeBar:!1,displaylogo:!1};b.newPlot(c.current,s,r,n);const t=c.current;return()=>{t&&b.purge(t)}},[m,e.labels,e.name,e.values,u,g,f,p,x,i]);const y=({labels:s,colors:r})=>{const n=s.map((o,v)=>l.jsx(a.Fragment,{children:l.jsxs("div",{className:"legend-item",children:[l.jsx("span",{className:"color-box",style:{background:r[v]}}),o,v<s.length-1&&l.jsx("span",{className:"divider"})]})},o)),t=6,d=[];for(let o=0;o<n.length;o+=t)d.push(l.jsx("div",{className:"legend-row",children:n.slice(o,o+t)},o));return l.jsx("div",{className:"legend-container",children:d})};return l.jsx("div",{className:"card-container",style:{width:u},children:l.jsxs("div",{className:"chart-container",children:[h&&l.jsx("div",{className:"title-container",children:l.jsx("h2",{className:"title",children:h})}),l.jsx("div",{ref:c,style:{width:"100%",height:"100%",margin:"0"}}),l.jsx(y,{labels:e.labels,colors:m})]})})};exports.PieChart=P;
2
2
  //# sourceMappingURL=PieChart.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"PieChart.cjs","sources":["../../../../src/components/charts/PieChart/PieChart.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { COLORS } from \"@/utils/colors\";\n\ninterface PieDataSeries {\n labels: string[];\n values: number[];\n name: string;\n colors?: string[];\n}\n\ntype PieTextInfo =\n | \"none\"\n | \"label\"\n | \"percent\"\n | \"value\"\n | \"label+percent\"\n | \"label+value\"\n | \"value+percent\"\n | \"label+value+percent\";\n\ntype PieChartProps = {\n dataSeries: PieDataSeries;\n width?: number;\n height?: number;\n title?: string;\n textInfo?: PieTextInfo;\n hole?: number;\n rotation?: number;\n};\n\nconst DEFAULT_COLORS = [\n COLORS.BLUE,\n COLORS.GREEN,\n COLORS.ORANGE,\n COLORS.RED,\n COLORS.YELLOW,\n COLORS.PURPLE,\n];\n\nconst PieChart: React.FC<PieChartProps> = ({\n dataSeries,\n width = 400,\n height = 400,\n title = \"Pie Chart\",\n textInfo = \"percent\",\n hole = 0,\n rotation = 0,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n\n const colors = useMemo(() => {\n if (\n dataSeries.colors &&\n dataSeries.colors.length >= dataSeries.labels.length\n ) {\n return dataSeries.colors;\n }\n\n const result = [...(dataSeries.colors || [])];\n const missingColors = dataSeries.labels.length - result.length;\n\n if (missingColors <= 0) return result;\n\n for (let i = 0; i < missingColors; i++) {\n result.push(DEFAULT_COLORS[i % DEFAULT_COLORS.length]);\n }\n\n return result;\n }, [dataSeries.colors, dataSeries.labels.length]);\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const plotData = [\n {\n type: \"pie\" as const,\n labels: dataSeries.labels,\n values: dataSeries.values,\n name: dataSeries.name,\n marker: {\n colors: colors,\n },\n textinfo: textInfo,\n hoverinfo: \"label+text+value\" as const,\n insidetextfont: {\n size: 0,\n family: \"Inter, sans-serif\",\n color: \"transparent\",\n },\n hole: hole,\n rotation: rotation,\n },\n ];\n\n const layout = {\n width,\n height,\n font: {\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n showlegend: false,\n margin: { l: 40, r: 40, b: 40, t: 40 },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\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\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [colors, dataSeries.labels, dataSeries.name, dataSeries.values, width, height, textInfo, hole, rotation, theme]);\n\n const PieChartLegend: React.FC<{ labels: string[]; colors: string[] }> = ({\n labels,\n colors,\n }) => {\n const items = labels.map((label, i) => (\n <React.Fragment key={label}>\n <div className=\"legend-item\">\n <span className=\"color-box\" style={{ background: colors[i] }} />\n {label}\n {i < labels.length - 1 && <span className=\"divider\" />}\n </div>\n </React.Fragment>\n ));\n\n const rowSize = 6;\n const rows = [];\n for (let i = 0; i < items.length; i += rowSize) {\n rows.push(\n <div className=\"legend-row\" key={i}>\n {items.slice(i, i + rowSize)}\n </div>\n );\n }\n return <div className=\"legend-container\">{rows}</div>;\n };\n\n return (\n <div className=\"card-container\" style={{ width: width }}>\n <div className=\"chart-container\">\n {title && (\n <div className=\"title-container\">\n <h2 className=\"title\">{title}</h2>\n </div>\n )}\n <div\n ref={plotRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n margin: \"0\",\n }}\n />\n <PieChartLegend labels={dataSeries.labels} colors={colors} />\n </div>\n </div>\n );\n};\n\nexport { PieChart };\nexport type { PieDataSeries, PieTextInfo, PieChartProps };\n"],"names":["DEFAULT_COLORS","COLORS","PieChart","dataSeries","width","height","title","textInfo","hole","rotation","plotRef","useRef","theme","usePlotlyTheme","colors","useMemo","result","missingColors","i","useEffect","plotData","layout","config","Plotly","plotElement","PieChartLegend","labels","items","label","jsx","React","jsxs","rowSize","rows"],"mappings":"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"}
1
+ {"version":3,"file":"PieChart.cjs","sources":["../../../../src/components/charts/PieChart/PieChart.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { CHART_COLORS } from \"@/utils/colors\";\n\ninterface PieDataSeries {\n labels: string[];\n values: number[];\n name: string;\n colors?: string[];\n}\n\ntype PieTextInfo =\n | \"none\"\n | \"label\"\n | \"percent\"\n | \"value\"\n | \"label+percent\"\n | \"label+value\"\n | \"value+percent\"\n | \"label+value+percent\";\n\ntype PieChartProps = {\n dataSeries: PieDataSeries;\n width?: number;\n height?: number;\n title?: string;\n textInfo?: PieTextInfo;\n hole?: number;\n rotation?: number;\n};\n\nconst DEFAULT_COLORS = CHART_COLORS;\n\nconst PieChart: React.FC<PieChartProps> = ({\n dataSeries,\n width = 400,\n height = 400,\n title = \"Pie Chart\",\n textInfo = \"percent\",\n hole = 0,\n rotation = 0,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n\n const colors = useMemo(() => {\n if (\n dataSeries.colors &&\n dataSeries.colors.length >= dataSeries.labels.length\n ) {\n return dataSeries.colors;\n }\n\n const result = [...(dataSeries.colors || [])];\n const missingColors = dataSeries.labels.length - result.length;\n\n if (missingColors <= 0) return result;\n\n for (let i = 0; i < missingColors; i++) {\n result.push(DEFAULT_COLORS[i % DEFAULT_COLORS.length]);\n }\n\n return result;\n }, [dataSeries.colors, dataSeries.labels.length]);\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const plotData = [\n {\n type: \"pie\" as const,\n labels: dataSeries.labels,\n values: dataSeries.values,\n name: dataSeries.name,\n marker: {\n colors: colors,\n },\n textinfo: textInfo,\n hoverinfo: \"label+text+value\" as const,\n insidetextfont: {\n size: 0,\n family: \"Inter, sans-serif\",\n color: \"transparent\",\n },\n hole: hole,\n rotation: rotation,\n },\n ];\n\n const layout = {\n width,\n height,\n font: {\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n showlegend: false,\n margin: { l: 40, r: 40, b: 40, t: 40 },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\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\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [colors, dataSeries.labels, dataSeries.name, dataSeries.values, width, height, textInfo, hole, rotation, theme]);\n\n const PieChartLegend: React.FC<{ labels: string[]; colors: string[] }> = ({\n labels,\n colors,\n }) => {\n const items = labels.map((label, i) => (\n <React.Fragment key={label}>\n <div className=\"legend-item\">\n <span className=\"color-box\" style={{ background: colors[i] }} />\n {label}\n {i < labels.length - 1 && <span className=\"divider\" />}\n </div>\n </React.Fragment>\n ));\n\n const rowSize = 6;\n const rows = [];\n for (let i = 0; i < items.length; i += rowSize) {\n rows.push(\n <div className=\"legend-row\" key={i}>\n {items.slice(i, i + rowSize)}\n </div>\n );\n }\n return <div className=\"legend-container\">{rows}</div>;\n };\n\n return (\n <div className=\"card-container\" style={{ width: width }}>\n <div className=\"chart-container\">\n {title && (\n <div className=\"title-container\">\n <h2 className=\"title\">{title}</h2>\n </div>\n )}\n <div\n ref={plotRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n margin: \"0\",\n }}\n />\n <PieChartLegend labels={dataSeries.labels} colors={colors} />\n </div>\n </div>\n );\n};\n\nexport { PieChart };\nexport type { PieDataSeries, PieTextInfo, PieChartProps };\n"],"names":["DEFAULT_COLORS","CHART_COLORS","PieChart","dataSeries","width","height","title","textInfo","hole","rotation","plotRef","useRef","theme","usePlotlyTheme","colors","useMemo","result","missingColors","i","useEffect","plotData","layout","config","Plotly","plotElement","PieChartLegend","labels","items","label","jsx","React","jsxs","rowSize","rows"],"mappings":"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"}