@tetrascience-npm/tetrascience-react-ui 0.6.0-beta.95.1 → 0.6.0-beta.97.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O=require("react/jsx-runtime"),T=require("plotly.js-dist"),c=require("react"),U=require("../ChartTooltip/ChartTooltip.cjs"),V=require("../../../hooks/use-plotly-theme.cjs"),X=require("../../../utils/colors.cjs"),B=require("../ChartTooltip/lines.cjs"),G=({dataSeries:u,width:w=1e3,height:b=600,xRange:h,yRange:d,variant:y="normal",xTitle:g="Columns",yTitle:M="Rows",title:C="Area Graph"})=>{const p=c.useRef(null),o=V.usePlotlyTheme(),{bindTooltip:z,tooltipElement:Y}=U.useChartTooltip({getLines:t=>B.chartTooltipLines(t.map(e=>typeof e.customdata=="number"?{...e,y:e.customdata}:e),{xLabel:g,yLabel:M})}),{xMin:A,xMax:E,yMin:v,yMax:I}=c.useMemo(()=>{let t=Number.MAX_VALUE,e=Number.MIN_VALUE,n=Number.MAX_VALUE,r=Number.MIN_VALUE;u.forEach(s=>{s.x.forEach(a=>{t=Math.min(t,a),e=Math.max(e,a)}),s.y.forEach(a=>{n=Math.min(n,a),r=Math.max(r,a)})});const l=(e-t)*.1,i=(r-n)*.1;return{xMin:t-l,xMax:e+l,yMin:y==="stacked"?0:n-i,yMax:r+i}},[u,y]),f=c.useMemo(()=>h||[A,E],[h,A,E]),m=c.useMemo(()=>d||[v,I],[d,v,I]),L=c.useMemo(()=>{const t=f[1]-f[0];let e=Math.pow(10,Math.floor(Math.log10(t)));t/e>10&&(e=e*2),t/e<4&&(e=e/2);const n=[];let r=Math.ceil(f[0]/e)*e;for(;r<=f[1];)n.push(r),r+=e;return n},[f]),q=c.useMemo(()=>{const t=m[1]-m[0];let e=Math.pow(10,Math.floor(Math.log10(t)));t/e>10&&(e=e*2),t/e<4&&(e=e/2);const n=[];let r=Math.ceil(m[0]/e)*e;for(;r<=m[1];)n.push(r),r+=e;return n},[m]),x=c.useMemo(()=>({tickcolor:o.tickColor,ticklen:12,tickwidth:1,ticks:"outside",tickfont:{size:16,color:o.textColor,family:"Inter, sans-serif",weight:400},linecolor:o.lineColor,linewidth:1,position:0,zeroline:!1}),[o]),N=c.useMemo(()=>({text:C,x:.5,y:.95,xanchor:"center",yanchor:"top",font:{size:32,weight:600,family:"Inter, sans-serif",color:o.textColor,lineheight:1.2,standoff:30}}),[C,o]);return c.useEffect(()=>{if(!p.current)return;let t;if(y==="stacked"){const l=new Array(u[0]?.x.length||0).fill(0);t=u.map((i,s)=>{const a=i.y.map((j,P)=>{const _=l[P]+j;return l[P]=_,_}),k=X.seriesColor(s,i.color);return{x:i.x,y:a,customdata:i.y,type:"scatter",mode:"lines+markers",name:i.name,hoverinfo:"none",fill:s===0?"tozeroy":"tonexty",fillcolor:k,line:{color:k,width:2},marker:{size:6,color:k,line:{color:o.markerOutline,width:1.5}}}})}else t=u.map((l,i)=>{const s=X.seriesColor(i,l.color);return{x:l.x,y:l.y,type:"scatter",mode:"lines+markers",name:l.name,hoverinfo:"none",fill:l.fill||"tozeroy",fillcolor:s,line:{color:s,width:2},marker:{size:6,color:s,line:{color:o.markerOutline,width:1.5}}}});const e={width:w,height:b,title:N,margin:{l:80,r:40,b:80,t:80,pad:0},paper_bgcolor:o.paperBg,plot_bgcolor:o.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:g,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:o.gridColor,range:h,autorange:!h,tickmode:"array",tickvals:L,showgrid:!0,...x},yaxis:{title:{text:M,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:o.gridColor,range:d,autorange:!d,tickmode:"array",tickvals:q,showgrid:!0,...x},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:13,color:o.legendColor,family:"Inter, sans-serif",weight:500,lineheight:18}},showlegend:!0},n={responsive:!0,displayModeBar:!1,displaylogo:!1};T.newPlot(p.current,t,e,n),z(p.current);const r=p.current;return()=>{r&&T.purge(r)}},[u,w,b,h,d,f,m,y,g,M,N,x,L,q,o,z]),O.jsxs("div",{className:"area-graph-container relative",children:[O.jsx("div",{ref:p,style:{width:"100%",height:"100%"}}),Y]})};exports.AreaGraph=G;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const V=require("react/jsx-runtime"),Y=require("plotly.js-dist"),i=require("react"),B=require("../ChartTooltip/ChartTooltip.cjs"),D=require("../../../hooks/use-plotly-theme.cjs"),j=require("../../../utils/colors.cjs"),R=require("../ChartTooltip/lines.cjs"),F=80,H=40,J=({dataSeries:a,width:A=1e3,height:_=600,xRange:h,yRange:d,variant:g="normal",xTitle:x="Columns",yTitle:k="Rows",title:p,xTickText:M})=>{const y=i.useRef(null),o=D.usePlotlyTheme(),{bindTooltip:v,tooltipElement:G}=B.useChartTooltip({getLines:t=>R.chartTooltipLines(t.map(e=>typeof e.customdata=="number"?{...e,y:e.customdata}:e),{xLabel:x,yLabel:k})}),{xMin:z,xMax:L,yMin:N,yMax:P}=i.useMemo(()=>{let t=Number.MAX_VALUE,e=Number.MIN_VALUE,n=Number.MAX_VALUE,r=Number.MIN_VALUE;a.forEach(c=>{c.x.forEach(u=>{t=Math.min(t,u),e=Math.max(e,u)}),c.y.forEach(u=>{n=Math.min(n,u),r=Math.max(r,u)})});const l=(e-t)*.1,s=(r-n)*.1;return{xMin:t-l,xMax:e+l,yMin:g==="stacked"?0:n-s,yMax:r+s}},[a,g]),f=i.useMemo(()=>h||[z,L],[h,z,L]),m=i.useMemo(()=>d||[N,P],[d,N,P]),O=i.useMemo(()=>{const t=f[1]-f[0];let e=Math.pow(10,Math.floor(Math.log10(t)));t/e>10&&(e=e*2),t/e<4&&(e=e/2);const n=[];let r=Math.ceil(f[0]/e)*e;for(;r<=f[1];)n.push(r),r+=e;return n},[f]),q=i.useMemo(()=>{const t=m[1]-m[0];let e=Math.pow(10,Math.floor(Math.log10(t)));t/e>10&&(e=e*2),t/e<4&&(e=e/2);const n=[];let r=Math.ceil(m[0]/e)*e;for(;r<=m[1];)n.push(r),r+=e;return n},[m]),w=i.useMemo(()=>[...new Set(a.flatMap(t=>t.x))].sort((t,e)=>t-e),[a]),b=!!M&&M.length===w.length,C=i.useMemo(()=>({tickcolor:o.tickColor,ticklen:12,tickwidth:1,ticks:"outside",tickfont:{size:16,color:o.textColor,family:"Inter, sans-serif",weight:400},linecolor:o.lineColor,linewidth:1,position:0,zeroline:!1}),[o]),E=i.useMemo(()=>p?{text:p,x:.5,y:.95,xanchor:"center",yanchor:"top",font:{size:32,weight:600,family:"Inter, sans-serif",color:o.textColor,lineheight:1.2,standoff:30}}:void 0,[p,o]);return i.useEffect(()=>{if(!y.current)return;let t;if(g==="stacked"){const l=new Array(a[0]?.x.length||0).fill(0);t=a.map((s,c)=>{const u=s.y.map((U,X)=>{const T=l[X]+U;return l[X]=T,T}),I=j.seriesColor(c,s.color);return{x:s.x,y:u,customdata:s.y,type:"scatter",mode:"lines+markers",name:s.name,hoverinfo:"none",fill:c===0?"tozeroy":"tonexty",fillcolor:I,line:{color:I,width:2},marker:{size:6,color:I,line:{color:o.markerOutline,width:1.5}}}})}else t=a.map((l,s)=>{const c=j.seriesColor(s,l.color);return{x:l.x,y:l.y,type:"scatter",mode:"lines+markers",name:l.name,hoverinfo:"none",fill:l.fill||"tozeroy",fillcolor:c,line:{color:c,width:2},marker:{size:6,color:c,line:{color:o.markerOutline,width:1.5}}}});const e={width:A,height:_,...E?{title:E}:{},margin:{l:80,r:40,b:80,t:p?F:H,pad:0},paper_bgcolor:o.paperBg,plot_bgcolor:o.plotBg,font:{family:"Inter, sans-serif"},dragmode:!1,xaxis:{title:{text:x,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:o.gridColor,range:h,autorange:!h,tickmode:"array",tickvals:b?w:O,...b?{ticktext:M}:{},showgrid:!0,...C},yaxis:{title:{text:k,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:15},gridcolor:o.gridColor,range:d,autorange:!d,tickmode:"array",tickvals:q,showgrid:!0,...C},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:13,color:o.legendColor,family:"Inter, sans-serif",weight:500,lineheight:18}},showlegend:!0},n={responsive:!0,displayModeBar:!1,displaylogo:!1};Y.newPlot(y.current,t,e,n),v(y.current);const r=y.current;return()=>{r&&Y.purge(r)}},[a,A,_,h,d,f,m,g,x,k,p,E,C,O,q,w,b,M,o,v]),V.jsxs("div",{className:"area-graph-container relative",children:[V.jsx("div",{ref:y,style:{width:"100%",height:"100%"}}),G]})};exports.AreaGraph=J;
2
2
  //# sourceMappingURL=AreaGraph.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AreaGraph.cjs","sources":["../../../../src/components/charts/AreaGraph/AreaGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { chartTooltipLines, useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface AreaDataSeries {\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 fill?: \"tozeroy\" | \"tonexty\" | \"toself\";\n}\n\ntype AreaGraphVariant = \"normal\" | \"stacked\";\n\ninterface AreaGraphProps {\n dataSeries: AreaDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: AreaGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n}\n\nconst AreaGraph: React.FC<AreaGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"normal\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Area Graph\",\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({\n // Stacked traces carry the original series values as customdata;\n // display those instead of the cumulative stack heights\n getLines: (points) =>\n chartTooltipLines(\n points.map((point) =>\n typeof point.customdata === \"number\"\n ? { ...point, y: point.customdata }\n : point,\n ),\n { xLabel: xTitle, yLabel: yTitle },\n ),\n });\n\n const { xMin, xMax, 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 === \"stacked\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveXRange = useMemo(\n () => xRange || [xMin, xMax],\n [xRange, xMin, xMax],\n );\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(() => {\n const range = effectiveXRange[1] - effectiveXRange[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(effectiveXRange[0] / step) * step;\n while (current <= effectiveXRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveXRange]);\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 let data;\n\n if (variant === \"stacked\") {\n // For stacked mode, we need to calculate cumulative values\n const cumulativeY = new Array(dataSeries[0]?.x.length || 0).fill(0);\n\n data = dataSeries.map((series, index) => {\n // Calculate cumulative values for this series\n const stackedY = series.y.map((value, i) => {\n const result = cumulativeY[i] + value;\n cumulativeY[i] = result;\n return result;\n });\n\n const color = seriesColor(index, series.color);\n return {\n x: series.x,\n y: stackedY,\n // Tooltips report the series' own values, not the stacked sums\n customdata: series.y,\n type: \"scatter\" as const,\n // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: index === 0 ? (\"tozeroy\" as const) : (\"tonexty\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\n });\n } else {\n // Normal mode - each area fills independently from zero\n data = 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 // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: series.fill || (\"tozeroy\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\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 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: 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, effectiveXRange, effectiveYRange, variant, xTitle, yTitle, titleOptions, tickOptions, xTicks, yTicks, theme, bindTooltip]);\n\n return (\n <div className=\"area-graph-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { AreaGraph };\nexport type { AreaDataSeries, AreaGraphVariant, AreaGraphProps };\n"],"names":["AreaGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","points","chartTooltipLines","point","xMin","xMax","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveXRange","effectiveYRange","xTicks","range","step","ticks","current","yTicks","tickOptions","titleOptions","useEffect","data","cumulativeY","index","stackedY","value","i","result","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"AreaGraph.cjs","sources":["../../../../src/components/charts/AreaGraph/AreaGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { chartTooltipLines, useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface AreaDataSeries {\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 fill?: \"tozeroy\" | \"tonexty\" | \"toself\";\n}\n\ntype AreaGraphVariant = \"normal\" | \"stacked\";\n\n/** Top margin reserving room for the 32px title; reduced when no title is set */\nconst TITLE_MARGIN_TOP = 80;\nconst NO_TITLE_MARGIN_TOP = 40;\n\ninterface AreaGraphProps {\n dataSeries: AreaDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: AreaGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive area positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n}\n\nconst AreaGraph: React.FC<AreaGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"normal\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({\n // Stacked traces carry the original series values as customdata;\n // display those instead of the cumulative stack heights\n getLines: (points) =>\n chartTooltipLines(\n points.map((point) =>\n typeof point.customdata === \"number\"\n ? { ...point, y: point.customdata }\n : point,\n ),\n { xLabel: xTitle, yLabel: yTitle },\n ),\n });\n\n const { xMin, xMax, 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 === \"stacked\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveXRange = useMemo(\n () => xRange || [xMin, xMax],\n [xRange, xMin, xMax],\n );\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(() => {\n const range = effectiveXRange[1] - effectiveXRange[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(effectiveXRange[0] / step) * step;\n while (current <= effectiveXRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveXRange]);\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 // When categorical labels are supplied, ticks must sit on the actual data\n // x-positions rather than the computed nice-step values above. Sorted\n // ascending so labels map deterministically to x regardless of series order.\n const xDataValues = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xDataValues.length;\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 title\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 : undefined,\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n let data;\n\n if (variant === \"stacked\") {\n // For stacked mode, we need to calculate cumulative values\n const cumulativeY = new Array(dataSeries[0]?.x.length || 0).fill(0);\n\n data = dataSeries.map((series, index) => {\n // Calculate cumulative values for this series\n const stackedY = series.y.map((value, i) => {\n const result = cumulativeY[i] + value;\n cumulativeY[i] = result;\n return result;\n });\n\n const color = seriesColor(index, series.color);\n return {\n x: series.x,\n y: stackedY,\n // Tooltips report the series' own values, not the stacked sums\n customdata: series.y,\n type: \"scatter\" as const,\n // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: index === 0 ? (\"tozeroy\" as const) : (\"tonexty\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\n });\n } else {\n // Normal mode - each area fills independently from zero\n data = 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 // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: series.fill || (\"tozeroy\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\n });\n }\n\n const layout = {\n width,\n height: height,\n ...(titleOptions ? { title: titleOptions } : {}),\n margin: {\n l: 80,\n r: 40,\n b: 80,\n t: title ? TITLE_MARGIN_TOP : NO_TITLE_MARGIN_TOP,\n pad: 0,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n 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 tickmode: \"array\" as const,\n tickvals: useCategoricalX ? xDataValues : xTicks,\n ...(useCategoricalX ? { ticktext: xTickText } : {}),\n showgrid: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 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, effectiveXRange, effectiveYRange, variant, xTitle, yTitle, title, titleOptions, tickOptions, xTicks, yTicks, xDataValues, useCategoricalX, xTickText, theme, bindTooltip]);\n\n return (\n <div className=\"area-graph-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { AreaGraph };\nexport type { AreaDataSeries, AreaGraphVariant, AreaGraphProps };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","AreaGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","points","chartTooltipLines","point","xMin","xMax","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveXRange","effectiveYRange","xTicks","range","step","ticks","current","yTicks","xDataValues","s","a","b","useCategoricalX","tickOptions","titleOptions","useEffect","data","cumulativeY","index","stackedY","value","i","result","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
@@ -1,37 +1,38 @@
1
- import { jsxs as B, jsx as j } from "react/jsx-runtime";
2
- import Y from "plotly.js-dist";
3
- import { useRef as G, useMemo as s, useEffect as T } from "react";
4
- import { useChartTooltip as q } from "../ChartTooltip/ChartTooltip.js";
5
- import { usePlotlyTheme as D } from "../../../hooks/use-plotly-theme.js";
6
- import { seriesColor as O } from "../../../utils/colors.js";
7
- import { chartTooltipLines as F } from "../ChartTooltip/lines.js";
8
- const R = ({
9
- dataSeries: f,
10
- width: w = 1e3,
11
- height: b = 600,
1
+ import { jsxs as T, jsx as D } from "react/jsx-runtime";
2
+ import U from "plotly.js-dist";
3
+ import { useRef as q, useMemo as s, useEffect as F } from "react";
4
+ import { useChartTooltip as H } from "../ChartTooltip/ChartTooltip.js";
5
+ import { usePlotlyTheme as J } from "../../../hooks/use-plotly-theme.js";
6
+ import { seriesColor as B } from "../../../utils/colors.js";
7
+ import { chartTooltipLines as K } from "../ChartTooltip/lines.js";
8
+ const Q = 80, W = 40, rt = ({
9
+ dataSeries: c,
10
+ width: _ = 1e3,
11
+ height: z = 600,
12
12
  xRange: u,
13
13
  yRange: p,
14
14
  variant: y = "normal",
15
- xTitle: g = "Columns",
16
- yTitle: x = "Rows",
17
- title: z = "Area Graph"
15
+ xTitle: x = "Columns",
16
+ yTitle: k = "Rows",
17
+ title: d,
18
+ xTickText: M
18
19
  }) => {
19
- const d = G(null), e = D(), { bindTooltip: C, tooltipElement: U } = q({
20
+ const g = q(null), e = J(), { bindTooltip: A, tooltipElement: G } = H({
20
21
  // Stacked traces carry the original series values as customdata;
21
22
  // display those instead of the cumulative stack heights
22
- getLines: (o) => F(
23
+ getLines: (o) => K(
23
24
  o.map(
24
25
  (t) => typeof t.customdata == "number" ? { ...t, y: t.customdata } : t
25
26
  ),
26
- { xLabel: g, yLabel: x }
27
+ { xLabel: x, yLabel: k }
27
28
  )
28
- }), { xMin: E, xMax: A, yMin: v, yMax: I } = s(() => {
29
+ }), { xMin: L, xMax: N, yMin: v, yMax: O } = s(() => {
29
30
  let o = Number.MAX_VALUE, t = Number.MIN_VALUE, n = Number.MAX_VALUE, r = Number.MIN_VALUE;
30
- f.forEach((a) => {
31
- a.x.forEach((c) => {
32
- o = Math.min(o, c), t = Math.max(t, c);
33
- }), a.y.forEach((c) => {
34
- n = Math.min(n, c), r = Math.max(r, c);
31
+ c.forEach((a) => {
32
+ a.x.forEach((f) => {
33
+ o = Math.min(o, f), t = Math.max(t, f);
34
+ }), a.y.forEach((f) => {
35
+ n = Math.min(n, f), r = Math.max(r, f);
35
36
  });
36
37
  });
37
38
  const l = (t - o) * 0.1, i = (r - n) * 0.1;
@@ -41,13 +42,13 @@ const R = ({
41
42
  yMin: y === "stacked" ? 0 : n - i,
42
43
  yMax: r + i
43
44
  };
44
- }, [f, y]), m = s(
45
- () => u || [E, A],
46
- [u, E, A]
45
+ }, [c, y]), m = s(
46
+ () => u || [L, N],
47
+ [u, L, N]
47
48
  ), h = s(
48
- () => p || [v, I],
49
- [p, v, I]
50
- ), L = s(() => {
49
+ () => p || [v, O],
50
+ [p, v, O]
51
+ ), P = s(() => {
51
52
  const o = m[1] - m[0];
52
53
  let t = Math.pow(10, Math.floor(Math.log10(o)));
53
54
  o / t > 10 && (t = t * 2), o / t < 4 && (t = t / 2);
@@ -56,7 +57,7 @@ const R = ({
56
57
  for (; r <= m[1]; )
57
58
  n.push(r), r += t;
58
59
  return n;
59
- }, [m]), N = s(() => {
60
+ }, [m]), X = s(() => {
60
61
  const o = h[1] - h[0];
61
62
  let t = Math.pow(10, Math.floor(Math.log10(o)));
62
63
  o / t > 10 && (t = t * 2), o / t < 4 && (t = t / 2);
@@ -65,7 +66,10 @@ const R = ({
65
66
  for (; r <= h[1]; )
66
67
  n.push(r), r += t;
67
68
  return n;
68
- }, [h]), M = s(
69
+ }, [h]), w = s(
70
+ () => [...new Set(c.flatMap((o) => o.x))].sort((o, t) => o - t),
71
+ [c]
72
+ ), E = !!M && M.length === w.length, I = s(
69
73
  () => ({
70
74
  tickcolor: e.tickColor,
71
75
  ticklen: 12,
@@ -83,9 +87,9 @@ const R = ({
83
87
  zeroline: !1
84
88
  }),
85
89
  [e]
86
- ), _ = s(
87
- () => ({
88
- text: z,
90
+ ), b = s(
91
+ () => d ? {
92
+ text: d,
89
93
  x: 0.5,
90
94
  y: 0.95,
91
95
  xanchor: "center",
@@ -98,22 +102,22 @@ const R = ({
98
102
  lineheight: 1.2,
99
103
  standoff: 30
100
104
  }
101
- }),
102
- [z, e]
105
+ } : void 0,
106
+ [d, e]
103
107
  );
104
- return T(() => {
105
- if (!d.current) return;
108
+ return F(() => {
109
+ if (!g.current) return;
106
110
  let o;
107
111
  if (y === "stacked") {
108
- const l = new Array(f[0]?.x.length || 0).fill(0);
109
- o = f.map((i, a) => {
110
- const c = i.y.map((V, P) => {
111
- const X = l[P] + V;
112
- return l[P] = X, X;
113
- }), k = O(a, i.color);
112
+ const l = new Array(c[0]?.x.length || 0).fill(0);
113
+ o = c.map((i, a) => {
114
+ const f = i.y.map((j, V) => {
115
+ const Y = l[V] + j;
116
+ return l[V] = Y, Y;
117
+ }), C = B(a, i.color);
114
118
  return {
115
119
  x: i.x,
116
- y: c,
120
+ y: f,
117
121
  // Tooltips report the series' own values, not the stacked sums
118
122
  customdata: i.y,
119
123
  type: "scatter",
@@ -122,21 +126,21 @@ const R = ({
122
126
  name: i.name,
123
127
  hoverinfo: "none",
124
128
  fill: a === 0 ? "tozeroy" : "tonexty",
125
- fillcolor: k,
129
+ fillcolor: C,
126
130
  line: {
127
- color: k,
131
+ color: C,
128
132
  width: 2
129
133
  },
130
134
  marker: {
131
135
  size: 6,
132
- color: k,
136
+ color: C,
133
137
  line: { color: e.markerOutline, width: 1.5 }
134
138
  }
135
139
  };
136
140
  });
137
141
  } else
138
- o = f.map((l, i) => {
139
- const a = O(i, l.color);
142
+ o = c.map((l, i) => {
143
+ const a = B(i, l.color);
140
144
  return {
141
145
  x: l.x,
142
146
  y: l.y,
@@ -159,10 +163,16 @@ const R = ({
159
163
  };
160
164
  });
161
165
  const t = {
162
- width: w,
163
- height: b,
164
- title: _,
165
- margin: { l: 80, r: 40, b: 80, t: 80, pad: 0 },
166
+ width: _,
167
+ height: z,
168
+ ...b ? { title: b } : {},
169
+ margin: {
170
+ l: 80,
171
+ r: 40,
172
+ b: 80,
173
+ t: d ? Q : W,
174
+ pad: 0
175
+ },
166
176
  paper_bgcolor: e.paperBg,
167
177
  plot_bgcolor: e.plotBg,
168
178
  font: {
@@ -171,7 +181,7 @@ const R = ({
171
181
  dragmode: !1,
172
182
  xaxis: {
173
183
  title: {
174
- text: g,
184
+ text: x,
175
185
  font: {
176
186
  size: 16,
177
187
  color: e.textSecondary,
@@ -184,13 +194,14 @@ const R = ({
184
194
  range: u,
185
195
  autorange: !u,
186
196
  tickmode: "array",
187
- tickvals: L,
197
+ tickvals: E ? w : P,
198
+ ...E ? { ticktext: M } : {},
188
199
  showgrid: !0,
189
- ...M
200
+ ...I
190
201
  },
191
202
  yaxis: {
192
203
  title: {
193
- text: x,
204
+ text: k,
194
205
  font: {
195
206
  size: 16,
196
207
  color: e.textSecondary,
@@ -203,9 +214,9 @@ const R = ({
203
214
  range: p,
204
215
  autorange: !p,
205
216
  tickmode: "array",
206
- tickvals: N,
217
+ tickvals: X,
207
218
  showgrid: !0,
208
- ...M
219
+ ...I
209
220
  },
210
221
  legend: {
211
222
  x: 0.5,
@@ -227,17 +238,17 @@ const R = ({
227
238
  displayModeBar: !1,
228
239
  displaylogo: !1
229
240
  };
230
- Y.newPlot(d.current, o, t, n), C(d.current);
231
- const r = d.current;
241
+ U.newPlot(g.current, o, t, n), A(g.current);
242
+ const r = g.current;
232
243
  return () => {
233
- r && Y.purge(r);
244
+ r && U.purge(r);
234
245
  };
235
- }, [f, w, b, u, p, m, h, y, g, x, _, M, L, N, e, C]), /* @__PURE__ */ B("div", { className: "area-graph-container relative", children: [
236
- /* @__PURE__ */ j("div", { ref: d, style: { width: "100%", height: "100%" } }),
237
- U
246
+ }, [c, _, z, u, p, m, h, y, x, k, d, b, I, P, X, w, E, M, e, A]), /* @__PURE__ */ T("div", { className: "area-graph-container relative", children: [
247
+ /* @__PURE__ */ D("div", { ref: g, style: { width: "100%", height: "100%" } }),
248
+ G
238
249
  ] });
239
250
  };
240
251
  export {
241
- R as AreaGraph
252
+ rt as AreaGraph
242
253
  };
243
254
  //# sourceMappingURL=AreaGraph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AreaGraph.js","sources":["../../../../src/components/charts/AreaGraph/AreaGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { chartTooltipLines, useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface AreaDataSeries {\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 fill?: \"tozeroy\" | \"tonexty\" | \"toself\";\n}\n\ntype AreaGraphVariant = \"normal\" | \"stacked\";\n\ninterface AreaGraphProps {\n dataSeries: AreaDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: AreaGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n}\n\nconst AreaGraph: React.FC<AreaGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"normal\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title = \"Area Graph\",\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({\n // Stacked traces carry the original series values as customdata;\n // display those instead of the cumulative stack heights\n getLines: (points) =>\n chartTooltipLines(\n points.map((point) =>\n typeof point.customdata === \"number\"\n ? { ...point, y: point.customdata }\n : point,\n ),\n { xLabel: xTitle, yLabel: yTitle },\n ),\n });\n\n const { xMin, xMax, 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 === \"stacked\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveXRange = useMemo(\n () => xRange || [xMin, xMax],\n [xRange, xMin, xMax],\n );\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(() => {\n const range = effectiveXRange[1] - effectiveXRange[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(effectiveXRange[0] / step) * step;\n while (current <= effectiveXRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveXRange]);\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 let data;\n\n if (variant === \"stacked\") {\n // For stacked mode, we need to calculate cumulative values\n const cumulativeY = new Array(dataSeries[0]?.x.length || 0).fill(0);\n\n data = dataSeries.map((series, index) => {\n // Calculate cumulative values for this series\n const stackedY = series.y.map((value, i) => {\n const result = cumulativeY[i] + value;\n cumulativeY[i] = result;\n return result;\n });\n\n const color = seriesColor(index, series.color);\n return {\n x: series.x,\n y: stackedY,\n // Tooltips report the series' own values, not the stacked sums\n customdata: series.y,\n type: \"scatter\" as const,\n // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: index === 0 ? (\"tozeroy\" as const) : (\"tonexty\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\n });\n } else {\n // Normal mode - each area fills independently from zero\n data = 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 // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: series.fill || (\"tozeroy\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\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 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: 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, effectiveXRange, effectiveYRange, variant, xTitle, yTitle, titleOptions, tickOptions, xTicks, yTicks, theme, bindTooltip]);\n\n return (\n <div className=\"area-graph-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { AreaGraph };\nexport type { AreaDataSeries, AreaGraphVariant, AreaGraphProps };\n"],"names":["AreaGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","points","chartTooltipLines","point","xMin","xMax","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveXRange","effectiveYRange","xTicks","range","step","ticks","current","yTicks","tickOptions","titleOptions","useEffect","data","cumulativeY","index","stackedY","value","i","result","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"AreaGraph.js","sources":["../../../../src/components/charts/AreaGraph/AreaGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { chartTooltipLines, useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface AreaDataSeries {\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 fill?: \"tozeroy\" | \"tonexty\" | \"toself\";\n}\n\ntype AreaGraphVariant = \"normal\" | \"stacked\";\n\n/** Top margin reserving room for the 32px title; reduced when no title is set */\nconst TITLE_MARGIN_TOP = 80;\nconst NO_TITLE_MARGIN_TOP = 40;\n\ninterface AreaGraphProps {\n dataSeries: AreaDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: AreaGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive area positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n}\n\nconst AreaGraph: React.FC<AreaGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"normal\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({\n // Stacked traces carry the original series values as customdata;\n // display those instead of the cumulative stack heights\n getLines: (points) =>\n chartTooltipLines(\n points.map((point) =>\n typeof point.customdata === \"number\"\n ? { ...point, y: point.customdata }\n : point,\n ),\n { xLabel: xTitle, yLabel: yTitle },\n ),\n });\n\n const { xMin, xMax, 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 === \"stacked\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveXRange = useMemo(\n () => xRange || [xMin, xMax],\n [xRange, xMin, xMax],\n );\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(() => {\n const range = effectiveXRange[1] - effectiveXRange[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(effectiveXRange[0] / step) * step;\n while (current <= effectiveXRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveXRange]);\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 // When categorical labels are supplied, ticks must sit on the actual data\n // x-positions rather than the computed nice-step values above. Sorted\n // ascending so labels map deterministically to x regardless of series order.\n const xDataValues = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xDataValues.length;\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 title\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 : undefined,\n [title, theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n let data;\n\n if (variant === \"stacked\") {\n // For stacked mode, we need to calculate cumulative values\n const cumulativeY = new Array(dataSeries[0]?.x.length || 0).fill(0);\n\n data = dataSeries.map((series, index) => {\n // Calculate cumulative values for this series\n const stackedY = series.y.map((value, i) => {\n const result = cumulativeY[i] + value;\n cumulativeY[i] = result;\n return result;\n });\n\n const color = seriesColor(index, series.color);\n return {\n x: series.x,\n y: stackedY,\n // Tooltips report the series' own values, not the stacked sums\n customdata: series.y,\n type: \"scatter\" as const,\n // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: index === 0 ? (\"tozeroy\" as const) : (\"tonexty\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\n });\n } else {\n // Normal mode - each area fills independently from zero\n data = 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 // Dots mark each data point — the spots the tooltip anchors to\n mode: \"lines+markers\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n fill: series.fill || (\"tozeroy\" as const),\n fillcolor: color,\n line: {\n color,\n width: 2,\n },\n marker: {\n size: 6,\n color,\n line: { color: theme.markerOutline, width: 1.5 },\n },\n };\n });\n }\n\n const layout = {\n width,\n height: height,\n ...(titleOptions ? { title: titleOptions } : {}),\n margin: {\n l: 80,\n r: 40,\n b: 80,\n t: title ? TITLE_MARGIN_TOP : NO_TITLE_MARGIN_TOP,\n pad: 0,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n 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 tickmode: \"array\" as const,\n tickvals: useCategoricalX ? xDataValues : xTicks,\n ...(useCategoricalX ? { ticktext: xTickText } : {}),\n showgrid: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 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, effectiveXRange, effectiveYRange, variant, xTitle, yTitle, title, titleOptions, tickOptions, xTicks, yTicks, xDataValues, useCategoricalX, xTickText, theme, bindTooltip]);\n\n return (\n <div className=\"area-graph-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { AreaGraph };\nexport type { AreaDataSeries, AreaGraphVariant, AreaGraphProps };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","AreaGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","points","chartTooltipLines","point","xMin","xMax","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveXRange","effectiveYRange","xTicks","range","step","ticks","current","yTicks","xDataValues","s","a","b","useCategoricalX","tickOptions","titleOptions","useEffect","data","cumulativeY","index","stackedY","value","i","result","color","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":";;;;;;;AAoBA,MAAMA,IAAmB,IACnBC,IAAsB,IAqBtBC,KAAsC,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;AAAA,EACA,WAAAC;AACF,MAAM;AACJ,QAAMC,IAAUC,EAAuB,IAAI,GACrCC,IAAQC,EAAA,GACR,EAAE,aAAAC,GAAa,gBAAAC,EAAA,IAAmBC,EAAgB;AAAA;AAAA;AAAA,IAGtD,UAAU,CAACC,MACTC;AAAA,MACED,EAAO;AAAA,QAAI,CAACE,MACV,OAAOA,EAAM,cAAe,WACxB,EAAE,GAAGA,GAAO,GAAGA,EAAM,eACrBA;AAAA,MAAA;AAAA,MAEN,EAAE,QAAQb,GAAQ,QAAQC,EAAA;AAAA,IAAO;AAAA,EACnC,CACH,GAEK,EAAE,MAAAa,GAAM,MAAAC,GAAM,MAAAC,GAAM,MAAAC,EAAA,IAASC,EAAQ,MAAM;AAC/C,QAAIC,IAAO,OAAO,WACdC,IAAO,OAAO,WACdC,IAAO,OAAO,WACdC,IAAO,OAAO;AAElB,IAAA5B,EAAW,QAAQ,CAAC6B,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,MAAM3B,MAAY,YAAY,IAAIsB,IAAOM;AAAA,MACzC,MAAML,IAAOK;AAAA,IAAA;AAAA,EAEjB,GAAG,CAACjC,GAAYK,CAAO,CAAC,GAElB6B,IAAkBV;AAAA,IACtB,MAAMrB,KAAU,CAACiB,GAAMC,CAAI;AAAA,IAC3B,CAAClB,GAAQiB,GAAMC,CAAI;AAAA,EAAA,GAEfc,IAAkBX;AAAA,IACtB,MAAMpB,KAAU,CAACkB,GAAMC,CAAI;AAAA,IAC3B,CAACnB,GAAQkB,GAAMC,CAAI;AAAA,EAAA,GAGfa,IAASZ,EAAQ,MAAM;AAC3B,UAAMa,IAAQH,EAAgB,CAAC,IAAIA,EAAgB,CAAC;AACpD,QAAII,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,KAAKN,EAAgB,CAAC,IAAII,CAAI,IAAIA;AACrD,WAAOE,KAAWN,EAAgB,CAAC;AACjC,MAAAK,EAAM,KAAKC,CAAO,GAClBA,KAAWF;AAEb,WAAOC;AAAA,EACT,GAAG,CAACL,CAAe,CAAC,GAEdO,IAASjB,EAAQ,MAAM;AAC3B,UAAMa,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,GAKdO,IAAclB;AAAA,IAClB,MAAM,CAAC,GAAG,IAAI,IAAIxB,EAAW,QAAQ,CAAC2C,MAAMA,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAACC,GAAGC,MAAMD,IAAIC,CAAC;AAAA,IACvE,CAAC7C,CAAU;AAAA,EAAA,GAKP8C,IAAkB,CAAC,CAACrC,KAAaA,EAAU,WAAWiC,EAAY,QAElEK,IAAcvB;AAAA,IAClB,OAAO;AAAA,MACL,WAAWZ,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,GAGFoC,IAAexB;AAAA,IACnB,MACEhB,IACI;AAAA,MACE,MAAMA;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,IAEF;AAAA,IACN,CAACJ,GAAOI,CAAK;AAAA,EAAA;AAGf,SAAAqC,EAAU,MAAM;AACd,QAAI,CAACvC,EAAQ,QAAS;AAEtB,QAAIwC;AAEJ,QAAI7C,MAAY,WAAW;AAEzB,YAAM8C,IAAc,IAAI,MAAMnD,EAAW,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC;AAElE,MAAAkD,IAAOlD,EAAW,IAAI,CAAC6B,GAAQuB,MAAU;AAEvC,cAAMC,IAAWxB,EAAO,EAAE,IAAI,CAACyB,GAAOC,MAAM;AAC1C,gBAAMC,IAASL,EAAYI,CAAC,IAAID;AAChC,iBAAAH,EAAYI,CAAC,IAAIC,GACVA;AAAA,QACT,CAAC,GAEKC,IAAQC,EAAYN,GAAOvB,EAAO,KAAK;AAC7C,eAAO;AAAA,UACL,GAAGA,EAAO;AAAA,UACV,GAAGwB;AAAA;AAAA,UAEH,YAAYxB,EAAO;AAAA,UACnB,MAAM;AAAA;AAAA,UAEN,MAAM;AAAA,UACN,MAAMA,EAAO;AAAA,UACb,WAAW;AAAA,UACX,MAAMuB,MAAU,IAAK,YAAuB;AAAA,UAC5C,WAAWK;AAAA,UACX,MAAM;AAAA,YACJ,OAAAA;AAAA,YACA,OAAO;AAAA,UAAA;AAAA,UAET,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,OAAAA;AAAA,YACA,MAAM,EAAE,OAAO7C,EAAM,eAAe,OAAO,IAAA;AAAA,UAAI;AAAA,QACjD;AAAA,MAEJ,CAAC;AAAA,IACH;AAEE,MAAAsC,IAAOlD,EAAW,IAAI,CAAC6B,GAAQuB,MAAU;AACvC,cAAMK,IAAQC,EAAYN,GAAOvB,EAAO,KAAK;AAC7C,eAAO;AAAA,UACL,GAAGA,EAAO;AAAA,UACV,GAAGA,EAAO;AAAA,UACV,MAAM;AAAA;AAAA,UAEN,MAAM;AAAA,UACN,MAAMA,EAAO;AAAA,UACb,WAAW;AAAA,UACX,MAAMA,EAAO,QAAS;AAAA,UACtB,WAAW4B;AAAA,UACX,MAAM;AAAA,YACJ,OAAAA;AAAA,YACA,OAAO;AAAA,UAAA;AAAA,UAET,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,OAAAA;AAAA,YACA,MAAM,EAAE,OAAO7C,EAAM,eAAe,OAAO,IAAA;AAAA,UAAI;AAAA,QACjD;AAAA,MAEJ,CAAC;AAGH,UAAM+C,IAAS;AAAA,MACb,OAAA1D;AAAA,MACA,QAAAC;AAAA,MACA,GAAI8C,IAAe,EAAE,OAAOA,EAAA,IAAiB,CAAA;AAAA,MAC7C,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAGxC,IAAQX,IAAmBC;AAAA,QAC9B,KAAK;AAAA,MAAA;AAAA,MAEP,eAAec,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,OAAOT;AAAA,QACP,WAAW,CAACA;AAAA,QACZ,UAAU;AAAA,QACV,UAAU2C,IAAkBJ,IAAcN;AAAA,QAC1C,GAAIU,IAAkB,EAAE,UAAUrC,EAAA,IAAc,CAAA;AAAA,QAChD,UAAU;AAAA,QACV,GAAGsC;AAAA,MAAA;AAAA,MAEL,OAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAMxC;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,UAAUqC;AAAA,QACV,UAAU;AAAA,QACV,GAAGM;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,OAAOnC,EAAM;AAAA,UACb,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,YAAY;AAAA,QAAA;AAAA,MACd;AAAA,MAEF,YAAY;AAAA,IAAA,GAGRgD,IAAS;AAAA,MACb,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,IAAA;AAGf,IAAAC,EAAO,QAAQnD,EAAQ,SAASwC,GAAMS,GAAQC,CAAM,GACpD9C,EAAYJ,EAAQ,OAAO;AAG3B,UAAMoD,IAAcpD,EAAQ;AAG5B,WAAO,MAAM;AACX,MAAIoD,KACFD,EAAO,MAAMC,CAAW;AAAA,IAE5B;AAAA,EACF,GAAG,CAAC9D,GAAYC,GAAOC,GAAQC,GAAQC,GAAQ8B,GAAiBC,GAAiB9B,GAASC,GAAQC,GAAQC,GAAOwC,GAAcD,GAAaX,GAAQK,GAAQC,GAAaI,GAAiBrC,GAAWG,GAAOE,CAAW,CAAC,GAGtN,gBAAAiD,EAAC,OAAA,EAAI,WAAU,iCACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,KAAKtD,GAAS,OAAO,EAAE,OAAO,QAAQ,QAAQ,OAAA,EAAO,CAAG;AAAA,IAC5DK;AAAA,EAAA,GACH;AAEJ;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("react/jsx-runtime"),q=require("plotly.js-dist"),s=require("react"),A=require("../ChartTooltip/ChartTooltip.cjs"),B=require("../../../hooks/use-plotly-theme.cjs"),L=require("../../../utils/colors.cjs"),j=({dataSeries:a,width:M=1e3,height:x=600,xRange:p,yRange:i,variant:m="group",xTitle:g="Columns",yTitle:d="Rows",title:k="Bar Graph",barWidth:b=24})=>{const c=s.useRef(null),o=B.usePlotlyTheme(),{bindTooltip:w,tooltipElement:z}=A.useChartTooltip({xLabel:g,yLabel:d}),{yMin:C,yMax:E}=s.useMemo(()=>{let t=Number.MAX_VALUE,e=Number.MIN_VALUE,n=Number.MAX_VALUE,r=Number.MIN_VALUE;a.forEach(N=>{N.x.forEach(f=>{t=Math.min(t,f),e=Math.max(e,f)}),N.y.forEach(f=>{n=Math.min(n,f),r=Math.max(r,f)})});const l=(e-t)*.1,h=(r-n)*.1;return{xMin:t-l,xMax:e+l,yMin:m==="stack"?0:n-h,yMax:r+h}},[a,m]),u=s.useMemo(()=>i||[C,E],[i,C,E]),v=s.useMemo(()=>[...new Set(a.flatMap(t=>t.x))],[a]),I=s.useMemo(()=>{const t=u[1]-u[0];let e=Math.pow(10,Math.floor(Math.log10(t)));t/e>10&&(e=e*2),t/e<4&&(e=e/2);const n=[];let r=Math.ceil(u[0]/e)*e;for(;r<=u[1];)n.push(r),r+=e;return n},[u]),_=s.useMemo(()=>{switch(m){case"stack":return"stack";case"overlay":return"overlay";default:return"group"}},[m]),y=s.useMemo(()=>({tickcolor:o.tickColor,ticklen:12,tickwidth:1,ticks:"outside",tickfont:{size:16,color:o.textColor,family:"Inter, sans-serif",weight:400},linecolor:o.lineColor,linewidth:1,position:0,zeroline:!1}),[o]);return s.useEffect(()=>{if(!c.current)return;const t=a.map((l,h)=>({x:l.x,y:l.y,type:"bar",name:l.name,hoverinfo:"none",marker:{color:L.seriesColor(h,l.color)},width:b,error_y:l.error_y})),e={title:{text:k,font:{size:32,family:"Inter, sans-serif",color:o.textColor}},width:M,height:x,margin:{l:80,r:30,b:80,t:60,pad:0},paper_bgcolor:o.paperBg,plot_bgcolor:o.plotBg,font:{family:"Inter, sans-serif"},barmode:_,bargap:.15,dragmode:!1,xaxis:{title:{text:g,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:32},gridcolor:o.gridColor,range:p,autorange:!p,tickmode:"array",tickvals:v,showgrid:!0,...y},yaxis:{title:{text:d,font:{size:16,color:o.textSecondary,family:"Inter, sans-serif",weight:400},standoff:30},gridcolor:o.gridColor,range:i,autorange:!i,tickmode:"array",tickvals:I,showgrid:!0,...y},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:16,color:o.legendColor,family:"Inter, sans-serif",weight:500}},showlegend:a.length>1},n={responsive:!0,displayModeBar:!1,displaylogo:!1};q.newPlot(c.current,t,e,n),w(c.current);const r=c.current;return()=>{r&&q.purge(r)}},[a,M,x,p,i,g,d,k,b,_,y,v,I,o,w]),P.jsxs("div",{className:"bar-graph-container relative",children:[P.jsx("div",{ref:c,style:{width:"100%",height:"100%"}}),z]})};exports.BarGraph=j;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const L=require("react/jsx-runtime"),q=require("plotly.js-dist"),l=require("react"),B=require("../ChartTooltip/ChartTooltip.cjs"),O=require("../../../hooks/use-plotly-theme.cjs"),X=require("../../../utils/colors.cjs"),j=60,G=30,T=({dataSeries:a,width:k=1e3,height:w=600,xRange:d,yRange:c,variant:m="group",xTitle:y="Columns",yTitle:M="Rows",title:h,barWidth:_=24,xTickText:g})=>{const i=l.useRef(null),t=O.usePlotlyTheme(),{bindTooltip:C,tooltipElement:z}=B.useChartTooltip({xLabel:y,yLabel:M}),{yMin:E,yMax:I}=l.useMemo(()=>{let e=Number.MAX_VALUE,o=Number.MIN_VALUE,n=Number.MAX_VALUE,r=Number.MIN_VALUE;a.forEach(A=>{A.x.forEach(f=>{e=Math.min(e,f),o=Math.max(o,f)}),A.y.forEach(f=>{n=Math.min(n,f),r=Math.max(r,f)})});const s=(o-e)*.1,p=(r-n)*.1;return{xMin:e-s,xMax:o+s,yMin:m==="stack"?0:n-p,yMax:r+p}},[a,m]),u=l.useMemo(()=>c||[E,I],[c,E,I]),x=l.useMemo(()=>[...new Set(a.flatMap(e=>e.x))].sort((e,o)=>e-o),[a]),N=!!g&&g.length===x.length,P=l.useMemo(()=>{const e=u[1]-u[0];let o=Math.pow(10,Math.floor(Math.log10(e)));e/o>10&&(o=o*2),e/o<4&&(o=o/2);const n=[];let r=Math.ceil(u[0]/o)*o;for(;r<=u[1];)n.push(r),r+=o;return n},[u]),v=l.useMemo(()=>{switch(m){case"stack":return"stack";case"overlay":return"overlay";default:return"group"}},[m]),b=l.useMemo(()=>({tickcolor:t.tickColor,ticklen:12,tickwidth:1,ticks:"outside",tickfont:{size:16,color:t.textColor,family:"Inter, sans-serif",weight:400},linecolor:t.lineColor,linewidth:1,position:0,zeroline:!1}),[t]);return l.useEffect(()=>{if(!i.current)return;const e=a.map((s,p)=>({x:s.x,y:s.y,type:"bar",name:s.name,hoverinfo:"none",marker:{color:X.seriesColor(p,s.color)},width:_,error_y:s.error_y})),o={...h?{title:{text:h,font:{size:32,family:"Inter, sans-serif",color:t.textColor}}}:{},width:k,height:w,margin:{l:80,r:30,b:80,t:h?j:G,pad:0},paper_bgcolor:t.paperBg,plot_bgcolor:t.plotBg,font:{family:"Inter, sans-serif"},barmode:v,bargap:.15,dragmode:!1,xaxis:{title:{text:y,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:32},gridcolor:t.gridColor,range:d,autorange:!d,tickmode:"array",tickvals:x,...N?{ticktext:g}:{},showgrid:!0,...b},yaxis:{title:{text:M,font:{size:16,color:t.textSecondary,family:"Inter, sans-serif",weight:400},standoff:30},gridcolor:t.gridColor,range:c,autorange:!c,tickmode:"array",tickvals:P,showgrid:!0,...b},legend:{x:.5,y:-.2,xanchor:"center",yanchor:"top",orientation:"h",font:{size:16,color:t.legendColor,family:"Inter, sans-serif",weight:500}},showlegend:a.length>1},n={responsive:!0,displayModeBar:!1,displaylogo:!1};q.newPlot(i.current,e,o,n),C(i.current);const r=i.current;return()=>{r&&q.purge(r)}},[a,k,w,d,c,y,M,h,_,v,b,x,P,N,g,t,C]),L.jsxs("div",{className:"bar-graph-container relative",children:[L.jsx("div",{ref:i,style:{width:"100%",height:"100%"}}),z]})};exports.BarGraph=T;
2
2
  //# sourceMappingURL=BarGraph.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"BarGraph.cjs","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
+ {"version":3,"file":"BarGraph.cjs","sources":["../../../../src/components/charts/BarGraph/BarGraph.tsx"],"sourcesContent":["import Plotly from \"plotly.js-dist\";\nimport React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { useChartTooltip } from \"../ChartTooltip\";\n\nimport { usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { seriesColor } from \"@/utils/colors\";\n\ninterface BarDataSeries {\n x: number[];\n y: number[];\n name: string;\n /** Optional color override (auto-assigned from CHART_COLORS if not provided) */\n color?: string;\n error_y?: {\n type: \"data\";\n array: number[];\n visible: boolean;\n };\n}\n\ntype BarGraphVariant = \"group\" | \"stack\" | \"overlay\";\n\n/** Top margin reserving room for the 32px title; reduced when no title is set */\nconst TITLE_MARGIN_TOP = 60;\nconst NO_TITLE_MARGIN_TOP = 30;\n\ninterface BarGraphProps {\n dataSeries: BarDataSeries[];\n width?: number;\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: BarGraphVariant;\n xTitle?: string;\n yTitle?: string;\n title?: string;\n barWidth?: number;\n /**\n * Categorical labels for the x-axis ticks. When provided, the x data values\n * still drive bar positioning but the displayed tick labels match these\n * strings in order (e.g. [\"Mon\", \"Tue\", …]). Should align 1:1 with the\n * unique, ordered x values across all series.\n */\n xTickText?: string[];\n}\n\nconst BarGraph: React.FC<BarGraphProps> = ({\n dataSeries,\n width = 1000,\n height = 600,\n xRange,\n yRange,\n variant = \"group\",\n xTitle = \"Columns\",\n yTitle = \"Rows\",\n title,\n barWidth = 24,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n const { bindTooltip, tooltipElement } = useChartTooltip({ xLabel: xTitle, yLabel: yTitle });\n\n const { yMin, yMax } = useMemo(() => {\n let minX = Number.MAX_VALUE;\n let maxX = Number.MIN_VALUE;\n let minY = Number.MAX_VALUE;\n let maxY = Number.MIN_VALUE;\n\n dataSeries.forEach((series) => {\n series.x.forEach((x) => {\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n });\n series.y.forEach((y) => {\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n });\n });\n\n const xPadding = (maxX - minX) * 0.1;\n const yPadding = (maxY - minY) * 0.1;\n\n return {\n xMin: minX - xPadding,\n xMax: maxX + xPadding,\n yMin: variant === \"stack\" ? 0 : minY - yPadding,\n yMax: maxY + yPadding,\n };\n }, [dataSeries, variant]);\n\n const effectiveYRange = useMemo(\n () => yRange || [yMin, yMax],\n [yRange, yMin, yMax],\n );\n\n const xTicks = useMemo(\n () => [...new Set(dataSeries.flatMap((s) => s.x))].sort((a, b) => a - b),\n [dataSeries],\n );\n\n // Only apply categorical labels when they align 1:1 with the tick positions;\n // a mismatch would silently mis-label ticks, so fall back to numeric ticks.\n const useCategoricalX = !!xTickText && xTickText.length === xTicks.length;\n\n const yTicks = useMemo(() => {\n const range = effectiveYRange[1] - effectiveYRange[0];\n let step = Math.pow(10, Math.floor(Math.log10(range)));\n\n if (range / step > 10) step = step * 2;\n if (range / step < 4) step = step / 2;\n\n const ticks = [];\n let current = Math.ceil(effectiveYRange[0] / step) * step;\n while (current <= effectiveYRange[1]) {\n ticks.push(current);\n current += step;\n }\n return ticks;\n }, [effectiveYRange]);\n\n const barMode = useMemo((): \"group\" | \"stack\" | \"overlay\" => {\n switch (variant) {\n case \"stack\":\n return \"stack\";\n case \"overlay\":\n return \"overlay\";\n case \"group\":\n default:\n return \"group\";\n }\n }, [variant]);\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: 12,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: 16,\n color: theme.textColor,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme],\n );\n\n useEffect(() => {\n if (!plotRef.current) return;\n\n const data = dataSeries.map((series, index) => ({\n x: series.x,\n y: series.y,\n type: \"bar\" as const,\n name: series.name,\n hoverinfo: \"none\" as const,\n marker: {\n color: seriesColor(index, series.color),\n },\n width: barWidth,\n error_y: series.error_y,\n }));\n\n const layout = {\n ...(title\n ? {\n title: {\n text: title,\n font: {\n size: 32,\n family: \"Inter, sans-serif\",\n color: theme.textColor,\n },\n },\n }\n : {}),\n width,\n height,\n margin: {\n l: 80,\n r: 30,\n b: 80,\n t: title ? TITLE_MARGIN_TOP : NO_TITLE_MARGIN_TOP,\n pad: 0,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: \"Inter, sans-serif\",\n },\n barmode: barMode,\n bargap: 0.15,\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 32,\n },\n gridcolor: theme.gridColor,\n range: xRange,\n autorange: !xRange,\n tickmode: \"array\" as const,\n tickvals: xTicks,\n ...(useCategoricalX ? { ticktext: xTickText } : {}),\n showgrid: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: \"Inter, sans-serif\",\n weight: 400,\n },\n standoff: 30,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTicks,\n showgrid: true,\n ...tickOptions,\n },\n legend: {\n x: 0.5,\n y: -0.2,\n xanchor: \"center\" as const,\n yanchor: \"top\" as const,\n orientation: \"h\" as const,\n font: {\n size: 16,\n color: theme.legendColor,\n family: \"Inter, sans-serif\",\n weight: 500,\n },\n },\n showlegend: dataSeries.length > 1,\n };\n\n const config = {\n responsive: true,\n displayModeBar: false,\n displaylogo: false,\n };\n\n Plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n const plotElement = plotRef.current;\n\n // Cleanup function\n return () => {\n if (plotElement) {\n Plotly.purge(plotElement);\n }\n };\n }, [dataSeries, width, height, xRange, yRange, xTitle, yTitle, title, barWidth, barMode, tickOptions, xTicks, yTicks, useCategoricalX, xTickText, theme, bindTooltip]);\n\n return (\n <div className=\"bar-graph-container relative\">\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { BarGraph };\nexport type { BarDataSeries, BarGraphVariant, BarGraphProps };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","BarGraph","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","barWidth","xTickText","plotRef","useRef","theme","usePlotlyTheme","bindTooltip","tooltipElement","useChartTooltip","yMin","yMax","useMemo","minX","maxX","minY","maxY","series","x","y","xPadding","yPadding","effectiveYRange","xTicks","s","a","b","useCategoricalX","yTicks","range","step","ticks","current","barMode","tickOptions","useEffect","data","index","seriesColor","layout","config","Plotly","plotElement","jsxs","jsx"],"mappings":"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"}