@tetrascience-npm/tetrascience-react-ui 1.0.0-beta.148.1 → 1.0.0-beta.149.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/charts/AreaPlot/AreaPlot.cjs +1 -1
- package/dist/components/charts/AreaPlot/AreaPlot.cjs.map +1 -1
- package/dist/components/charts/AreaPlot/AreaPlot.js +166 -148
- package/dist/components/charts/AreaPlot/AreaPlot.js.map +1 -1
- package/dist/components/charts/BarChart/BarChart.cjs +1 -1
- package/dist/components/charts/BarChart/BarChart.cjs.map +1 -1
- package/dist/components/charts/BarChart/BarChart.d.ts +7 -0
- package/dist/components/charts/BarChart/BarChart.js +151 -120
- package/dist/components/charts/BarChart/BarChart.js.map +1 -1
- package/dist/components/charts/BoxPlot/BoxPlot.cjs +1 -1
- package/dist/components/charts/BoxPlot/BoxPlot.cjs.map +1 -1
- package/dist/components/charts/BoxPlot/BoxPlot.d.ts +4 -0
- package/dist/components/charts/BoxPlot/BoxPlot.js +133 -102
- package/dist/components/charts/BoxPlot/BoxPlot.js.map +1 -1
- package/dist/components/charts/ChartTooltip/lines.cjs.map +1 -1
- package/dist/components/charts/ChartTooltip/lines.d.ts +2 -0
- package/dist/components/charts/ChartTooltip/lines.js.map +1 -1
- package/dist/components/charts/Chromatogram/Chromatogram.cjs +1 -1
- package/dist/components/charts/Chromatogram/Chromatogram.cjs.map +1 -1
- package/dist/components/charts/Chromatogram/Chromatogram.js +111 -114
- package/dist/components/charts/Chromatogram/Chromatogram.js.map +1 -1
- package/dist/components/charts/Chromatogram/plotBuilder.cjs +4 -1
- package/dist/components/charts/Chromatogram/plotBuilder.cjs.map +1 -1
- package/dist/components/charts/Chromatogram/plotBuilder.d.ts +32 -2
- package/dist/components/charts/Chromatogram/plotBuilder.js +170 -127
- package/dist/components/charts/Chromatogram/plotBuilder.js.map +1 -1
- package/dist/components/charts/Chromatogram/regionOverlays.cjs +1 -1
- package/dist/components/charts/Chromatogram/regionOverlays.cjs.map +1 -1
- package/dist/components/charts/Chromatogram/regionOverlays.js +11 -11
- package/dist/components/charts/Chromatogram/regionOverlays.js.map +1 -1
- package/dist/components/charts/Chromatogram/types.d.ts +4 -2
- package/dist/components/charts/Electropherogram/Electropherogram.cjs +1 -1
- package/dist/components/charts/Electropherogram/Electropherogram.cjs.map +1 -1
- package/dist/components/charts/Electropherogram/Electropherogram.js +89 -88
- package/dist/components/charts/Electropherogram/Electropherogram.js.map +1 -1
- package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.cjs +1 -1
- package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.cjs.map +1 -1
- package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.js +4 -5
- package/dist/components/charts/ScatterPlotInteractive/ScatterPlotInteractive.js.map +1 -1
- package/dist/components/charts/chart-scale.cjs +2 -0
- package/dist/components/charts/chart-scale.cjs.map +1 -0
- package/dist/components/charts/chart-scale.d.ts +61 -0
- package/dist/components/charts/chart-scale.js +61 -0
- package/dist/components/charts/chart-scale.js.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.scoped.css +1 -1
- package/dist/index.tailwind.css +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Q=require("react/jsx-runtime"),r=require("react"),L=require("../chart-scale.cjs"),lt=require("../ChartTooltip/ChartTooltip.cjs"),I=require("../plotly-loader.cjs"),ct=require("../../../hooks/use-element-size.cjs"),m=require("../../../hooks/use-plotly-theme.cjs"),st=require("../../../lib/utils.cjs"),Z=require("../../../utils/colors.cjs"),at=require("../ChartTooltip/lines.cjs"),ut=({dataSeries:f,width:q,height:H,xRange:p,yRange:x,variant:k="normal",xTitle:z,yTitle:v,title:w,xTickText:T})=>{const d=r.useRef(null),i=m.usePlotlyTheme(),[$,O]=ct.useElementSize(),h=q??O.width,s=H??O.height,V=h>0&&s>0,tt=q===void 0,et=H===void 0,o=L.resolveChartScale(h,s),A=w?o.margin.tTitle:o.margin.tNoTitle,C=r.useRef({width:h,height:s});C.current={width:h,height:s};const F=r.useRef(!1),_=r.useRef({width:0,height:0}),{bindTooltip:X,tooltipElement:ot}=lt.useChartTooltip({getLines:e=>at.chartTooltipLines(e.map(t=>typeof t.customdata=="number"?{...t,y:t.customdata}:t),{xLabel:z,yLabel:v})}),{xMin:j,xMax:B,yMin:U,yMax:K}=r.useMemo(()=>{let e=Number.MAX_VALUE,t=Number.MIN_VALUE,c=Number.MAX_VALUE,n=Number.MIN_VALUE;f.forEach(u=>{u.x.forEach(a=>{e=Math.min(e,a),t=Math.max(t,a)}),u.y.forEach(a=>{c=Math.min(c,a),n=Math.max(n,a)})});const M=(t-e)*.1,l=(n-c)*.1;return{xMin:e-M,xMax:t+M,yMin:k==="stacked"?0:c-l,yMax:n+l}},[f,k]),g=r.useMemo(()=>p||[j,B],[p,j,B]),y=r.useMemo(()=>x||[U,K],[x,U,K]),W=r.useMemo(()=>{const e=g[1]-g[0];let t=Math.pow(10,Math.floor(Math.log10(e)));e/t>10&&(t=t*2),e/t<4&&(t=t/2);const c=[];let n=Math.ceil(g[0]/t)*t;for(;n<=g[1];)c.push(n),n+=t;return c},[g]),b=r.useMemo(()=>{const e=y[1]-y[0];let t=Math.pow(10,Math.floor(Math.log10(e)));e/t>10&&(t=t*2),e/t<4&&(t=t/2);const c=[];let n=Math.ceil(y[0]/t)*t;for(;n<=y[1];)c.push(n),n+=t;return c},[y]),E=r.useMemo(()=>[...new Set(f.flatMap(e=>e.x))].sort((e,t)=>e-t),[f]),N=!!T&&T.length===E.length,R=r.useMemo(()=>L.thinTicks(b,L.maxTickCount(s-A-o.margin.b,o.tickFontSize*L.Y_TICK_LABEL_SPACING)),[b,s,A,o]),rt=R.join(","),S=r.useRef(R);S.current=R;const P=r.useMemo(()=>({tickcolor:i.tickColor,ticklen:o.ticklen,tickwidth:1,ticks:"outside",tickfont:{size:o.tickFontSize,color:i.textColor,family:m.CHART_FONT_FAMILY,weight:400},linecolor:i.lineColor,linewidth:1,position:0,zeroline:!1}),[i,o]),Y=r.useMemo(()=>w?{text:w,x:.5,y:.95,xanchor:"center",yanchor:"top",font:{size:o.titleFontSize,weight:600,family:m.CHART_FONT_FAMILY,color:i.textColor,lineheight:1.2,standoff:30}}:void 0,[w,i,o]);return r.useEffect(()=>{if(!d.current||!V)return;let e;if(k==="stacked"){const l=new Array(f[0]?.x.length||0).fill(0);e=f.map((u,a)=>{const nt=u.y.map((it,G)=>{const J=l[G]+it;return l[G]=J,J}),D=Z.seriesColor(a,u.color);return{x:u.x,y:nt,customdata:u.y,type:"scatter",mode:"lines",name:u.name,hoverinfo:"none",fill:a===0?"tozeroy":"tonexty",fillcolor:D,line:{color:D,width:2}}})}else e=f.map((l,u)=>{const a=Z.seriesColor(u,l.color);return{x:l.x,y:l.y,type:"scatter",mode:"lines",name:l.name,hoverinfo:"none",fill:l.fill||"tozeroy",fillcolor:a,line:{color:a,width:2}}});const t={width:C.current.width,height:C.current.height,...Y?{title:Y}:{},margin:{l:o.margin.l,r:o.margin.r,b:o.margin.b,t:A,pad:0},paper_bgcolor:i.paperBg,plot_bgcolor:i.plotBg,font:{family:m.CHART_FONT_FAMILY},dragmode:!1,xaxis:{title:{text:z,font:{size:o.axisTitleFontSize,color:i.textSecondary,family:m.CHART_FONT_FAMILY,weight:400},standoff:o.axisTitleStandoff},gridcolor:i.gridColor,range:p,autorange:!p,tickmode:"array",tickvals:N?E:W,...N?{ticktext:T}:{},showgrid:!0,automargin:!0,...P},yaxis:{title:{text:v,font:{size:o.axisTitleFontSize,color:i.textSecondary,family:m.CHART_FONT_FAMILY,weight:400},standoff:o.axisTitleStandoff},gridcolor:i.gridColor,range:x,autorange:!x,tickmode:"array",tickvals:S.current,showgrid:!0,automargin:!0,...P},legend:{x:.5,y:0,xanchor:"center",yanchor:"bottom",yref:"container",orientation:"h",font:{size:o.legendFontSize,color:i.legendColor,family:m.CHART_FONT_FAMILY,weight:500,lineheight:o.legendLineHeight}},showlegend:!0},c={responsive:!1,displayModeBar:!1,displaylogo:!1};let n=!1,M=null;return I.loadPlotly().then(l=>{n||!d.current||(l.newPlot(d.current,e,t,c),X(d.current),M=d.current,F.current=!0,_.current={...C.current})}),()=>{n=!0,M&&(I.getLoadedPlotly().purge(M),F.current=!1)}},[f,V,p,x,g,y,k,z,v,w,Y,P,W,b,E,N,T,i,o,A,X]),r.useEffect(()=>{const e=d.current;!e||!F.current||h<=0||s<=0||_.current.width===h&&_.current.height===s||(_.current={width:h,height:s},I.getLoadedPlotly().relayout(e,{width:h,height:s,"yaxis.tickvals":S.current}).catch(()=>{}))},[h,s,rt]),Q.jsxs("div",{ref:$,className:st.cn("area-graph-container relative",tt&&"w-full",et&&"h-full"),children:[Q.jsx("div",{ref:d,style:{width:"100%",height:"100%"}}),ot]})};exports.AreaPlot=ut;
|
|
2
2
|
//# sourceMappingURL=AreaPlot.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AreaPlot.cjs","sources":["../../../../src/components/charts/AreaPlot/AreaPlot.tsx"],"sourcesContent":["import React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { chartTooltipLines, useChartTooltip } from \"../ChartTooltip\";\nimport { getLoadedPlotly, loadPlotly } from \"../plotly-loader\";\n\nimport { useElementSize } from \"@/hooks/use-element-size\";\nimport { CHART_FONT_FAMILY, usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { cn } from \"@/lib/utils\";\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 AreaPlotVariant = \"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 AreaPlotProps {\n dataSeries: AreaDataSeries[];\n /**\n * Fixed width in pixels. When omitted, the chart fills its container and\n * tracks the container's width via a `ResizeObserver`.\n */\n width?: number;\n /**\n * Fixed height in pixels. When omitted, the chart fills its container and\n * tracks the container's height via a `ResizeObserver`.\n */\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: AreaPlotVariant;\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 AreaPlot: React.FC<AreaPlotProps> = ({\n dataSeries,\n width,\n height,\n xRange,\n yRange,\n variant = \"normal\",\n xTitle,\n yTitle,\n title,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n\n // When width/height are omitted the chart fills its container; otherwise the\n // explicit pixel size wins. The container is measured either way (cheap) but\n // only used as the resolved size for the omitted dimension(s).\n const [containerRef, measured] = useElementSize<HTMLDivElement>();\n const resolvedWidth = width ?? measured.width;\n const resolvedHeight = height ?? measured.height;\n const hasSize = resolvedWidth > 0 && resolvedHeight > 0;\n // Fill is per-dimension: omit width to fill the container width, omit height\n // to fill its height (so e.g. a fixed width with a container-driven height works).\n const fillWidth = width === undefined;\n const fillHeight = height === undefined;\n\n // Hold the latest resolved size in a ref so the newPlot effect can read it\n // without listing it as a dependency — size changes are handled by a\n // separate relayout effect rather than by tearing down and recreating the plot.\n const sizeRef = useRef({ width: resolvedWidth, height: resolvedHeight });\n sizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n const plotInitedRef = useRef(false);\n // Size last applied to the plot, so the resize effect can skip a redundant\n // relayout right after newPlot already drew at that size.\n const appliedSizeRef = useRef({ width: 0, height: 0 });\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: CHART_FONT_FAMILY,\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: CHART_FONT_FAMILY,\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 || !hasSize) 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 mode: \"lines\" 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 };\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 mode: \"lines\" 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 };\n });\n }\n\n const layout = {\n width: sizeRef.current.width,\n height: sizeRef.current.height,\n ...(titleOptions ? { title: titleOptions } : {}),\n margin: {\n l: 80,\n r: 40,\n // Reserve room for tick labels, the x-axis title, and the\n // container-anchored bottom legend stacked beneath them.\n b: 96,\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: CHART_FONT_FAMILY,\n },\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: CHART_FONT_FAMILY,\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 // Reserve space for tick labels + the axis title so the bottom legend\n // can't overlap them at small sizes (SW-2157).\n automargin: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: 16,\n color: theme.textSecondary,\n family: CHART_FONT_FAMILY,\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 automargin: true,\n ...tickOptions,\n },\n legend: {\n // Anchor to the bottom of the container (not the plot area) so the\n // legend always clears the x-axis tick labels + title — a paper-relative\n // fractional offset collapses into the ticks at small heights (SW-2157).\n x: 0.5,\n y: 0,\n xanchor: \"center\" as const,\n yanchor: \"bottom\" as const,\n yref: \"container\" as const,\n orientation: \"h\" as const,\n font: {\n size: 13,\n color: theme.legendColor,\n family: CHART_FONT_FAMILY,\n weight: 500,\n lineheight: 18,\n },\n },\n showlegend: true,\n };\n\n const config = {\n // We drive sizing explicitly from the measured container, so Plotly's own\n // window-resize responsiveness is disabled (it can't see container resizes).\n responsive: false,\n displayModeBar: false,\n displaylogo: false,\n };\n\n // Plotly is loaded lazily so it stays out of the consumer's main chunk\n // (SW-2007); the draw is skipped if the effect re-runs or unmounts first.\n let cancelled = false;\n let plotElement: HTMLDivElement | null = null;\n void loadPlotly().then((plotly) => {\n if (cancelled || !plotRef.current) return;\n plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n plotElement = plotRef.current;\n plotInitedRef.current = true;\n appliedSizeRef.current = { ...sizeRef.current };\n });\n\n return () => {\n cancelled = true;\n if (plotElement) {\n getLoadedPlotly().purge(plotElement);\n plotInitedRef.current = false;\n }\n };\n }, [dataSeries, hasSize, xRange, yRange, effectiveXRange, effectiveYRange, variant, xTitle, yTitle, title, titleOptions, tickOptions, xTicks, yTicks, xDataValues, useCategoricalX, xTickText, theme, bindTooltip]);\n\n // Resize in place when the measured/overridden size changes — far cheaper\n // than recreating the plot (and it preserves tooltip/event bindings).\n useEffect(() => {\n const plotElement = plotRef.current;\n if (!plotElement || !plotInitedRef.current || resolvedWidth <= 0 || resolvedHeight <= 0) {\n return;\n }\n // newPlot already drew at the current size; skip the redundant relayout\n // (it would queue an automargin redraw that can reject if we unmount first).\n if (\n appliedSizeRef.current.width === resolvedWidth &&\n appliedSizeRef.current.height === resolvedHeight\n ) {\n return;\n }\n appliedSizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n // Swallow rejections from a relayout that races an unmount/purge.\n // plotInitedRef guarantees Plotly finished loading, so sync access is safe.\n void getLoadedPlotly()\n .relayout(plotElement, { width: resolvedWidth, height: resolvedHeight })\n .catch(() => {});\n }, [resolvedWidth, resolvedHeight]);\n\n return (\n <div\n ref={containerRef}\n className={cn(\"area-graph-container relative\", fillWidth && \"w-full\", fillHeight && \"h-full\")}\n >\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { AreaPlot };\nexport type { AreaDataSeries, AreaPlotVariant, AreaPlotProps };\n"],"names":["TITLE_MARGIN_TOP","NO_TITLE_MARGIN_TOP","AreaPlot","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","xTickText","plotRef","useRef","theme","usePlotlyTheme","containerRef","measured","useElementSize","resolvedWidth","resolvedHeight","hasSize","fillWidth","fillHeight","sizeRef","plotInitedRef","appliedSizeRef","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","CHART_FONT_FAMILY","titleOptions","useEffect","data","cumulativeY","index","stackedY","value","i","result","color","seriesColor","layout","config","cancelled","plotElement","loadPlotly","plotly","getLoadedPlotly","jsxs","cn","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AreaPlot.cjs","sources":["../../../../src/components/charts/AreaPlot/AreaPlot.tsx"],"sourcesContent":["import React, { useEffect, useRef, useMemo } from \"react\";\n\nimport { Y_TICK_LABEL_SPACING, maxTickCount, resolveChartScale, thinTicks } from \"../chart-scale\";\nimport { chartTooltipLines, useChartTooltip } from \"../ChartTooltip\";\nimport { getLoadedPlotly, loadPlotly } from \"../plotly-loader\";\n\nimport type Plotly from \"plotly.js-dist\";\n\nimport { useElementSize } from \"@/hooks/use-element-size\";\nimport { CHART_FONT_FAMILY, usePlotlyTheme } from \"@/hooks/use-plotly-theme\";\nimport { cn } from \"@/lib/utils\";\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 AreaPlotVariant = \"normal\" | \"stacked\";\n\ninterface AreaPlotProps {\n dataSeries: AreaDataSeries[];\n /**\n * Fixed width in pixels. When omitted, the chart fills its container and\n * tracks the container's width via a `ResizeObserver`.\n */\n width?: number;\n /**\n * Fixed height in pixels. When omitted, the chart fills its container and\n * tracks the container's height via a `ResizeObserver`.\n */\n height?: number;\n xRange?: [number, number];\n yRange?: [number, number];\n variant?: AreaPlotVariant;\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 AreaPlot: React.FC<AreaPlotProps> = ({\n dataSeries,\n width,\n height,\n xRange,\n yRange,\n variant = \"normal\",\n xTitle,\n yTitle,\n title,\n xTickText,\n}) => {\n const plotRef = useRef<HTMLDivElement>(null);\n const theme = usePlotlyTheme();\n\n // When width/height are omitted the chart fills its container; otherwise the\n // explicit pixel size wins. The container is measured either way (cheap) but\n // only used as the resolved size for the omitted dimension(s).\n const [containerRef, measured] = useElementSize<HTMLDivElement>();\n const resolvedWidth = width ?? measured.width;\n const resolvedHeight = height ?? measured.height;\n const hasSize = resolvedWidth > 0 && resolvedHeight > 0;\n // Fill is per-dimension: omit width to fill the container width, omit height\n // to fill its height (so e.g. a fixed width with a container-driven height works).\n const fillWidth = width === undefined;\n const fillHeight = height === undefined;\n // Fonts, tick length and margins step down on small canvases so the plot\n // area (not the chrome) gets the pixels (SW-2298).\n const scale = resolveChartScale(resolvedWidth, resolvedHeight);\n const marginTop = title ? scale.margin.tTitle : scale.margin.tNoTitle;\n\n // Hold the latest resolved size in a ref so the newPlot effect can read it\n // without listing it as a dependency — size changes are handled by a\n // separate relayout effect rather than by tearing down and recreating the plot.\n const sizeRef = useRef({ width: resolvedWidth, height: resolvedHeight });\n sizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n const plotInitedRef = useRef(false);\n // Size last applied to the plot, so the resize effect can skip a redundant\n // relayout right after newPlot already drew at that size.\n const appliedSizeRef = useRef({ width: 0, height: 0 });\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 // Y ticks thinned to what fits the plot height. Derived from the resolved\n // (not last-plotted) height so an in-place resize also updates them via the\n // relayout effect below, instead of only when the scale bucket flips.\n const yTickVals = useMemo(\n () =>\n thinTicks(\n yTicks,\n maxTickCount(\n resolvedHeight - marginTop - scale.margin.b,\n scale.tickFontSize * Y_TICK_LABEL_SPACING,\n ),\n ),\n [yTicks, resolvedHeight, marginTop, scale],\n );\n const yTickKey = yTickVals.join(\",\");\n const yTickValsRef = useRef(yTickVals);\n yTickValsRef.current = yTickVals;\n\n const tickOptions = useMemo(\n () => ({\n tickcolor: theme.tickColor,\n ticklen: scale.ticklen,\n tickwidth: 1,\n ticks: \"outside\" as const,\n tickfont: {\n size: scale.tickFontSize,\n color: theme.textColor,\n family: CHART_FONT_FAMILY,\n weight: 400,\n },\n linecolor: theme.lineColor,\n linewidth: 1,\n position: 0,\n zeroline: false,\n }),\n [theme, scale],\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: scale.titleFontSize,\n weight: 600,\n family: CHART_FONT_FAMILY,\n color: theme.textColor,\n lineheight: 1.2,\n standoff: 30,\n },\n }\n : undefined,\n [title, theme, scale],\n );\n\n useEffect(() => {\n if (!plotRef.current || !hasSize) 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 mode: \"lines\" 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 };\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 mode: \"lines\" 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 };\n });\n }\n\n const layout = {\n width: sizeRef.current.width,\n height: sizeRef.current.height,\n ...(titleOptions ? { title: titleOptions } : {}),\n margin: {\n l: scale.margin.l,\n r: scale.margin.r,\n // Reserve room for tick labels, the x-axis title, and the\n // container-anchored bottom legend stacked beneath them.\n b: scale.margin.b,\n t: marginTop,\n pad: 0,\n },\n paper_bgcolor: theme.paperBg,\n plot_bgcolor: theme.plotBg,\n font: {\n family: CHART_FONT_FAMILY,\n },\n dragmode: false as const,\n xaxis: {\n title: {\n text: xTitle,\n font: {\n size: scale.axisTitleFontSize,\n color: theme.textSecondary,\n family: CHART_FONT_FAMILY,\n weight: 400,\n },\n standoff: scale.axisTitleStandoff,\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 // Reserve space for tick labels + the axis title so the bottom legend\n // can't overlap them at small sizes (SW-2157).\n automargin: true,\n ...tickOptions,\n },\n yaxis: {\n title: {\n text: yTitle,\n font: {\n size: scale.axisTitleFontSize,\n color: theme.textSecondary,\n family: CHART_FONT_FAMILY,\n weight: 400,\n },\n standoff: scale.axisTitleStandoff,\n },\n gridcolor: theme.gridColor,\n range: yRange,\n autorange: !yRange,\n tickmode: \"array\" as const,\n tickvals: yTickValsRef.current,\n showgrid: true,\n automargin: true,\n ...tickOptions,\n },\n legend: {\n // Anchor to the bottom of the container (not the plot area) so the\n // legend always clears the x-axis tick labels + title — a paper-relative\n // fractional offset collapses into the ticks at small heights (SW-2157).\n x: 0.5,\n y: 0,\n xanchor: \"center\" as const,\n yanchor: \"bottom\" as const,\n yref: \"container\" as const,\n orientation: \"h\" as const,\n font: {\n size: scale.legendFontSize,\n color: theme.legendColor,\n family: CHART_FONT_FAMILY,\n weight: 500,\n lineheight: scale.legendLineHeight,\n },\n },\n showlegend: true,\n };\n\n const config = {\n // We drive sizing explicitly from the measured container, so Plotly's own\n // window-resize responsiveness is disabled (it can't see container resizes).\n responsive: false,\n displayModeBar: false,\n displaylogo: false,\n };\n\n // Plotly is loaded lazily so it stays out of the consumer's main chunk\n // (SW-2007); the draw is skipped if the effect re-runs or unmounts first.\n let cancelled = false;\n let plotElement: HTMLDivElement | null = null;\n void loadPlotly().then((plotly) => {\n if (cancelled || !plotRef.current) return;\n plotly.newPlot(plotRef.current, data, layout, config);\n bindTooltip(plotRef.current);\n\n // Capture ref value for cleanup\n plotElement = plotRef.current;\n plotInitedRef.current = true;\n appliedSizeRef.current = { ...sizeRef.current };\n });\n\n return () => {\n cancelled = true;\n if (plotElement) {\n getLoadedPlotly().purge(plotElement);\n plotInitedRef.current = false;\n }\n };\n }, [dataSeries, hasSize, xRange, yRange, effectiveXRange, effectiveYRange, variant, xTitle, yTitle, title, titleOptions, tickOptions, xTicks, yTicks, xDataValues, useCategoricalX, xTickText, theme, scale, marginTop, bindTooltip]);\n\n // Resize in place when the measured/overridden size changes — far cheaper\n // than recreating the plot (and it preserves tooltip/event bindings).\n useEffect(() => {\n const plotElement = plotRef.current;\n if (!plotElement || !plotInitedRef.current || resolvedWidth <= 0 || resolvedHeight <= 0) {\n return;\n }\n // newPlot already drew at the current size; skip the redundant relayout\n // (it would queue an automargin redraw that can reject if we unmount first).\n if (\n appliedSizeRef.current.width === resolvedWidth &&\n appliedSizeRef.current.height === resolvedHeight\n ) {\n return;\n }\n appliedSizeRef.current = { width: resolvedWidth, height: resolvedHeight };\n // Swallow rejections from a relayout that races an unmount/purge.\n // plotInitedRef guarantees Plotly finished loading, so sync access is safe.\n void getLoadedPlotly()\n .relayout(plotElement, {\n width: resolvedWidth,\n height: resolvedHeight,\n // Re-thin the y ticks for the new plot height (SW-2298). The flattened\n // key is valid relayout input but not part of the Layout type.\n \"yaxis.tickvals\": yTickValsRef.current,\n } as Partial<Plotly.Layout>)\n .catch(() => {});\n }, [resolvedWidth, resolvedHeight, yTickKey]);\n\n return (\n <div\n ref={containerRef}\n className={cn(\"area-graph-container relative\", fillWidth && \"w-full\", fillHeight && \"h-full\")}\n >\n <div ref={plotRef} style={{ width: \"100%\", height: \"100%\" }} />\n {tooltipElement}\n </div>\n );\n};\n\nexport { AreaPlot };\nexport type { AreaDataSeries, AreaPlotVariant, AreaPlotProps };\n"],"names":["AreaPlot","dataSeries","width","height","xRange","yRange","variant","xTitle","yTitle","title","xTickText","plotRef","useRef","theme","usePlotlyTheme","containerRef","measured","useElementSize","resolvedWidth","resolvedHeight","hasSize","fillWidth","fillHeight","scale","resolveChartScale","marginTop","sizeRef","plotInitedRef","appliedSizeRef","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","yTickVals","thinTicks","maxTickCount","Y_TICK_LABEL_SPACING","yTickKey","yTickValsRef","tickOptions","CHART_FONT_FAMILY","titleOptions","useEffect","data","cumulativeY","index","stackedY","value","i","result","color","seriesColor","layout","config","cancelled","plotElement","loadPlotly","plotly","getLoadedPlotly","jsxs","cn","jsx"],"mappings":"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"}
|
|
@@ -1,220 +1,232 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useRef as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { jsxs as lt, jsx as ct } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as k, useMemo as f, useEffect as J } from "react";
|
|
3
|
+
import { resolveChartScale as at, thinTicks as st, maxTickCount as ht, Y_TICK_LABEL_SPACING as ft } from "../chart-scale.js";
|
|
4
|
+
import { useChartTooltip as mt } from "../ChartTooltip/ChartTooltip.js";
|
|
5
|
+
import { loadPlotly as ut, getLoadedPlotly as Q } from "../plotly-loader.js";
|
|
6
|
+
import { useElementSize as dt } from "../../../hooks/use-element-size.js";
|
|
7
|
+
import { usePlotlyTheme as gt, CHART_FONT_FAMILY as y } from "../../../hooks/use-plotly-theme.js";
|
|
8
|
+
import { cn as pt } from "../../../lib/utils.js";
|
|
9
|
+
import { seriesColor as Z } from "../../../utils/colors.js";
|
|
10
|
+
import { chartTooltipLines as yt } from "../ChartTooltip/lines.js";
|
|
11
|
+
const At = ({
|
|
12
|
+
dataSeries: m,
|
|
12
13
|
width: I,
|
|
13
|
-
height:
|
|
14
|
-
xRange:
|
|
15
|
-
yRange:
|
|
16
|
-
variant:
|
|
17
|
-
xTitle:
|
|
18
|
-
yTitle:
|
|
19
|
-
title:
|
|
20
|
-
xTickText:
|
|
14
|
+
height: X,
|
|
15
|
+
xRange: x,
|
|
16
|
+
yRange: w,
|
|
17
|
+
variant: z = "normal",
|
|
18
|
+
xTitle: L,
|
|
19
|
+
yTitle: A,
|
|
20
|
+
title: M,
|
|
21
|
+
xTickText: v
|
|
21
22
|
}) => {
|
|
22
|
-
const u =
|
|
23
|
-
|
|
24
|
-
const
|
|
23
|
+
const u = k(null), n = gt(), [$, B] = dt(), h = I ?? B.width, c = X ?? B.height, H = h > 0 && c > 0, tt = I === void 0, et = X === void 0, o = at(h, c), C = M ? o.margin.tTitle : o.margin.tNoTitle, b = k({ width: h, height: c });
|
|
24
|
+
b.current = { width: h, height: c };
|
|
25
|
+
const T = k(!1), E = k({ width: 0, height: 0 }), { bindTooltip: U, tooltipElement: ot } = mt({
|
|
25
26
|
// Stacked traces carry the original series values as customdata;
|
|
26
27
|
// display those instead of the cumulative stack heights
|
|
27
|
-
getLines: (
|
|
28
|
-
|
|
28
|
+
getLines: (e) => yt(
|
|
29
|
+
e.map(
|
|
29
30
|
(t) => typeof t.customdata == "number" ? { ...t, y: t.customdata } : t
|
|
30
31
|
),
|
|
31
|
-
{ xLabel:
|
|
32
|
+
{ xLabel: L, yLabel: A }
|
|
32
33
|
)
|
|
33
|
-
}), { xMin:
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}),
|
|
39
|
-
l = Math.min(l,
|
|
34
|
+
}), { xMin: j, xMax: O, yMin: K, yMax: R } = f(() => {
|
|
35
|
+
let e = Number.MAX_VALUE, t = Number.MIN_VALUE, l = Number.MAX_VALUE, r = Number.MIN_VALUE;
|
|
36
|
+
m.forEach((s) => {
|
|
37
|
+
s.x.forEach((a) => {
|
|
38
|
+
e = Math.min(e, a), t = Math.max(t, a);
|
|
39
|
+
}), s.y.forEach((a) => {
|
|
40
|
+
l = Math.min(l, a), r = Math.max(r, a);
|
|
40
41
|
});
|
|
41
42
|
});
|
|
42
|
-
const
|
|
43
|
+
const p = (t - e) * 0.1, i = (r - l) * 0.1;
|
|
43
44
|
return {
|
|
44
|
-
xMin:
|
|
45
|
-
xMax: t +
|
|
46
|
-
yMin:
|
|
47
|
-
yMax:
|
|
45
|
+
xMin: e - p,
|
|
46
|
+
xMax: t + p,
|
|
47
|
+
yMin: z === "stacked" ? 0 : l - i,
|
|
48
|
+
yMax: r + i
|
|
48
49
|
};
|
|
49
|
-
}, [
|
|
50
|
-
() =>
|
|
51
|
-
[
|
|
52
|
-
),
|
|
53
|
-
() =>
|
|
54
|
-
[
|
|
55
|
-
),
|
|
56
|
-
const
|
|
57
|
-
let t = Math.pow(10, Math.floor(Math.log10(
|
|
58
|
-
|
|
50
|
+
}, [m, z]), d = f(
|
|
51
|
+
() => x || [j, O],
|
|
52
|
+
[x, j, O]
|
|
53
|
+
), g = f(
|
|
54
|
+
() => w || [K, R],
|
|
55
|
+
[w, K, R]
|
|
56
|
+
), W = f(() => {
|
|
57
|
+
const e = d[1] - d[0];
|
|
58
|
+
let t = Math.pow(10, Math.floor(Math.log10(e)));
|
|
59
|
+
e / t > 10 && (t = t * 2), e / t < 4 && (t = t / 2);
|
|
59
60
|
const l = [];
|
|
60
|
-
let
|
|
61
|
-
for (;
|
|
62
|
-
l.push(
|
|
61
|
+
let r = Math.ceil(d[0] / t) * t;
|
|
62
|
+
for (; r <= d[1]; )
|
|
63
|
+
l.push(r), r += t;
|
|
63
64
|
return l;
|
|
64
|
-
}, [
|
|
65
|
-
const
|
|
66
|
-
let t = Math.pow(10, Math.floor(Math.log10(
|
|
67
|
-
|
|
65
|
+
}, [d]), _ = f(() => {
|
|
66
|
+
const e = g[1] - g[0];
|
|
67
|
+
let t = Math.pow(10, Math.floor(Math.log10(e)));
|
|
68
|
+
e / t > 10 && (t = t * 2), e / t < 4 && (t = t / 2);
|
|
68
69
|
const l = [];
|
|
69
|
-
let
|
|
70
|
-
for (;
|
|
71
|
-
l.push(
|
|
70
|
+
let r = Math.ceil(g[0] / t) * t;
|
|
71
|
+
for (; r <= g[1]; )
|
|
72
|
+
l.push(r), r += t;
|
|
72
73
|
return l;
|
|
73
|
-
}, [
|
|
74
|
-
() => [...new Set(
|
|
75
|
-
[
|
|
76
|
-
),
|
|
74
|
+
}, [g]), N = f(
|
|
75
|
+
() => [...new Set(m.flatMap((e) => e.x))].sort((e, t) => e - t),
|
|
76
|
+
[m]
|
|
77
|
+
), S = !!v && v.length === N.length, F = f(
|
|
78
|
+
() => st(
|
|
79
|
+
_,
|
|
80
|
+
ht(
|
|
81
|
+
c - C - o.margin.b,
|
|
82
|
+
o.tickFontSize * ft
|
|
83
|
+
)
|
|
84
|
+
),
|
|
85
|
+
[_, c, C, o]
|
|
86
|
+
), rt = F.join(","), P = k(F);
|
|
87
|
+
P.current = F;
|
|
88
|
+
const V = f(
|
|
77
89
|
() => ({
|
|
78
|
-
tickcolor:
|
|
79
|
-
ticklen:
|
|
90
|
+
tickcolor: n.tickColor,
|
|
91
|
+
ticklen: o.ticklen,
|
|
80
92
|
tickwidth: 1,
|
|
81
93
|
ticks: "outside",
|
|
82
94
|
tickfont: {
|
|
83
|
-
size:
|
|
84
|
-
color:
|
|
85
|
-
family:
|
|
95
|
+
size: o.tickFontSize,
|
|
96
|
+
color: n.textColor,
|
|
97
|
+
family: y,
|
|
86
98
|
weight: 400
|
|
87
99
|
},
|
|
88
|
-
linecolor:
|
|
100
|
+
linecolor: n.lineColor,
|
|
89
101
|
linewidth: 1,
|
|
90
102
|
position: 0,
|
|
91
103
|
zeroline: !1
|
|
92
104
|
}),
|
|
93
|
-
[
|
|
94
|
-
),
|
|
95
|
-
() =>
|
|
96
|
-
text:
|
|
105
|
+
[n, o]
|
|
106
|
+
), Y = f(
|
|
107
|
+
() => M ? {
|
|
108
|
+
text: M,
|
|
97
109
|
x: 0.5,
|
|
98
110
|
y: 0.95,
|
|
99
111
|
xanchor: "center",
|
|
100
112
|
yanchor: "top",
|
|
101
113
|
font: {
|
|
102
|
-
size:
|
|
114
|
+
size: o.titleFontSize,
|
|
103
115
|
weight: 600,
|
|
104
|
-
family:
|
|
105
|
-
color:
|
|
116
|
+
family: y,
|
|
117
|
+
color: n.textColor,
|
|
106
118
|
lineheight: 1.2,
|
|
107
119
|
standoff: 30
|
|
108
120
|
}
|
|
109
121
|
} : void 0,
|
|
110
|
-
[
|
|
122
|
+
[M, n, o]
|
|
111
123
|
);
|
|
112
|
-
return
|
|
113
|
-
if (!u.current || !
|
|
114
|
-
let
|
|
115
|
-
if (
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
return
|
|
121
|
-
}),
|
|
124
|
+
return J(() => {
|
|
125
|
+
if (!u.current || !H) return;
|
|
126
|
+
let e;
|
|
127
|
+
if (z === "stacked") {
|
|
128
|
+
const i = new Array(m[0]?.x.length || 0).fill(0);
|
|
129
|
+
e = m.map((s, a) => {
|
|
130
|
+
const nt = s.y.map((it, G) => {
|
|
131
|
+
const q = i[G] + it;
|
|
132
|
+
return i[G] = q, q;
|
|
133
|
+
}), D = Z(a, s.color);
|
|
122
134
|
return {
|
|
123
|
-
x:
|
|
124
|
-
y:
|
|
135
|
+
x: s.x,
|
|
136
|
+
y: nt,
|
|
125
137
|
// Tooltips report the series' own values, not the stacked sums
|
|
126
|
-
customdata:
|
|
138
|
+
customdata: s.y,
|
|
127
139
|
type: "scatter",
|
|
128
140
|
mode: "lines",
|
|
129
|
-
name:
|
|
141
|
+
name: s.name,
|
|
130
142
|
hoverinfo: "none",
|
|
131
|
-
fill:
|
|
132
|
-
fillcolor:
|
|
143
|
+
fill: a === 0 ? "tozeroy" : "tonexty",
|
|
144
|
+
fillcolor: D,
|
|
133
145
|
line: {
|
|
134
|
-
color:
|
|
146
|
+
color: D,
|
|
135
147
|
width: 2
|
|
136
148
|
}
|
|
137
149
|
};
|
|
138
150
|
});
|
|
139
151
|
} else
|
|
140
|
-
|
|
141
|
-
const
|
|
152
|
+
e = m.map((i, s) => {
|
|
153
|
+
const a = Z(s, i.color);
|
|
142
154
|
return {
|
|
143
|
-
x:
|
|
144
|
-
y:
|
|
155
|
+
x: i.x,
|
|
156
|
+
y: i.y,
|
|
145
157
|
type: "scatter",
|
|
146
158
|
mode: "lines",
|
|
147
|
-
name:
|
|
159
|
+
name: i.name,
|
|
148
160
|
hoverinfo: "none",
|
|
149
|
-
fill:
|
|
150
|
-
fillcolor:
|
|
161
|
+
fill: i.fill || "tozeroy",
|
|
162
|
+
fillcolor: a,
|
|
151
163
|
line: {
|
|
152
|
-
color:
|
|
164
|
+
color: a,
|
|
153
165
|
width: 2
|
|
154
166
|
}
|
|
155
167
|
};
|
|
156
168
|
});
|
|
157
169
|
const t = {
|
|
158
|
-
width:
|
|
159
|
-
height:
|
|
160
|
-
...
|
|
170
|
+
width: b.current.width,
|
|
171
|
+
height: b.current.height,
|
|
172
|
+
...Y ? { title: Y } : {},
|
|
161
173
|
margin: {
|
|
162
|
-
l:
|
|
163
|
-
r:
|
|
174
|
+
l: o.margin.l,
|
|
175
|
+
r: o.margin.r,
|
|
164
176
|
// Reserve room for tick labels, the x-axis title, and the
|
|
165
177
|
// container-anchored bottom legend stacked beneath them.
|
|
166
|
-
b:
|
|
167
|
-
t:
|
|
178
|
+
b: o.margin.b,
|
|
179
|
+
t: C,
|
|
168
180
|
pad: 0
|
|
169
181
|
},
|
|
170
|
-
paper_bgcolor:
|
|
171
|
-
plot_bgcolor:
|
|
182
|
+
paper_bgcolor: n.paperBg,
|
|
183
|
+
plot_bgcolor: n.plotBg,
|
|
172
184
|
font: {
|
|
173
|
-
family:
|
|
185
|
+
family: y
|
|
174
186
|
},
|
|
175
187
|
dragmode: !1,
|
|
176
188
|
xaxis: {
|
|
177
189
|
title: {
|
|
178
|
-
text:
|
|
190
|
+
text: L,
|
|
179
191
|
font: {
|
|
180
|
-
size:
|
|
181
|
-
color:
|
|
182
|
-
family:
|
|
192
|
+
size: o.axisTitleFontSize,
|
|
193
|
+
color: n.textSecondary,
|
|
194
|
+
family: y,
|
|
183
195
|
weight: 400
|
|
184
196
|
},
|
|
185
|
-
standoff:
|
|
197
|
+
standoff: o.axisTitleStandoff
|
|
186
198
|
},
|
|
187
|
-
gridcolor:
|
|
188
|
-
range:
|
|
189
|
-
autorange: !
|
|
199
|
+
gridcolor: n.gridColor,
|
|
200
|
+
range: x,
|
|
201
|
+
autorange: !x,
|
|
190
202
|
tickmode: "array",
|
|
191
|
-
tickvals:
|
|
192
|
-
...
|
|
203
|
+
tickvals: S ? N : W,
|
|
204
|
+
...S ? { ticktext: v } : {},
|
|
193
205
|
showgrid: !0,
|
|
194
206
|
// Reserve space for tick labels + the axis title so the bottom legend
|
|
195
207
|
// can't overlap them at small sizes (SW-2157).
|
|
196
208
|
automargin: !0,
|
|
197
|
-
...
|
|
209
|
+
...V
|
|
198
210
|
},
|
|
199
211
|
yaxis: {
|
|
200
212
|
title: {
|
|
201
|
-
text:
|
|
213
|
+
text: A,
|
|
202
214
|
font: {
|
|
203
|
-
size:
|
|
204
|
-
color:
|
|
205
|
-
family:
|
|
215
|
+
size: o.axisTitleFontSize,
|
|
216
|
+
color: n.textSecondary,
|
|
217
|
+
family: y,
|
|
206
218
|
weight: 400
|
|
207
219
|
},
|
|
208
|
-
standoff:
|
|
220
|
+
standoff: o.axisTitleStandoff
|
|
209
221
|
},
|
|
210
|
-
gridcolor:
|
|
211
|
-
range:
|
|
212
|
-
autorange: !
|
|
222
|
+
gridcolor: n.gridColor,
|
|
223
|
+
range: w,
|
|
224
|
+
autorange: !w,
|
|
213
225
|
tickmode: "array",
|
|
214
|
-
tickvals:
|
|
226
|
+
tickvals: P.current,
|
|
215
227
|
showgrid: !0,
|
|
216
228
|
automargin: !0,
|
|
217
|
-
...
|
|
229
|
+
...V
|
|
218
230
|
},
|
|
219
231
|
legend: {
|
|
220
232
|
// Anchor to the bottom of the container (not the plot area) so the
|
|
@@ -227,11 +239,11 @@ const st = 80, ht = 40, xt = ({
|
|
|
227
239
|
yref: "container",
|
|
228
240
|
orientation: "h",
|
|
229
241
|
font: {
|
|
230
|
-
size:
|
|
231
|
-
color:
|
|
232
|
-
family:
|
|
242
|
+
size: o.legendFontSize,
|
|
243
|
+
color: n.legendColor,
|
|
244
|
+
family: y,
|
|
233
245
|
weight: 500,
|
|
234
|
-
lineheight:
|
|
246
|
+
lineheight: o.legendLineHeight
|
|
235
247
|
}
|
|
236
248
|
},
|
|
237
249
|
showlegend: !0
|
|
@@ -242,29 +254,35 @@ const st = 80, ht = 40, xt = ({
|
|
|
242
254
|
displayModeBar: !1,
|
|
243
255
|
displaylogo: !1
|
|
244
256
|
};
|
|
245
|
-
let
|
|
246
|
-
return
|
|
247
|
-
|
|
257
|
+
let r = !1, p = null;
|
|
258
|
+
return ut().then((i) => {
|
|
259
|
+
r || !u.current || (i.newPlot(u.current, e, t, l), U(u.current), p = u.current, T.current = !0, E.current = { ...b.current });
|
|
248
260
|
}), () => {
|
|
249
|
-
|
|
261
|
+
r = !0, p && (Q().purge(p), T.current = !1);
|
|
250
262
|
};
|
|
251
|
-
}, [
|
|
252
|
-
const
|
|
253
|
-
!
|
|
263
|
+
}, [m, H, x, w, d, g, z, L, A, M, Y, V, W, _, N, S, v, n, o, C, U]), J(() => {
|
|
264
|
+
const e = u.current;
|
|
265
|
+
!e || !T.current || h <= 0 || c <= 0 || E.current.width === h && E.current.height === c || (E.current = { width: h, height: c }, Q().relayout(e, {
|
|
266
|
+
width: h,
|
|
267
|
+
height: c,
|
|
268
|
+
// Re-thin the y ticks for the new plot height (SW-2298). The flattened
|
|
269
|
+
// key is valid relayout input but not part of the Layout type.
|
|
270
|
+
"yaxis.tickvals": P.current
|
|
271
|
+
}).catch(() => {
|
|
254
272
|
}));
|
|
255
|
-
}, [
|
|
273
|
+
}, [h, c, rt]), /* @__PURE__ */ lt(
|
|
256
274
|
"div",
|
|
257
275
|
{
|
|
258
|
-
ref:
|
|
259
|
-
className:
|
|
276
|
+
ref: $,
|
|
277
|
+
className: pt("area-graph-container relative", tt && "w-full", et && "h-full"),
|
|
260
278
|
children: [
|
|
261
|
-
/* @__PURE__ */
|
|
262
|
-
|
|
279
|
+
/* @__PURE__ */ ct("div", { ref: u, style: { width: "100%", height: "100%" } }),
|
|
280
|
+
ot
|
|
263
281
|
]
|
|
264
282
|
}
|
|
265
283
|
);
|
|
266
284
|
};
|
|
267
285
|
export {
|
|
268
|
-
|
|
286
|
+
At as AreaPlot
|
|
269
287
|
};
|
|
270
288
|
//# sourceMappingURL=AreaPlot.js.map
|