@acronis-platform/ui-react 5.4.4 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/components/ui/area-chart/area-chart.js +114 -113
  2. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  3. package/dist/components/ui/bar-chart/bar-chart.js +53 -49
  4. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  5. package/dist/components/ui/chart/chart.js +108 -97
  6. package/dist/components/ui/chart/chart.js.map +1 -1
  7. package/dist/components/ui/composed-chart/composed-chart.js +134 -130
  8. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
  9. package/dist/components/ui/confidence-cone/confidence-cone.js +36 -35
  10. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
  11. package/dist/components/ui/dialog/dialog.js +69 -67
  12. package/dist/components/ui/dialog/dialog.js.map +1 -1
  13. package/dist/components/ui/funnel-chart/funnel-chart.js +38 -37
  14. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
  15. package/dist/components/ui/line-chart/line-chart.js +35 -34
  16. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  17. package/dist/components/ui/pie-chart/pie-chart.js +28 -27
  18. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
  19. package/dist/components/ui/radar-chart/radar-chart.js +68 -65
  20. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
  21. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +64 -63
  22. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
  23. package/dist/components/ui/scatter-chart/scatter-chart.js +26 -26
  24. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  25. package/dist/components/ui/treemap/treemap.js +22 -22
  26. package/dist/components/ui/treemap/treemap.js.map +1 -1
  27. package/dist/index.js +106 -106
  28. package/dist/llms/area-chart.md +1 -0
  29. package/dist/llms/bar-chart.md +1 -0
  30. package/dist/llms/chart.md +10 -0
  31. package/dist/llms/composed-chart.md +1 -0
  32. package/dist/llms/confidence-cone.md +1 -0
  33. package/dist/llms/funnel-chart.md +1 -0
  34. package/dist/llms/line-chart.md +1 -0
  35. package/dist/llms/pie-chart.md +1 -0
  36. package/dist/llms/radar-chart.md +1 -0
  37. package/dist/llms/radial-bar-chart.md +1 -0
  38. package/dist/llms/scatter-chart.md +1 -0
  39. package/dist/llms/treemap.md +1 -0
  40. package/dist/llms.txt +1 -1
  41. package/dist/react.js +106 -106
  42. package/dist/src/components/ui/area-chart/area-chart.d.ts +6 -1
  43. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +8 -2
  44. package/dist/src/components/ui/category-bar/category-bar.d.ts +1 -1
  45. package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +16 -0
  46. package/dist/src/components/ui/chart/chart.d.ts +12 -1
  47. package/dist/src/components/ui/chart/index.d.ts +1 -1
  48. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +6 -1
  49. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +6 -1
  50. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +6 -1
  51. package/dist/src/components/ui/grid/grid.d.ts +1 -1
  52. package/dist/src/components/ui/line-chart/line-chart.d.ts +6 -1
  53. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +6 -1
  54. package/dist/src/components/ui/progress-circle/progress-circle.d.ts +1 -1
  55. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +9 -1
  56. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +6 -1
  57. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +6 -1
  58. package/dist/src/components/ui/spinner/spinner.d.ts +1 -1
  59. package/dist/src/components/ui/stack/stack.d.ts +1 -1
  60. package/dist/src/components/ui/treemap/treemap.d.ts +6 -1
  61. package/dist/ui-react.css +1 -1
  62. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"composed-chart.js","names":[],"sources":["../../../../src/components/ui/composed-chart/composed-chart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n Area,\n Bar,\n Brush,\n CartesianGrid,\n ComposedChart as RechartsComposedChart,\n LabelList,\n Line,\n ReferenceArea,\n ReferenceLine,\n XAxis,\n YAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n CHART_LABEL_FONT_SIZE,\n CHART_LABEL_MARGIN,\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAnimation,\n resolveAxisDomain,\n resolveBrushProps,\n resolveCartesianLabelPosition,\n resolveCategoryRange,\n resolveChartReferenceValue,\n resolveLabelFillClass,\n resolveReferenceLineProps,\n resolveRotatedTickAnchor,\n resolveXAxisTitle,\n resolveYAxisTitle,\n toLabelFormatter,\n toCssKey,\n type ChartConfig,\n type ChartPalette,\n type ChartLegendContentProps,\n type CartesianChartProps,\n type ChartAnimationProps,\n type ChartBrushProps,\n type ChartCategoryRange,\n type ChartDataLabelProps,\n type ChartReferenceLine,\n type CartesianLabelPosition,\n type ChartYAxisTarget,\n type SecondaryYAxisProps,\n} from '../chart';\nimport {\n mergeXAxisLayoutMargin,\n useXAxisLayout,\n} from '../chart/use-x-axis-layout';\nimport { resolveXAxisTickLabels } from '../chart/chart-format';\n\n// A typed recharts composition over the shared `Chart` primitives. A composed\n// chart's defining trait is that each series picks its own render type\n// (bar / line / area) over one shared category axis, so the mark mix is not a\n// variant — it lives in the `series[].type` list. `orientation` is: it is the\n// same one-axis choice `BarChart` models (which way the marks grow), and it\n// re-roles both axes. The class stays empty because the recharts SVG — not CSS —\n// draws the series; CVA is kept so the variant set is a first-class,\n// spec-conformant part of the API (matched against ui-spec's api.yaml enums) and\n// exposed via `VariantProps`. The resolved value is mirrored onto\n// `data-orientation` for styling hooks and tests.\nconst composedChartVariants = cva('', {\n variants: {\n orientation: {\n vertical: '',\n horizontal: '',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\nexport type ComposedSeriesType = 'bar' | 'line' | 'area';\n\n/** Interpolation for a line or area series. */\nexport type ComposedCurveType = 'linear' | 'monotone' | 'step';\n\n/**\n * How a series is marked in the legend. Deliberately narrower than recharts'\n * icon set: `ChartLegendContent` draws its own marker and reads only whether the\n * entry is a `line` (a rule, dashed when the series is) or anything else (a\n * swatch), so the wider union would advertise icons that never render. `none`\n * keeps the series off the legend entirely.\n */\nexport type ComposedSeriesLegendType = 'line' | 'rect' | 'none';\n\n/** Plot-area inset, in px. Any side left out keeps the chart's own default. */\nexport interface ComposedChartMargin {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\n// recharts 3 paints graphical items into z-index layers keyed by their *type*\n// (Area 100, Bar 300, Line 400), so JSX order alone decides nothing across\n// types — an area would always sit under the bars however the caller ordered\n// `series`. Giving each entry an explicit z-index from its index restores\n// \"later entry paints on top\". The band stays under the axis layer (500).\nconst SERIES_Z_INDEX_BASE = 100;\n\n// A reference band is a backdrop, so it has to sit under the marks. That is\n// recharts' own arrangement (its band defaults to 100, below Bar's 300), but\n// pulling the series down into the 100s to order them by array index lands them\n// on the band's layer — where the band, rendered later, would paint over them.\n// Below the series and above the grid (-100) restores the intent. A reference\n// *line* keeps its own default (400): a rule reads as an annotation on top.\nconst REFERENCE_AREA_Z_INDEX = 50;\n\n// recharts keys every axis by id, defaulting to `0` on both the axis and each\n// graphical item. The primary value axis keeps that implicit id rather than\n// taking an explicit one, so a chart with no secondary series renders\n// byte-identically — and `CartesianGrid` (whose own ids default to `0`) keeps\n// drawing its lines against the primary scale, which is the only readable\n// choice: gridlines from two different scales would cross at meaningless\n// heights.\nconst SECONDARY_VALUE_AXIS_ID = 'secondary';\n\n// recharts' own plot inset, spelled out so a caller-supplied `margin` can\n// override one side without erasing the other three.\nconst DEFAULT_CHART_MARGIN = { top: 5, right: 5, bottom: 5, left: 5 } as const;\n\n/** Fill opacity of a hovered bar when `showActiveBar` is on. */\nconst ACTIVE_BAR_FILL_OPACITY = 0.85;\n\n// Headroom for the caption a vertical reference rule hangs above the plot. Sized\n// to the 12px caption plus its descender, matching CHART_LABEL_MARGIN's top.\nconst REFERENCE_LABEL_MARGIN = { top: 16 } as const;\n\nexport interface ComposedSeries {\n /** Column key to plot — must match a `config` entry; drives its `--color-<key>` paint. */\n key: string;\n /** How this series renders. */\n type: ComposedSeriesType;\n /**\n * Which value axis this series is measured against. Defaults to `primary`.\n * The secondary axis is rendered only when at least one series selects it — use\n * it when a series carries a different unit or magnitude (a rate next to a\n * count) that a shared scale would flatten.\n */\n yAxis?: ChartYAxisTarget;\n /**\n * Paint for this series, overriding the stop of the container's `palette` it\n * would otherwise take. Reference an existing semantic `--ui-*` token.\n */\n color?: string;\n /**\n * Stack this series with every other series of the *same mark type* carrying\n * the same id. Bars stack with bars and areas with areas — the ids are\n * namespaced per type, so one id can't merge a bar into an area stack. Ignored\n * on a line series, which recharts does not stack.\n */\n stackId?: string;\n /** Interpolation, overriding the chart's `curve`. Line and area series only. */\n curve?: ComposedCurveType;\n /**\n * Stroke width, overriding the chart's `strokeWidth` on a line or area series.\n * On a bar it sizes the dashed outline `strokeDasharray` draws — a bar has no\n * other stroke, so the chart-level default never reaches one and this is the\n * only way to set it.\n */\n strokeWidth?: number;\n /**\n * Dash pattern for the stroke (an SVG `stroke-dasharray`, e.g. `'5 5'`) — the\n * conventional way to mark a series as a projection. On a bar series it draws a\n * dashed outline in the series colour.\n */\n strokeDasharray?: string;\n /** Render a dot at each point, overriding the chart's `showDots`. Line and area series only. */\n showDots?: boolean;\n /** Render the hover dot, overriding the chart's `showActiveDots`. Line and area series only. */\n showActiveDots?: boolean;\n /** Bridge `null` gaps instead of breaking the series, overriding `connectNulls`. */\n connectNulls?: boolean;\n /** Corner radius on the growing end, overriding the chart's `barRadius`. Bar series only. */\n barRadius?: number;\n /** Fixed bar thickness in px, overriding the chart's `barSize`. Bar series only. */\n barSize?: number;\n /** Highlight this bar on hover, overriding the chart's `showActiveBar`. Bar series only. */\n showActiveBar?: boolean;\n /** Draw a full-height track behind this series' bars, overriding `showBackground`. Bar series only. */\n showBackground?: boolean;\n /** Fill opacity, overriding the chart's `fillOpacity` (which applies to area series). */\n fillOpacity?: number;\n /** How this series is marked in the legend — `none` keeps it off the legend. */\n legendType?: ComposedSeriesLegendType;\n}\n\n/**\n * A dashed rule on the chart. Either a position on the *value* axis (a fixed\n * `value`, or the mean of one/every series via `average`) or, with `category`, a\n * rule across the *category* axis at one category — the \"today\" divider between\n * actuals and forecast. A value position wins if both are given.\n */\nexport interface ComposedChartReferenceLine extends ChartReferenceLine {\n /**\n * Category to draw the rule at — the category's own value (an `xKey` cell) or\n * its 0-based row index.\n */\n category?: string | number;\n /**\n * Which value axis the rule is measured against, on a chart carrying two.\n * Defaults to the axis of the series named by `average`, and to `primary`\n * otherwise — so a target read off the secondary scale lands on it rather\n * than being plotted against the primary one. `average: true` then pools only\n * the series on this axis, never two scales at once. Inert while no series\n * selects the secondary axis.\n */\n yAxis?: ChartYAxisTarget;\n}\n\n/** A shaded band behind a range of categories. */\nexport interface ComposedChartReferenceArea extends ChartCategoryRange {\n /** Caption above the band. */\n label?: string;\n}\n\nexport interface ComposedChartProps\n extends Omit<React.ComponentProps<'div'>, 'children'>,\n VariantProps<typeof composedChartVariants>,\n CartesianChartProps,\n SecondaryYAxisProps,\n ChartAnimationProps,\n ChartBrushProps,\n ChartDataLabelProps {\n /**\n * The dataviz palette this chart's series are painted from. Series that\n * state no `color` of their own take a stop of it. See `ChartPalette`.\n */\n palette?: ChartPalette;\n /** Row-per-category data. Each object holds `xKey` + one numeric field per series (`null` breaks a line/area unless `connectNulls`). */\n data: ReadonlyArray<Record<string, string | number | null>>;\n /**\n * Per-series map of `label` / `icon` / `tone`, keyed by `series[].key`\n * (imported from the shared `Chart` primitives). Turned into `--color-<key>`\n * custom properties. Series take their colour from the container's `palette`;\n * each entry maps a key to a `label` and an optional `tone`.\n */\n config: ChartConfig;\n /**\n * Series to plot, each `{ key, type }` plus any per-series style override —\n * one bar/line/area per entry. Each key must exist in `config` and every data\n * row. Every styling prop on the chart is the default a series overrides here.\n */\n series: ComposedSeries[];\n /** Category axis key (the shared dimension across rows, e.g. `\"month\"`). */\n xKey: string;\n /**\n * One or more dashed reference lines — on a value axis (`value` / `average`,\n * placed by the entry's `yAxis`) or across the category axis (`category`).\n * Pass a single object or an array.\n */\n referenceLine?: ComposedChartReferenceLine | ComposedChartReferenceLine[];\n /**\n * One or more shaded bands behind a range of categories — e.g. a forecast\n * period. Pass a single object or an array to draw several.\n */\n referenceArea?: ComposedChartReferenceArea | ComposedChartReferenceArea[];\n /** Unit suffix on the value-axis tick values when it is X (`orientation=\"horizontal\"`). */\n xUnit?: string;\n /** Interpolation for the line and area series. */\n curve?: ComposedCurveType;\n /** Corner radius on the growing end of bar series. */\n barRadius?: number;\n /** Fixed bar thickness, in px. Unset, recharts sizes bars from the available width. */\n barSize?: number;\n /** Gap between bars of the same category, in px or a percentage string. */\n barGap?: number | string;\n /** Gap between category groups, in px or a percentage string. */\n barCategoryGap?: number | string;\n /** Draw a full-height track behind every bar. */\n showBackground?: boolean;\n /** Fill for the track background. Defaults to the secondary surface. */\n backgroundFill?: string;\n /** Highlight the hovered bar. */\n showActiveBar?: boolean;\n /** Flat-fill opacity for area series. */\n fillOpacity?: number;\n /** Stroke width for the line series. Areas keep recharts' thinner outline unless set. */\n strokeWidth?: number;\n /** Render a dot at each point of the line and area series. */\n showDots?: boolean;\n /** Render the hover dot on the line and area series. Unset, recharts' own default applies. */\n showActiveDots?: boolean;\n /** Bridge `null` gaps in the data instead of breaking the line/area. */\n connectNulls?: boolean;\n /** Plot-area inset. Any side left out keeps the chart's own default. */\n margin?: ComposedChartMargin;\n /** Draw the hover cursor (the band/rule under the tooltip). Defaults to `true`. */\n tooltipCursor?: boolean;\n showLegend?: boolean;\n /** Which edge the legend sits on. Defaults to `bottom`. */\n legendPosition?: 'top' | 'bottom';\n /**\n * Position of the value labels when `showLabels` is on. Defaults to each\n * series' growing end — `top` (or `right` when horizontal), and the centre of\n * a stacked segment, which has no free space at its end.\n */\n labelPosition?: CartesianLabelPosition;\n}\n\n// recharts types a legend's `content` as an element *or* a render function.\n// Naming that union is what lets the content be built above the returned tree\n// (see `legendContent`) without hand-typing the props the render form is given.\ntype LegendContentType = NonNullable<\n React.ComponentProps<typeof ChartLegend>['content']\n>;\n\nconst ComposedChart = React.forwardRef<HTMLDivElement, ComposedChartProps>(\n (\n {\n className,\n config,\n palette,\n data,\n series,\n xKey,\n referenceLine,\n referenceArea,\n orientation = 'vertical',\n xAxisLabel,\n yAxisLabel,\n xUnit,\n yUnit,\n curve = 'monotone',\n barRadius = 4,\n barSize,\n barGap,\n barCategoryGap,\n showBackground = false,\n backgroundFill = 'var(--ui-background-surface-secondary)',\n showActiveBar = false,\n fillOpacity = 0.3,\n strokeWidth,\n showDots = false,\n showActiveDots,\n connectNulls = false,\n margin,\n showGrid = true,\n showTooltip = true,\n tooltipCursor = true,\n showLegend = true,\n legendPosition = 'bottom',\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n yAxisOrientation,\n showSecondaryYAxis = true,\n secondaryYAxisLabel,\n secondaryYUnit,\n secondaryYTickFormatter,\n secondaryYAxisTickCount,\n secondaryYAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n showLabels = false,\n labelPosition,\n labelFormatter,\n showBrush = false,\n brushHeight,\n brushAriaLabel,\n ...props\n },\n ref\n ) => {\n const animation = resolveAnimation({\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n });\n // Our `orientation` is the direction the marks grow; recharts' `layout` is\n // the opposite axis. Horizontal puts the categories on Y and the values on X,\n // which re-roles every axis prop below.\n const isHorizontal = orientation === 'horizontal';\n // Axis titles: the X title sits below the ticks; the Y title is rotated in\n // the side gutter. Passed to recharts' native `label` (themed via the\n // `.recharts-label` fill selector on the container).\n const xAxisTitle = resolveXAxisTitle(xAxisLabel);\n // The secondary axis is derived from the series, not from a flag of its own:\n // that keeps a series from pointing at an id no axis declares, where recharts\n // falls back to an implicit axis — the series still scales off its own data, but\n // silently loses the domain/tickCount/formatter/unit that axis was configured\n // with, and renders no chrome for it.\n const hasSecondaryValueAxis = series.some((s) => s.yAxis === 'secondary');\n // The mirror case the `series` opt-in can't rule out on its own: every series\n // asks for the secondary axis, leaving the primary one with nothing measured\n // against it. recharts gives an axis with no graphical items no ticks at all, so\n // it paints a blank gutter and `CartesianGrid` — which follows it — collapses to\n // the two plot boundaries. Hand the gutter and the grid to the axis that does\n // have the series. Both conditionals are inert on every other chart shape, so\n // single-axis output is untouched.\n const hasPrimarySeries = series.some((s) => s.yAxis !== 'secondary');\n const primaryValueAxisIsOrphaned = hasSecondaryValueAxis && !hasPrimarySeries;\n const primaryOrientation = yAxisOrientation ?? 'left';\n const secondaryOrientation = primaryOrientation === 'left' ? 'right' : 'left';\n\n // The category axis is pinned to the left when the marks grow horizontally,\n // so its title is angled for that side whatever `yAxisOrientation` says.\n const yAxisTitle = resolveYAxisTitle(\n yAxisLabel,\n isHorizontal ? 'left' : primaryOrientation\n );\n const secondaryYAxisTitle = resolveYAxisTitle(\n secondaryYAxisLabel,\n secondaryOrientation\n );\n // Horizontal puts the second scale on a top X axis, where a rotated title\n // would read sideways over the plot.\n const secondaryXAxisTitle = resolveXAxisTitle(\n secondaryYAxisLabel,\n 'insideTop'\n );\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n const secondaryYDomain = resolveAxisDomain(secondaryYAxisDomain);\n\n // Which axis a series (or the grid, or a reference element) binds to. The\n // value axis is Y by default and X when horizontal; the primary one keeps\n // recharts' implicit id `0` — `resolveDefaultProps` fills the `undefined` in —\n // so a series that opts out of the secondary axis passes exactly what it\n // passed before that axis existed.\n const valueAxisBinding = (target: ChartYAxisTarget | undefined) => {\n const id = target === 'secondary' ? SECONDARY_VALUE_AXIS_ID : undefined;\n return isHorizontal ? { xAxisId: id } : { yAxisId: id };\n };\n // Spread (rather than passed as an `undefined` prop) so the primary case\n // reorders nothing: see the `orientation` note on the primary axis below.\n const orphanedAxisBinding = primaryValueAxisIsOrphaned\n ? valueAxisBinding('secondary')\n : {};\n\n const xAxisTickLabels = resolveXAxisTickLabels(\n isHorizontal\n ? []\n : data.map((row) => row[xKey]),\n xTickFormatter\n );\n const chartContainerRef = React.useRef<HTMLDivElement>(null);\n const xAxisLayout = useXAxisLayout(\n chartContainerRef,\n xAxisAngle,\n xAxisLabel,\n xAxisTickLabels.join('\\u0000')\n );\n\n const referenceLines = referenceLine\n ? Array.isArray(referenceLine)\n ? referenceLine\n : [referenceLine]\n : [];\n const referenceAreas = (\n referenceArea\n ? Array.isArray(referenceArea)\n ? referenceArea\n : [referenceArea]\n : []\n )\n .map((area) => ({ area, range: resolveCategoryRange(area, data, xKey) }))\n .filter(\n (\n entry\n ): entry is { area: ComposedChartReferenceArea; range: [number, number] } =>\n entry.range !== undefined\n );\n // A reference rule belongs to one scale, so both halves of it — which keys\n // an `average` pools, and which axis the result is plotted against — have to\n // agree. When the primary axis is orphaned every series is on the secondary\n // one, so that becomes the default rather than leaving `average: true` with\n // an empty key set.\n const defaultReferenceAxis: ChartYAxisTarget = primaryValueAxisIsOrphaned\n ? 'secondary'\n : 'primary';\n const seriesAxisOf = (s: ComposedSeries) => s.yAxis ?? 'primary';\n const seriesAxisByKey = new Map(series.map((s) => [s.key, seriesAxisOf(s)]));\n const seriesKeysOn = (target: ChartYAxisTarget) =>\n series.filter((s) => seriesAxisOf(s) === target).map((s) => s.key);\n const hiddenLegendKeys = new Set(\n series.filter((s) => s.legendType === 'none').map((s) => s.key)\n );\n // The axis position a band/rule is placed at. `?? undefined` because a row\n // whose category cell is null has no position on the axis — recharts types\n // its reference coordinates as `string | number`.\n const categoryAt = (row: number) => data[row]?.[xKey] ?? undefined;\n\n // Resolved up here, not inside the map, because the plot margin below has to\n // know whether any rule will hang a caption above the plot.\n const resolvedReferenceLines = referenceLines\n .map((line) => {\n // A category rule is placed by the category's own value, so an index\n // bound is resolved back to it first.\n const categoryRange =\n line.category !== undefined\n ? resolveCategoryRange(\n { from: line.category, to: line.category },\n data,\n xKey\n )\n : undefined;\n // An `average` naming one series is read off that series' own scale\n // unless the caller says otherwise; anything else falls back to the\n // chart's default axis.\n const lineAxis =\n line.yAxis ??\n (typeof line.average === 'string'\n ? (seriesAxisByKey.get(line.average) ?? defaultReferenceAxis)\n : defaultReferenceAxis);\n const value = resolveChartReferenceValue(line, data, seriesKeysOn(lineAxis));\n const category = categoryRange\n ? categoryAt(categoryRange[0])\n : undefined;\n // The value position wins when both are given; a category that resolves\n // to nothing (an unknown bound) draws no rule.\n const position =\n value !== undefined\n ? isHorizontal\n ? { x: value }\n : { y: value }\n : category !== undefined\n ? isHorizontal\n ? { y: category }\n : { x: category }\n : undefined;\n // A value rule runs across the value axis, so it is drawn vertical\n // exactly when the values are on X — and a category rule the other way\n // round.\n const isVerticalRule = (value !== undefined) === isHorizontal;\n return { line, lineAxis, position, isVerticalRule };\n })\n .filter(\n (\n entry\n ): entry is typeof entry & { position: Record<string, string | number> } =>\n entry.position !== undefined\n );\n\n // Line/area series don't clamp their labels to the plot (see\n // CHART_LABEL_MARGIN); a composed chart can hold either. A caller-supplied\n // margin overrides that per side rather than replacing it, so asking for one\n // wider gutter can't silently drop the label headroom.\n const labelMargin = showLabels ? CHART_LABEL_MARGIN : undefined;\n // A vertical rule hangs its caption off the top end, outside the plot, where\n // recharts' 5px inset clips it — the same headroom problem CHART_LABEL_MARGIN\n // solves for data labels, so it is reserved the same way rather than left for\n // the caller to discover and pass a `margin` for.\n const referenceLabelMargin = resolvedReferenceLines.some(\n (entry) => entry.line.label && entry.isVerticalRule\n )\n ? REFERENCE_LABEL_MARGIN\n : undefined;\n const baseMargin =\n margin || labelMargin || referenceLabelMargin\n ? {\n ...(margin ? DEFAULT_CHART_MARGIN : {}),\n ...referenceLabelMargin,\n ...labelMargin,\n ...margin,\n }\n : undefined;\n const resolvedMargin = mergeXAxisLayoutMargin(baseMargin, xAxisLayout.margin);\n\n // Only the segment at the growing end of a stack rounds its corners — the\n // ones below it butt against the next segment.\n const lastIndexInStack = new Map<string, number>();\n series.forEach((s, index) => {\n if (s.stackId && s.type !== 'line') {\n lastIndexInStack.set(`${s.type}-${s.stackId}`, index);\n }\n });\n\n // Everything from here to the `return` is lifted out of the returned tree\n // only to keep it readable as a flat list of chart children. Nothing in\n // recharts forces the `render*` helpers to be plain functions: axes and\n // series register themselves with the chart's store, and `<Cell>` is the\n // only child still looked up by element type — a component wrapper renders\n // fine (see AreaChart's `AreaFillGradients`). They stay functions because\n // they are declared inside the render body, where a component would get a\n // fresh element type on every render and remount its subtree.\n\n // The two orientations stay two whole blocks rather than one parameterised\n // axis pair: they swap which axis is `type=\"number\"` and which carries the\n // categories, and they differ in props recharts treats as present-but-\n // undefined vs absent (see the `orientation` note below), which a shared\n // element would have to reintroduce prop by prop anyway.\n\n // Horizontal marks put the values on X, so the value-axis props\n // (unit/tickCount/domain) belong on the X axis here — recharts ignores them\n // on the category axis.\n const renderHorizontalAxes = () => (\n <>\n <XAxis\n type=\"number\"\n hide={!showXAxis || primaryValueAxisIsOrphaned}\n tickLine={false}\n axisLine={false}\n unit={xUnit}\n tickFormatter={xTickFormatter}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n tickCount={yAxisTickCount}\n domain={yDomain}\n height={xAxisLayout.height}\n label={xAxisTitle}\n />\n <YAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showYAxis}\n // `yAxisOrientation` picks the side of the *value* axis, which\n // is X here — a left/right choice it has no room for, and one\n // the secondary axis already spends on the top edge. Moving the\n // category axis with it instead would satisfy the prop name and\n // break its contract, so it stays inert in this orientation.\n tickLine={false}\n axisLine={false}\n tickFormatter={yTickFormatter}\n width={yAxisLabel ? 96 : 80}\n label={yAxisTitle}\n />\n {hasSecondaryValueAxis && (\n <XAxis\n xAxisId={SECONDARY_VALUE_AXIS_ID}\n type=\"number\"\n hide={!showSecondaryYAxis}\n orientation=\"top\"\n tickLine={false}\n axisLine={false}\n unit={secondaryYUnit}\n tickFormatter={secondaryYTickFormatter}\n tickCount={secondaryYAxisTickCount}\n domain={secondaryYDomain}\n label={secondaryXAxisTitle}\n />\n )}\n </>\n );\n\n const renderVerticalAxes = () => (\n <>\n <XAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n height={xAxisLayout.height}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n hide={!showYAxis || primaryValueAxisIsOrphaned}\n // Spread only when set. `orientation={undefined}` would resolve to the\n // same `left`, but the key's presence moves it ahead of `width` in the\n // props object recharts spreads onto its tick labels — reordering the\n // SVG attributes of every existing chart for no functional gain.\n {...(yAxisOrientation ? { orientation: yAxisOrientation } : {})}\n tickLine={false}\n axisLine={false}\n unit={yUnit}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n {hasSecondaryValueAxis && (\n <YAxis\n yAxisId={SECONDARY_VALUE_AXIS_ID}\n type=\"number\"\n hide={!showSecondaryYAxis}\n orientation={secondaryOrientation}\n tickLine={false}\n axisLine={false}\n unit={secondaryYUnit}\n tickFormatter={secondaryYTickFormatter}\n tickCount={secondaryYAxisTickCount}\n domain={secondaryYDomain}\n width={secondaryYAxisLabel ? 72 : undefined}\n label={secondaryYAxisTitle}\n />\n )}\n </>\n );\n\n // recharts keeps a `legendType=\"none\"` series in the legend payload (it only\n // drops its icon), so hiding an entry is this filter's job — the same guard\n // `BarChart` applies to its synthetic series. Only wired up when a series\n // asks for it, so every other chart keeps the plain content element.\n const legendContent: LegendContentType =\n hiddenLegendKeys.size > 0\n ? (legendProps) => (\n <ChartLegendContent\n verticalAlign={legendPosition}\n payload={\n legendProps.payload?.filter(\n (item) => !hiddenLegendKeys.has(String(item.dataKey))\n ) as ChartLegendContentProps['payload']\n }\n />\n )\n : <ChartLegendContent verticalAlign={legendPosition} />;\n\n const renderSeries = (s: ComposedSeries, index: number) => {\n const color = s.color ?? `var(--color-${toCssKey(s.key)})`;\n const zIndex = SERIES_Z_INDEX_BASE + index;\n const axisBinding = valueAxisBinding(s.yAxis);\n const stackId =\n s.stackId && s.type !== 'line' ? `${s.type}-${s.stackId}` : undefined;\n const seriesFillOpacity = s.fillOpacity ?? fillOpacity;\n const seriesConnectNulls = s.connectNulls ?? connectNulls;\n const seriesShowDots = s.showDots ?? showDots;\n const seriesShowActiveDots = s.showActiveDots ?? showActiveDots;\n const seriesLegendType = s.legendType ? { legendType: s.legendType } : {};\n // A stacked segment has no free space at its growing end (the next\n // segment is drawn there), so its labels centre in their own\n // segment instead.\n const seriesLabelPosition = resolveCartesianLabelPosition({\n labelPosition,\n isStacked: stackId !== undefined,\n growingEnd: isHorizontal ? 'right' : 'top',\n });\n const label = showLabels ? (\n <LabelList\n dataKey={s.key}\n position={seriesLabelPosition}\n formatter={toLabelFormatter(labelFormatter)}\n className={resolveLabelFillClass(seriesLabelPosition, {\n translucentSeries: s.type === 'area',\n })}\n fontSize={CHART_LABEL_FONT_SIZE}\n />\n ) : null;\n\n if (s.type === 'bar') {\n const radius = s.barRadius ?? barRadius;\n const rounded =\n stackId === undefined || lastIndexInStack.get(stackId) === index;\n const barBackground = s.showBackground ?? showBackground;\n // recharts spreads the active option over the bar's own props, so\n // an explicit `undefined` fill would wipe the series color (an\n // unfilled path paints black) — only dim it.\n const barActive = s.showActiveBar ?? showActiveBar;\n return (\n <Bar\n key={s.key}\n dataKey={s.key}\n {...axisBinding}\n fill={color}\n radius={\n radius > 0 && rounded\n ? isHorizontal\n ? [0, radius, radius, 0]\n : [radius, radius, 0, 0]\n : undefined\n }\n zIndex={zIndex}\n {...(stackId ? { stackId } : {})}\n {...(s.barSize !== undefined ? { barSize: s.barSize } : {})}\n {...(s.fillOpacity !== undefined\n ? { fillOpacity: s.fillOpacity }\n : {})}\n // A bar has no outline of its own, so a dash pattern brings\n // one with it — in the series colour, at the series' stroke\n // width if it set one.\n {...(s.strokeDasharray !== undefined\n ? {\n stroke: color,\n strokeDasharray: s.strokeDasharray,\n ...(s.strokeWidth !== undefined\n ? { strokeWidth: s.strokeWidth }\n : {}),\n }\n : {})}\n {...(barBackground ? { background: { fill: backgroundFill } } : {})}\n {...(barActive\n ? { activeBar: { fillOpacity: ACTIVE_BAR_FILL_OPACITY } }\n : {})}\n {...seriesLegendType}\n {...animation}\n >\n {label}\n </Bar>\n );\n }\n if (s.type === 'area') {\n const width = s.strokeWidth ?? strokeWidth;\n const areaStrokeWidth =\n width !== undefined ? { strokeWidth: width } : {};\n return (\n <Area\n key={s.key}\n type={s.curve ?? curve}\n dataKey={s.key}\n {...axisBinding}\n stroke={color}\n fill={color}\n fillOpacity={seriesFillOpacity}\n zIndex={zIndex}\n {...(stackId ? { stackId } : {})}\n // Areas keep recharts' own thinner outline unless a width is\n // asked for: the chart-level default exists for the lines,\n // where 2px is this suite's stroke.\n {...areaStrokeWidth}\n {...(s.strokeDasharray !== undefined\n ? { strokeDasharray: s.strokeDasharray }\n : {})}\n dot={seriesShowDots ? { r: 3 } : false}\n {...(seriesShowActiveDots !== undefined\n ? { activeDot: seriesShowActiveDots ? { r: 5 } : false }\n : {})}\n connectNulls={seriesConnectNulls}\n {...seriesLegendType}\n {...animation}\n >\n {label}\n </Area>\n );\n }\n return (\n <Line\n key={s.key}\n type={s.curve ?? curve}\n dataKey={s.key}\n {...axisBinding}\n stroke={color}\n strokeWidth={s.strokeWidth ?? strokeWidth ?? 2}\n dot={seriesShowDots ? { r: 3 } : false}\n zIndex={zIndex}\n {...(s.strokeDasharray !== undefined\n ? { strokeDasharray: s.strokeDasharray }\n : {})}\n {...(seriesShowActiveDots !== undefined\n ? { activeDot: seriesShowActiveDots ? { r: 5 } : false }\n : {})}\n connectNulls={seriesConnectNulls}\n {...seriesLegendType}\n {...animation}\n >\n {label}\n </Line>\n );\n };\n\n const renderReferenceArea = (\n { area, range }: (typeof referenceAreas)[number],\n index: number\n ) => {\n const [start, end] = range;\n return (\n <ReferenceArea\n key={`${area.label ?? 'area'}-${index}`}\n {...orphanedAxisBinding}\n // Bands run along the category axis: X by default, Y when the\n // marks grow horizontally.\n {...(isHorizontal\n ? { y1: categoryAt(start), y2: categoryAt(end) }\n : { x1: categoryAt(start), x2: categoryAt(end) })}\n fill=\"var(--ui-background-surface-secondary)\"\n fillOpacity={0.6}\n zIndex={REFERENCE_AREA_Z_INDEX}\n ifOverflow=\"extendDomain\"\n label={\n area.label\n ? {\n value: area.label,\n position: 'insideTop',\n fill: 'var(--ui-text-on-surface-secondary)',\n fontSize: 12,\n }\n : undefined\n }\n />\n );\n };\n\n const renderReferenceLine = (\n {\n line,\n lineAxis,\n position,\n isVerticalRule,\n }: (typeof resolvedReferenceLines)[number],\n index: number\n ) => (\n <ReferenceLine\n key={`${line.label ?? 'ref'}-${index}`}\n // Binding to an id no axis declares makes recharts invent an\n // implicit one (see `hasSecondaryValueAxis`), so the request is\n // only honored once a series has brought that axis into being.\n {...(lineAxis === 'secondary' && hasSecondaryValueAxis\n ? valueAxisBinding('secondary')\n : {})}\n {...position}\n // Caption at the top of the rule by default: above the right\n // end of a horizontal one, above the top of a vertical one\n // (which the plot margin reserves room for — see\n // REFERENCE_LABEL_MARGIN). A config's own `labelPosition`\n // overrides that, as on the other cartesian charts.\n {...resolveReferenceLineProps(\n line.label,\n line.labelPosition ?? (isVerticalRule ? 'top' : 'insideTopRight')\n )}\n />\n );\n\n return (\n <div\n ref={ref}\n data-orientation={orientation}\n className={cn(composedChartVariants({ orientation }), className)}\n {...props}\n >\n <ChartContainer\n ref={chartContainerRef}\n config={config}\n palette={palette}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <RechartsComposedChart\n data={data as readonly unknown[]}\n layout={isHorizontal ? 'vertical' : 'horizontal'}\n barSize={barSize}\n barGap={barGap}\n barCategoryGap={barCategoryGap}\n margin={resolvedMargin}\n >\n {showGrid && (\n <CartesianGrid\n // Spread only when the primary axis has no series (see above) —\n // an explicit `undefined` id resolves to the same `0` but\n // reorders the grid's SVG attributes on every existing chart.\n {...orphanedAxisBinding}\n horizontal={gridHorizontal ?? !isHorizontal}\n vertical={gridVertical ?? isHorizontal}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n {isHorizontal ? renderHorizontalAxes() : renderVerticalAxes()}\n {showTooltip && (\n <ChartTooltip\n {...(tooltipCursor ? {} : { cursor: false })}\n content={tooltipContent ?? <ChartTooltipContent />}\n />\n )}\n {showLegend && (\n <ChartLegend\n verticalAlign={legendPosition}\n content={legendContent}\n />\n )}\n {/* Rendered back-to-front in the caller's `series` order — later\n entries sit on top. Order them so thin marks (a line) come after\n the areas/bars they should overlay. */}\n {series.map(renderSeries)}\n {referenceAreas.map(renderReferenceArea)}\n {resolvedReferenceLines.map(renderReferenceLine)}\n {showBrush && (\n <Brush\n dataKey={xKey}\n // The brush slices rows by index, so its captions come from\n // whichever axis holds the categories — Y when horizontal.\n tickFormatter={isHorizontal ? yTickFormatter : xTickFormatter}\n {...resolveBrushProps({ brushHeight, brushAriaLabel })}\n />\n )}\n </RechartsComposedChart>\n </ChartContainer>\n </div>\n );\n }\n);\nComposedChart.displayName = 'ComposedChart';\n\nexport { ComposedChart, composedChartVariants };\n"],"mappings":"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"}
1
+ {"version":3,"file":"composed-chart.js","names":[],"sources":["../../../../src/components/ui/composed-chart/composed-chart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n Area,\n Bar,\n Brush,\n CartesianGrid,\n ComposedChart as RechartsComposedChart,\n LabelList,\n Line,\n ReferenceArea,\n ReferenceLine,\n XAxis,\n YAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n CHART_LABEL_FONT_SIZE,\n CHART_LABEL_MARGIN,\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAnimation,\n resolveAxisDomain,\n resolveBrushProps,\n resolveCartesianLabelPosition,\n resolveCategoryRange,\n resolveChartReferenceValue,\n resolveLabelFillClass,\n resolveReferenceLineProps,\n resolveRotatedTickAnchor,\n resolveXAxisTitle,\n resolveYAxisTitle,\n toLabelFormatter,\n toCssKey,\n type ChartConfig,\n type ChartLegendFontSize,\n type ChartPalette,\n type ChartLegendContentProps,\n type CartesianChartProps,\n type ChartAnimationProps,\n type ChartBrushProps,\n type ChartCategoryRange,\n type ChartDataLabelProps,\n type ChartReferenceLine,\n type CartesianLabelPosition,\n type ChartYAxisTarget,\n type SecondaryYAxisProps,\n} from '../chart';\nimport {\n mergeXAxisLayoutMargin,\n useXAxisLayout,\n} from '../chart/use-x-axis-layout';\nimport { resolveXAxisTickLabels } from '../chart/chart-format';\n\n// A typed recharts composition over the shared `Chart` primitives. A composed\n// chart's defining trait is that each series picks its own render type\n// (bar / line / area) over one shared category axis, so the mark mix is not a\n// variant — it lives in the `series[].type` list. `orientation` is: it is the\n// same one-axis choice `BarChart` models (which way the marks grow), and it\n// re-roles both axes. The class stays empty because the recharts SVG — not CSS —\n// draws the series; CVA is kept so the variant set is a first-class,\n// spec-conformant part of the API (matched against ui-spec's api.yaml enums) and\n// exposed via `VariantProps`. The resolved value is mirrored onto\n// `data-orientation` for styling hooks and tests.\nconst composedChartVariants = cva('', {\n variants: {\n orientation: {\n vertical: '',\n horizontal: '',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n});\n\nexport type ComposedSeriesType = 'bar' | 'line' | 'area';\n\n/** Interpolation for a line or area series. */\nexport type ComposedCurveType = 'linear' | 'monotone' | 'step';\n\n/**\n * How a series is marked in the legend. Deliberately narrower than recharts'\n * icon set: `ChartLegendContent` draws its own marker and reads only whether the\n * entry is a `line` (a rule, dashed when the series is) or anything else (a\n * swatch), so the wider union would advertise icons that never render. `none`\n * keeps the series off the legend entirely.\n */\nexport type ComposedSeriesLegendType = 'line' | 'rect' | 'none';\n\n/** Plot-area inset, in px. Any side left out keeps the chart's own default. */\nexport interface ComposedChartMargin {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\n// recharts 3 paints graphical items into z-index layers keyed by their *type*\n// (Area 100, Bar 300, Line 400), so JSX order alone decides nothing across\n// types — an area would always sit under the bars however the caller ordered\n// `series`. Giving each entry an explicit z-index from its index restores\n// \"later entry paints on top\". The band stays under the axis layer (500).\nconst SERIES_Z_INDEX_BASE = 100;\n\n// A reference band is a backdrop, so it has to sit under the marks. That is\n// recharts' own arrangement (its band defaults to 100, below Bar's 300), but\n// pulling the series down into the 100s to order them by array index lands them\n// on the band's layer — where the band, rendered later, would paint over them.\n// Below the series and above the grid (-100) restores the intent. A reference\n// *line* keeps its own default (400): a rule reads as an annotation on top.\nconst REFERENCE_AREA_Z_INDEX = 50;\n\n// recharts keys every axis by id, defaulting to `0` on both the axis and each\n// graphical item. The primary value axis keeps that implicit id rather than\n// taking an explicit one, so a chart with no secondary series renders\n// byte-identically — and `CartesianGrid` (whose own ids default to `0`) keeps\n// drawing its lines against the primary scale, which is the only readable\n// choice: gridlines from two different scales would cross at meaningless\n// heights.\nconst SECONDARY_VALUE_AXIS_ID = 'secondary';\n\n// recharts' own plot inset, spelled out so a caller-supplied `margin` can\n// override one side without erasing the other three.\nconst DEFAULT_CHART_MARGIN = { top: 5, right: 5, bottom: 5, left: 5 } as const;\n\n/** Fill opacity of a hovered bar when `showActiveBar` is on. */\nconst ACTIVE_BAR_FILL_OPACITY = 0.85;\n\n// Headroom for the caption a vertical reference rule hangs above the plot. Sized\n// to the 12px caption plus its descender, matching CHART_LABEL_MARGIN's top.\nconst REFERENCE_LABEL_MARGIN = { top: 16 } as const;\n\nexport interface ComposedSeries {\n /** Column key to plot — must match a `config` entry; drives its `--color-<key>` paint. */\n key: string;\n /** How this series renders. */\n type: ComposedSeriesType;\n /**\n * Which value axis this series is measured against. Defaults to `primary`.\n * The secondary axis is rendered only when at least one series selects it — use\n * it when a series carries a different unit or magnitude (a rate next to a\n * count) that a shared scale would flatten.\n */\n yAxis?: ChartYAxisTarget;\n /**\n * Paint for this series, overriding the stop of the container's `palette` it\n * would otherwise take. Reference an existing semantic `--ui-*` token.\n */\n color?: string;\n /**\n * Stack this series with every other series of the *same mark type* carrying\n * the same id. Bars stack with bars and areas with areas — the ids are\n * namespaced per type, so one id can't merge a bar into an area stack. Ignored\n * on a line series, which recharts does not stack.\n */\n stackId?: string;\n /** Interpolation, overriding the chart's `curve`. Line and area series only. */\n curve?: ComposedCurveType;\n /**\n * Stroke width, overriding the chart's `strokeWidth` on a line or area series.\n * On a bar it sizes the dashed outline `strokeDasharray` draws — a bar has no\n * other stroke, so the chart-level default never reaches one and this is the\n * only way to set it.\n */\n strokeWidth?: number;\n /**\n * Dash pattern for the stroke (an SVG `stroke-dasharray`, e.g. `'5 5'`) — the\n * conventional way to mark a series as a projection. On a bar series it draws a\n * dashed outline in the series colour.\n */\n strokeDasharray?: string;\n /** Render a dot at each point, overriding the chart's `showDots`. Line and area series only. */\n showDots?: boolean;\n /** Render the hover dot, overriding the chart's `showActiveDots`. Line and area series only. */\n showActiveDots?: boolean;\n /** Bridge `null` gaps instead of breaking the series, overriding `connectNulls`. */\n connectNulls?: boolean;\n /** Corner radius on the growing end, overriding the chart's `barRadius`. Bar series only. */\n barRadius?: number;\n /** Fixed bar thickness in px, overriding the chart's `barSize`. Bar series only. */\n barSize?: number;\n /** Highlight this bar on hover, overriding the chart's `showActiveBar`. Bar series only. */\n showActiveBar?: boolean;\n /** Draw a full-height track behind this series' bars, overriding `showBackground`. Bar series only. */\n showBackground?: boolean;\n /** Fill opacity, overriding the chart's `fillOpacity` (which applies to area series). */\n fillOpacity?: number;\n /** How this series is marked in the legend — `none` keeps it off the legend. */\n legendType?: ComposedSeriesLegendType;\n}\n\n/**\n * A dashed rule on the chart. Either a position on the *value* axis (a fixed\n * `value`, or the mean of one/every series via `average`) or, with `category`, a\n * rule across the *category* axis at one category — the \"today\" divider between\n * actuals and forecast. A value position wins if both are given.\n */\nexport interface ComposedChartReferenceLine extends ChartReferenceLine {\n /**\n * Category to draw the rule at — the category's own value (an `xKey` cell) or\n * its 0-based row index.\n */\n category?: string | number;\n /**\n * Which value axis the rule is measured against, on a chart carrying two.\n * Defaults to the axis of the series named by `average`, and to `primary`\n * otherwise — so a target read off the secondary scale lands on it rather\n * than being plotted against the primary one. `average: true` then pools only\n * the series on this axis, never two scales at once. Inert while no series\n * selects the secondary axis.\n */\n yAxis?: ChartYAxisTarget;\n}\n\n/** A shaded band behind a range of categories. */\nexport interface ComposedChartReferenceArea extends ChartCategoryRange {\n /** Caption above the band. */\n label?: string;\n}\n\nexport interface ComposedChartProps\n extends Omit<React.ComponentProps<'div'>, 'children'>,\n VariantProps<typeof composedChartVariants>,\n CartesianChartProps,\n SecondaryYAxisProps,\n ChartAnimationProps,\n ChartBrushProps,\n ChartDataLabelProps {\n /**\n * The dataviz palette this chart's series are painted from. Series that\n * state no `color` of their own take a stop of it. See `ChartPalette`.\n */\n palette?: ChartPalette;\n /** Row-per-category data. Each object holds `xKey` + one numeric field per series (`null` breaks a line/area unless `connectNulls`). */\n data: ReadonlyArray<Record<string, string | number | null>>;\n /**\n * Per-series map of `label` / `icon` / `tone`, keyed by `series[].key`\n * (imported from the shared `Chart` primitives). Turned into `--color-<key>`\n * custom properties. Series take their colour from the container's `palette`;\n * each entry maps a key to a `label` and an optional `tone`.\n */\n config: ChartConfig;\n /**\n * Series to plot, each `{ key, type }` plus any per-series style override —\n * one bar/line/area per entry. Each key must exist in `config` and every data\n * row. Every styling prop on the chart is the default a series overrides here.\n */\n series: ComposedSeries[];\n /** Category axis key (the shared dimension across rows, e.g. `\"month\"`). */\n xKey: string;\n /**\n * One or more dashed reference lines — on a value axis (`value` / `average`,\n * placed by the entry's `yAxis`) or across the category axis (`category`).\n * Pass a single object or an array.\n */\n referenceLine?: ComposedChartReferenceLine | ComposedChartReferenceLine[];\n /**\n * One or more shaded bands behind a range of categories — e.g. a forecast\n * period. Pass a single object or an array to draw several.\n */\n referenceArea?: ComposedChartReferenceArea | ComposedChartReferenceArea[];\n /** Unit suffix on the value-axis tick values when it is X (`orientation=\"horizontal\"`). */\n xUnit?: string;\n /** Interpolation for the line and area series. */\n curve?: ComposedCurveType;\n /** Corner radius on the growing end of bar series. */\n barRadius?: number;\n /** Fixed bar thickness, in px. Unset, recharts sizes bars from the available width. */\n barSize?: number;\n /** Gap between bars of the same category, in px or a percentage string. */\n barGap?: number | string;\n /** Gap between category groups, in px or a percentage string. */\n barCategoryGap?: number | string;\n /** Draw a full-height track behind every bar. */\n showBackground?: boolean;\n /** Fill for the track background. Defaults to the secondary surface. */\n backgroundFill?: string;\n /** Highlight the hovered bar. */\n showActiveBar?: boolean;\n /** Flat-fill opacity for area series. */\n fillOpacity?: number;\n /** Stroke width for the line series. Areas keep recharts' thinner outline unless set. */\n strokeWidth?: number;\n /** Render a dot at each point of the line and area series. */\n showDots?: boolean;\n /** Render the hover dot on the line and area series. Unset, recharts' own default applies. */\n showActiveDots?: boolean;\n /** Bridge `null` gaps in the data instead of breaking the line/area. */\n connectNulls?: boolean;\n /** Plot-area inset. Any side left out keeps the chart's own default. */\n margin?: ComposedChartMargin;\n /** Draw the hover cursor (the band/rule under the tooltip). Defaults to `true`. */\n tooltipCursor?: boolean;\n showLegend?: boolean;\n /** Which edge the legend sits on. Defaults to `bottom`. */\n legendPosition?: 'top' | 'bottom';\n /**\n * Font size of the legend text. Defaults to `'xs'` — the size the legend has\n * always rendered at. See `ChartLegendFontSize`.\n */\n legendFontSize?: ChartLegendFontSize;\n /**\n * Position of the value labels when `showLabels` is on. Defaults to each\n * series' growing end — `top` (or `right` when horizontal), and the centre of\n * a stacked segment, which has no free space at its end.\n */\n labelPosition?: CartesianLabelPosition;\n}\n\n// recharts types a legend's `content` as an element *or* a render function.\n// Naming that union is what lets the content be built above the returned tree\n// (see `legendContent`) without hand-typing the props the render form is given.\ntype LegendContentType = NonNullable<\n React.ComponentProps<typeof ChartLegend>['content']\n>;\n\nconst ComposedChart = React.forwardRef<HTMLDivElement, ComposedChartProps>(\n (\n {\n className,\n config,\n palette,\n data,\n series,\n xKey,\n referenceLine,\n referenceArea,\n orientation = 'vertical',\n xAxisLabel,\n yAxisLabel,\n xUnit,\n yUnit,\n curve = 'monotone',\n barRadius = 4,\n barSize,\n barGap,\n barCategoryGap,\n showBackground = false,\n backgroundFill = 'var(--ui-background-surface-secondary)',\n showActiveBar = false,\n fillOpacity = 0.3,\n strokeWidth,\n showDots = false,\n showActiveDots,\n connectNulls = false,\n margin,\n showGrid = true,\n showTooltip = true,\n tooltipCursor = true,\n showLegend = true,\n legendPosition = 'bottom',\n legendFontSize,\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n yAxisOrientation,\n showSecondaryYAxis = true,\n secondaryYAxisLabel,\n secondaryYUnit,\n secondaryYTickFormatter,\n secondaryYAxisTickCount,\n secondaryYAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n showLabels = false,\n labelPosition,\n labelFormatter,\n showBrush = false,\n brushHeight,\n brushAriaLabel,\n ...props\n },\n ref\n ) => {\n const animation = resolveAnimation({\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n });\n // Our `orientation` is the direction the marks grow; recharts' `layout` is\n // the opposite axis. Horizontal puts the categories on Y and the values on X,\n // which re-roles every axis prop below.\n const isHorizontal = orientation === 'horizontal';\n // Axis titles: the X title sits below the ticks; the Y title is rotated in\n // the side gutter. Passed to recharts' native `label` (themed via the\n // `.recharts-label` fill selector on the container).\n const xAxisTitle = resolveXAxisTitle(xAxisLabel);\n // The secondary axis is derived from the series, not from a flag of its own:\n // that keeps a series from pointing at an id no axis declares, where recharts\n // falls back to an implicit axis — the series still scales off its own data, but\n // silently loses the domain/tickCount/formatter/unit that axis was configured\n // with, and renders no chrome for it.\n const hasSecondaryValueAxis = series.some((s) => s.yAxis === 'secondary');\n // The mirror case the `series` opt-in can't rule out on its own: every series\n // asks for the secondary axis, leaving the primary one with nothing measured\n // against it. recharts gives an axis with no graphical items no ticks at all, so\n // it paints a blank gutter and `CartesianGrid` — which follows it — collapses to\n // the two plot boundaries. Hand the gutter and the grid to the axis that does\n // have the series. Both conditionals are inert on every other chart shape, so\n // single-axis output is untouched.\n const hasPrimarySeries = series.some((s) => s.yAxis !== 'secondary');\n const primaryValueAxisIsOrphaned = hasSecondaryValueAxis && !hasPrimarySeries;\n const primaryOrientation = yAxisOrientation ?? 'left';\n const secondaryOrientation = primaryOrientation === 'left' ? 'right' : 'left';\n\n // The category axis is pinned to the left when the marks grow horizontally,\n // so its title is angled for that side whatever `yAxisOrientation` says.\n const yAxisTitle = resolveYAxisTitle(\n yAxisLabel,\n isHorizontal ? 'left' : primaryOrientation\n );\n const secondaryYAxisTitle = resolveYAxisTitle(\n secondaryYAxisLabel,\n secondaryOrientation\n );\n // Horizontal puts the second scale on a top X axis, where a rotated title\n // would read sideways over the plot.\n const secondaryXAxisTitle = resolveXAxisTitle(\n secondaryYAxisLabel,\n 'insideTop'\n );\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n const secondaryYDomain = resolveAxisDomain(secondaryYAxisDomain);\n\n // Which axis a series (or the grid, or a reference element) binds to. The\n // value axis is Y by default and X when horizontal; the primary one keeps\n // recharts' implicit id `0` — `resolveDefaultProps` fills the `undefined` in —\n // so a series that opts out of the secondary axis passes exactly what it\n // passed before that axis existed.\n const valueAxisBinding = (target: ChartYAxisTarget | undefined) => {\n const id = target === 'secondary' ? SECONDARY_VALUE_AXIS_ID : undefined;\n return isHorizontal ? { xAxisId: id } : { yAxisId: id };\n };\n // Spread (rather than passed as an `undefined` prop) so the primary case\n // reorders nothing: see the `orientation` note on the primary axis below.\n const orphanedAxisBinding = primaryValueAxisIsOrphaned\n ? valueAxisBinding('secondary')\n : {};\n\n const xAxisTickLabels = resolveXAxisTickLabels(\n isHorizontal\n ? []\n : data.map((row) => row[xKey]),\n xTickFormatter\n );\n const chartContainerRef = React.useRef<HTMLDivElement>(null);\n const xAxisLayout = useXAxisLayout(\n chartContainerRef,\n xAxisAngle,\n xAxisLabel,\n xAxisTickLabels.join('\\u0000')\n );\n\n const referenceLines = referenceLine\n ? Array.isArray(referenceLine)\n ? referenceLine\n : [referenceLine]\n : [];\n const referenceAreas = (\n referenceArea\n ? Array.isArray(referenceArea)\n ? referenceArea\n : [referenceArea]\n : []\n )\n .map((area) => ({ area, range: resolveCategoryRange(area, data, xKey) }))\n .filter(\n (\n entry\n ): entry is { area: ComposedChartReferenceArea; range: [number, number] } =>\n entry.range !== undefined\n );\n // A reference rule belongs to one scale, so both halves of it — which keys\n // an `average` pools, and which axis the result is plotted against — have to\n // agree. When the primary axis is orphaned every series is on the secondary\n // one, so that becomes the default rather than leaving `average: true` with\n // an empty key set.\n const defaultReferenceAxis: ChartYAxisTarget = primaryValueAxisIsOrphaned\n ? 'secondary'\n : 'primary';\n const seriesAxisOf = (s: ComposedSeries) => s.yAxis ?? 'primary';\n const seriesAxisByKey = new Map(series.map((s) => [s.key, seriesAxisOf(s)]));\n const seriesKeysOn = (target: ChartYAxisTarget) =>\n series.filter((s) => seriesAxisOf(s) === target).map((s) => s.key);\n const hiddenLegendKeys = new Set(\n series.filter((s) => s.legendType === 'none').map((s) => s.key)\n );\n // The axis position a band/rule is placed at. `?? undefined` because a row\n // whose category cell is null has no position on the axis — recharts types\n // its reference coordinates as `string | number`.\n const categoryAt = (row: number) => data[row]?.[xKey] ?? undefined;\n\n // Resolved up here, not inside the map, because the plot margin below has to\n // know whether any rule will hang a caption above the plot.\n const resolvedReferenceLines = referenceLines\n .map((line) => {\n // A category rule is placed by the category's own value, so an index\n // bound is resolved back to it first.\n const categoryRange =\n line.category !== undefined\n ? resolveCategoryRange(\n { from: line.category, to: line.category },\n data,\n xKey\n )\n : undefined;\n // An `average` naming one series is read off that series' own scale\n // unless the caller says otherwise; anything else falls back to the\n // chart's default axis.\n const lineAxis =\n line.yAxis ??\n (typeof line.average === 'string'\n ? (seriesAxisByKey.get(line.average) ?? defaultReferenceAxis)\n : defaultReferenceAxis);\n const value = resolveChartReferenceValue(line, data, seriesKeysOn(lineAxis));\n const category = categoryRange\n ? categoryAt(categoryRange[0])\n : undefined;\n // The value position wins when both are given; a category that resolves\n // to nothing (an unknown bound) draws no rule.\n const position =\n value !== undefined\n ? isHorizontal\n ? { x: value }\n : { y: value }\n : category !== undefined\n ? isHorizontal\n ? { y: category }\n : { x: category }\n : undefined;\n // A value rule runs across the value axis, so it is drawn vertical\n // exactly when the values are on X — and a category rule the other way\n // round.\n const isVerticalRule = (value !== undefined) === isHorizontal;\n return { line, lineAxis, position, isVerticalRule };\n })\n .filter(\n (\n entry\n ): entry is typeof entry & { position: Record<string, string | number> } =>\n entry.position !== undefined\n );\n\n // Line/area series don't clamp their labels to the plot (see\n // CHART_LABEL_MARGIN); a composed chart can hold either. A caller-supplied\n // margin overrides that per side rather than replacing it, so asking for one\n // wider gutter can't silently drop the label headroom.\n const labelMargin = showLabels ? CHART_LABEL_MARGIN : undefined;\n // A vertical rule hangs its caption off the top end, outside the plot, where\n // recharts' 5px inset clips it — the same headroom problem CHART_LABEL_MARGIN\n // solves for data labels, so it is reserved the same way rather than left for\n // the caller to discover and pass a `margin` for.\n const referenceLabelMargin = resolvedReferenceLines.some(\n (entry) => entry.line.label && entry.isVerticalRule\n )\n ? REFERENCE_LABEL_MARGIN\n : undefined;\n const baseMargin =\n margin || labelMargin || referenceLabelMargin\n ? {\n ...(margin ? DEFAULT_CHART_MARGIN : {}),\n ...referenceLabelMargin,\n ...labelMargin,\n ...margin,\n }\n : undefined;\n const resolvedMargin = mergeXAxisLayoutMargin(baseMargin, xAxisLayout.margin);\n\n // Only the segment at the growing end of a stack rounds its corners — the\n // ones below it butt against the next segment.\n const lastIndexInStack = new Map<string, number>();\n series.forEach((s, index) => {\n if (s.stackId && s.type !== 'line') {\n lastIndexInStack.set(`${s.type}-${s.stackId}`, index);\n }\n });\n\n // Everything from here to the `return` is lifted out of the returned tree\n // only to keep it readable as a flat list of chart children. Nothing in\n // recharts forces the `render*` helpers to be plain functions: axes and\n // series register themselves with the chart's store, and `<Cell>` is the\n // only child still looked up by element type — a component wrapper renders\n // fine (see AreaChart's `AreaFillGradients`). They stay functions because\n // they are declared inside the render body, where a component would get a\n // fresh element type on every render and remount its subtree.\n\n // The two orientations stay two whole blocks rather than one parameterised\n // axis pair: they swap which axis is `type=\"number\"` and which carries the\n // categories, and they differ in props recharts treats as present-but-\n // undefined vs absent (see the `orientation` note below), which a shared\n // element would have to reintroduce prop by prop anyway.\n\n // Horizontal marks put the values on X, so the value-axis props\n // (unit/tickCount/domain) belong on the X axis here — recharts ignores them\n // on the category axis.\n const renderHorizontalAxes = () => (\n <>\n <XAxis\n type=\"number\"\n hide={!showXAxis || primaryValueAxisIsOrphaned}\n tickLine={false}\n axisLine={false}\n unit={xUnit}\n tickFormatter={xTickFormatter}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n tickCount={yAxisTickCount}\n domain={yDomain}\n height={xAxisLayout.height}\n label={xAxisTitle}\n />\n <YAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showYAxis}\n // `yAxisOrientation` picks the side of the *value* axis, which\n // is X here — a left/right choice it has no room for, and one\n // the secondary axis already spends on the top edge. Moving the\n // category axis with it instead would satisfy the prop name and\n // break its contract, so it stays inert in this orientation.\n tickLine={false}\n axisLine={false}\n tickFormatter={yTickFormatter}\n width={yAxisLabel ? 96 : 80}\n label={yAxisTitle}\n />\n {hasSecondaryValueAxis && (\n <XAxis\n xAxisId={SECONDARY_VALUE_AXIS_ID}\n type=\"number\"\n hide={!showSecondaryYAxis}\n orientation=\"top\"\n tickLine={false}\n axisLine={false}\n unit={secondaryYUnit}\n tickFormatter={secondaryYTickFormatter}\n tickCount={secondaryYAxisTickCount}\n domain={secondaryYDomain}\n label={secondaryXAxisTitle}\n />\n )}\n </>\n );\n\n const renderVerticalAxes = () => (\n <>\n <XAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n height={xAxisLayout.height}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n hide={!showYAxis || primaryValueAxisIsOrphaned}\n // Spread only when set. `orientation={undefined}` would resolve to the\n // same `left`, but the key's presence moves it ahead of `width` in the\n // props object recharts spreads onto its tick labels — reordering the\n // SVG attributes of every existing chart for no functional gain.\n {...(yAxisOrientation ? { orientation: yAxisOrientation } : {})}\n tickLine={false}\n axisLine={false}\n unit={yUnit}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n {hasSecondaryValueAxis && (\n <YAxis\n yAxisId={SECONDARY_VALUE_AXIS_ID}\n type=\"number\"\n hide={!showSecondaryYAxis}\n orientation={secondaryOrientation}\n tickLine={false}\n axisLine={false}\n unit={secondaryYUnit}\n tickFormatter={secondaryYTickFormatter}\n tickCount={secondaryYAxisTickCount}\n domain={secondaryYDomain}\n width={secondaryYAxisLabel ? 72 : undefined}\n label={secondaryYAxisTitle}\n />\n )}\n </>\n );\n\n // recharts keeps a `legendType=\"none\"` series in the legend payload (it only\n // drops its icon), so hiding an entry is this filter's job — the same guard\n // `BarChart` applies to its synthetic series. Only wired up when a series\n // asks for it, so every other chart keeps the plain content element.\n const legendContent: LegendContentType =\n hiddenLegendKeys.size > 0\n ? (legendProps) => (\n <ChartLegendContent\n verticalAlign={legendPosition}\n fontSize={legendFontSize}\n payload={\n legendProps.payload?.filter(\n (item) => !hiddenLegendKeys.has(String(item.dataKey))\n ) as ChartLegendContentProps['payload']\n }\n />\n )\n : <ChartLegendContent verticalAlign={legendPosition} fontSize={legendFontSize} />;\n\n const renderSeries = (s: ComposedSeries, index: number) => {\n const color = s.color ?? `var(--color-${toCssKey(s.key)})`;\n const zIndex = SERIES_Z_INDEX_BASE + index;\n const axisBinding = valueAxisBinding(s.yAxis);\n const stackId =\n s.stackId && s.type !== 'line' ? `${s.type}-${s.stackId}` : undefined;\n const seriesFillOpacity = s.fillOpacity ?? fillOpacity;\n const seriesConnectNulls = s.connectNulls ?? connectNulls;\n const seriesShowDots = s.showDots ?? showDots;\n const seriesShowActiveDots = s.showActiveDots ?? showActiveDots;\n const seriesLegendType = s.legendType ? { legendType: s.legendType } : {};\n // A stacked segment has no free space at its growing end (the next\n // segment is drawn there), so its labels centre in their own\n // segment instead.\n const seriesLabelPosition = resolveCartesianLabelPosition({\n labelPosition,\n isStacked: stackId !== undefined,\n growingEnd: isHorizontal ? 'right' : 'top',\n });\n const label = showLabels ? (\n <LabelList\n dataKey={s.key}\n position={seriesLabelPosition}\n formatter={toLabelFormatter(labelFormatter)}\n className={resolveLabelFillClass(seriesLabelPosition, {\n translucentSeries: s.type === 'area',\n })}\n fontSize={CHART_LABEL_FONT_SIZE}\n />\n ) : null;\n\n if (s.type === 'bar') {\n const radius = s.barRadius ?? barRadius;\n const rounded =\n stackId === undefined || lastIndexInStack.get(stackId) === index;\n const barBackground = s.showBackground ?? showBackground;\n // recharts spreads the active option over the bar's own props, so\n // an explicit `undefined` fill would wipe the series color (an\n // unfilled path paints black) — only dim it.\n const barActive = s.showActiveBar ?? showActiveBar;\n return (\n <Bar\n key={s.key}\n dataKey={s.key}\n {...axisBinding}\n fill={color}\n radius={\n radius > 0 && rounded\n ? isHorizontal\n ? [0, radius, radius, 0]\n : [radius, radius, 0, 0]\n : undefined\n }\n zIndex={zIndex}\n {...(stackId ? { stackId } : {})}\n {...(s.barSize !== undefined ? { barSize: s.barSize } : {})}\n {...(s.fillOpacity !== undefined\n ? { fillOpacity: s.fillOpacity }\n : {})}\n // A bar has no outline of its own, so a dash pattern brings\n // one with it — in the series colour, at the series' stroke\n // width if it set one.\n {...(s.strokeDasharray !== undefined\n ? {\n stroke: color,\n strokeDasharray: s.strokeDasharray,\n ...(s.strokeWidth !== undefined\n ? { strokeWidth: s.strokeWidth }\n : {}),\n }\n : {})}\n {...(barBackground ? { background: { fill: backgroundFill } } : {})}\n {...(barActive\n ? { activeBar: { fillOpacity: ACTIVE_BAR_FILL_OPACITY } }\n : {})}\n {...seriesLegendType}\n {...animation}\n >\n {label}\n </Bar>\n );\n }\n if (s.type === 'area') {\n const width = s.strokeWidth ?? strokeWidth;\n const areaStrokeWidth =\n width !== undefined ? { strokeWidth: width } : {};\n return (\n <Area\n key={s.key}\n type={s.curve ?? curve}\n dataKey={s.key}\n {...axisBinding}\n stroke={color}\n fill={color}\n fillOpacity={seriesFillOpacity}\n zIndex={zIndex}\n {...(stackId ? { stackId } : {})}\n // Areas keep recharts' own thinner outline unless a width is\n // asked for: the chart-level default exists for the lines,\n // where 2px is this suite's stroke.\n {...areaStrokeWidth}\n {...(s.strokeDasharray !== undefined\n ? { strokeDasharray: s.strokeDasharray }\n : {})}\n dot={seriesShowDots ? { r: 3 } : false}\n {...(seriesShowActiveDots !== undefined\n ? { activeDot: seriesShowActiveDots ? { r: 5 } : false }\n : {})}\n connectNulls={seriesConnectNulls}\n {...seriesLegendType}\n {...animation}\n >\n {label}\n </Area>\n );\n }\n return (\n <Line\n key={s.key}\n type={s.curve ?? curve}\n dataKey={s.key}\n {...axisBinding}\n stroke={color}\n strokeWidth={s.strokeWidth ?? strokeWidth ?? 2}\n dot={seriesShowDots ? { r: 3 } : false}\n zIndex={zIndex}\n {...(s.strokeDasharray !== undefined\n ? { strokeDasharray: s.strokeDasharray }\n : {})}\n {...(seriesShowActiveDots !== undefined\n ? { activeDot: seriesShowActiveDots ? { r: 5 } : false }\n : {})}\n connectNulls={seriesConnectNulls}\n {...seriesLegendType}\n {...animation}\n >\n {label}\n </Line>\n );\n };\n\n const renderReferenceArea = (\n { area, range }: (typeof referenceAreas)[number],\n index: number\n ) => {\n const [start, end] = range;\n return (\n <ReferenceArea\n key={`${area.label ?? 'area'}-${index}`}\n {...orphanedAxisBinding}\n // Bands run along the category axis: X by default, Y when the\n // marks grow horizontally.\n {...(isHorizontal\n ? { y1: categoryAt(start), y2: categoryAt(end) }\n : { x1: categoryAt(start), x2: categoryAt(end) })}\n fill=\"var(--ui-background-surface-secondary)\"\n fillOpacity={0.6}\n zIndex={REFERENCE_AREA_Z_INDEX}\n ifOverflow=\"extendDomain\"\n label={\n area.label\n ? {\n value: area.label,\n position: 'insideTop',\n fill: 'var(--ui-text-on-surface-secondary)',\n fontSize: 12,\n }\n : undefined\n }\n />\n );\n };\n\n const renderReferenceLine = (\n {\n line,\n lineAxis,\n position,\n isVerticalRule,\n }: (typeof resolvedReferenceLines)[number],\n index: number\n ) => (\n <ReferenceLine\n key={`${line.label ?? 'ref'}-${index}`}\n // Binding to an id no axis declares makes recharts invent an\n // implicit one (see `hasSecondaryValueAxis`), so the request is\n // only honored once a series has brought that axis into being.\n {...(lineAxis === 'secondary' && hasSecondaryValueAxis\n ? valueAxisBinding('secondary')\n : {})}\n {...position}\n // Caption at the top of the rule by default: above the right\n // end of a horizontal one, above the top of a vertical one\n // (which the plot margin reserves room for — see\n // REFERENCE_LABEL_MARGIN). A config's own `labelPosition`\n // overrides that, as on the other cartesian charts.\n {...resolveReferenceLineProps(\n line.label,\n line.labelPosition ?? (isVerticalRule ? 'top' : 'insideTopRight')\n )}\n />\n );\n\n return (\n <div\n ref={ref}\n data-orientation={orientation}\n className={cn(composedChartVariants({ orientation }), className)}\n {...props}\n >\n <ChartContainer\n ref={chartContainerRef}\n config={config}\n palette={palette}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <RechartsComposedChart\n data={data as readonly unknown[]}\n layout={isHorizontal ? 'vertical' : 'horizontal'}\n barSize={barSize}\n barGap={barGap}\n barCategoryGap={barCategoryGap}\n margin={resolvedMargin}\n >\n {showGrid && (\n <CartesianGrid\n // Spread only when the primary axis has no series (see above) —\n // an explicit `undefined` id resolves to the same `0` but\n // reorders the grid's SVG attributes on every existing chart.\n {...orphanedAxisBinding}\n horizontal={gridHorizontal ?? !isHorizontal}\n vertical={gridVertical ?? isHorizontal}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n {isHorizontal ? renderHorizontalAxes() : renderVerticalAxes()}\n {showTooltip && (\n <ChartTooltip\n {...(tooltipCursor ? {} : { cursor: false })}\n content={tooltipContent ?? <ChartTooltipContent />}\n />\n )}\n {showLegend && (\n <ChartLegend\n verticalAlign={legendPosition}\n content={legendContent}\n />\n )}\n {/* Rendered back-to-front in the caller's `series` order — later\n entries sit on top. Order them so thin marks (a line) come after\n the areas/bars they should overlay. */}\n {series.map(renderSeries)}\n {referenceAreas.map(renderReferenceArea)}\n {resolvedReferenceLines.map(renderReferenceLine)}\n {showBrush && (\n <Brush\n dataKey={xKey}\n // The brush slices rows by index, so its captions come from\n // whichever axis holds the categories — Y when horizontal.\n tickFormatter={isHorizontal ? yTickFormatter : xTickFormatter}\n {...resolveBrushProps({ brushHeight, brushAriaLabel })}\n />\n )}\n </RechartsComposedChart>\n </ChartContainer>\n </div>\n );\n }\n);\nComposedChart.displayName = 'ComposedChart';\n\nexport { ComposedChart, composedChartVariants };\n"],"mappings":"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"}
@@ -39,7 +39,7 @@ function S(e, t, n) {
39
39
  });
40
40
  };
41
41
  }
42
- var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, series: E, actualKey: D, forecastKey: O, lowerKey: k, upperKey: A, xAxisLabel: j, yAxisLabel: M, yUnit: fe, actualType: N = "area", strokeWidth: P = 2, showDots: F = !1, styleForecastTicks: I = !1, referenceLine: L, showForecastRegion: R = !0, showGrid: z = !0, showTooltip: B = !0, showLegend: V = !0, showXAxis: pe = !0, showYAxis: me = !0, xTickFormatter: H, yTickFormatter: he, xAxisAngle: U, xAxisInterval: ge, yAxisTickCount: _e, yAxisDomain: ve, gridDashed: ye, gridHorizontal: be, gridVertical: xe, tooltipContent: W, animate: Se, animationDuration: Ce, animationBegin: we, animationEasing: Te, ...Ee }, De) => {
42
+ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, series: E, actualKey: D, forecastKey: O, lowerKey: k, upperKey: A, xAxisLabel: j, yAxisLabel: M, yUnit: fe, actualType: N = "area", strokeWidth: P = 2, showDots: F = !1, styleForecastTicks: I = !1, referenceLine: L, showForecastRegion: R = !0, showGrid: z = !0, showTooltip: B = !0, showLegend: V = !0, legendFontSize: pe, showXAxis: me = !0, showYAxis: he = !0, xTickFormatter: H, yTickFormatter: ge, xAxisAngle: U, xAxisInterval: _e, yAxisTickCount: ve, yAxisDomain: ye, gridDashed: be, gridHorizontal: xe, gridVertical: Se, tooltipContent: W, animate: Ce, animationDuration: we, animationBegin: Te, animationEasing: Ee, ...De }, Oe) => {
43
43
  let G = c.useMemo(() => E?.length ? E : !D || !O ? [] : [{
44
44
  actualKey: D,
45
45
  forecastKey: O,
@@ -52,11 +52,11 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
52
52
  k,
53
53
  A
54
54
  ]), K = ee({
55
- animate: Se,
56
- animationDuration: Ce,
57
- animationBegin: we,
58
- animationEasing: Te
59
- }), q = c.useMemo(() => W ? b(W) : void 0, [W]), Oe = ie(j), ke = s(M), Ae = te(ve), je = c.useMemo(() => {
55
+ animate: Ce,
56
+ animationDuration: we,
57
+ animationBegin: Te,
58
+ animationEasing: Ee
59
+ }), q = c.useMemo(() => W ? b(W) : void 0, [W]), ke = ie(j), Ae = s(M), je = te(ye), Me = c.useMemo(() => {
60
60
  let e;
61
61
  for (let { actualKey: t, forecastKey: n } of G) {
62
62
  let r = g[t], i = g[n];
@@ -67,7 +67,7 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
67
67
  });
68
68
  }
69
69
  return e ?? g;
70
- }, [g, G]), Me = re(w.map((e) => e[T]), H), J = c.useRef(null), Y = oe(J, U, j, Me.join("\0")), Ne = w.map((e) => {
70
+ }, [g, G]), Ne = re(w.map((e) => e[T]), H), J = c.useRef(null), Y = oe(J, U, j, Ne.join("\0")), Pe = w.map((e) => {
71
71
  let t = { ...e };
72
72
  for (let { actualKey: n, lowerKey: r, upperKey: i } of G) {
73
73
  if (!r || !i) continue;
@@ -75,31 +75,31 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
75
75
  t[_(n)] = typeof a == "number" && typeof o == "number" ? [a, o] : void 0;
76
76
  }
77
77
  return t;
78
- }), X = x(w, G, T), Z = R ? X[0] : void 0, Q = w[w.length - 1]?.[T], Pe = S(new Set(X), `var(--color-${o(G[0]?.actualKey ?? "")})`, H), Fe = L ? Array.isArray(L) ? L : [L] : [], Ie = () => /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ u(ue, {
78
+ }), X = x(w, G, T), Z = R ? X[0] : void 0, Q = w[w.length - 1]?.[T], $ = S(new Set(X), `var(--color-${o(G[0]?.actualKey ?? "")})`, H), Fe = L ? Array.isArray(L) ? L : [L] : [], Ie = () => /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ u(ue, {
79
79
  dataKey: T,
80
80
  type: "category",
81
- hide: !pe,
81
+ hide: !me,
82
82
  tickLine: !1,
83
83
  axisLine: !1,
84
84
  tickMargin: 8,
85
85
  tickFormatter: H,
86
- tick: I ? Pe : void 0,
86
+ tick: I ? $ : void 0,
87
87
  angle: U,
88
- interval: ge,
88
+ interval: _e,
89
89
  textAnchor: ne(U),
90
90
  height: Y.height,
91
- label: Oe
91
+ label: ke
92
92
  }), /* @__PURE__ */ u(de, {
93
93
  type: "number",
94
- hide: !me,
94
+ hide: !he,
95
95
  tickLine: !1,
96
96
  axisLine: !1,
97
97
  unit: fe,
98
- tickFormatter: he,
99
- tickCount: _e,
100
- domain: Ae,
98
+ tickFormatter: ge,
99
+ tickCount: ve,
100
+ domain: je,
101
101
  width: M ? 72 : void 0,
102
- label: ke
102
+ label: Ae
103
103
  })] }), Le = () => /* @__PURE__ */ d(l, { children: [Z != null && Q != null && /* @__PURE__ */ u(le, {
104
104
  x1: Z,
105
105
  x2: Q,
@@ -110,7 +110,7 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
110
110
  x: Z,
111
111
  stroke: "var(--ui-border-on-surface-border)",
112
112
  strokeDasharray: "4 4"
113
- })] }), $ = (e, t) => /* @__PURE__ */ u(m, {
113
+ })] }), Re = (e, t) => /* @__PURE__ */ u(m, {
114
114
  y: e.value,
115
115
  stroke: "var(--ui-text-on-surface-secondary)",
116
116
  strokeDasharray: "4 4",
@@ -121,14 +121,15 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
121
121
  fill: "var(--ui-text-on-surface-secondary)",
122
122
  fontSize: 12
123
123
  } : void 0
124
- }, `${e.label ?? "threshold"}-${t}`), Re = () => q ? /* @__PURE__ */ u(i, { content: q }) : /* @__PURE__ */ u(i, { content: (e) => /* @__PURE__ */ u(a, {
124
+ }, `${e.label ?? "threshold"}-${t}`), ze = () => q ? /* @__PURE__ */ u(i, { content: q }) : /* @__PURE__ */ u(i, { content: (e) => /* @__PURE__ */ u(a, {
125
125
  active: e.active,
126
126
  label: e.label,
127
127
  payload: v(e.payload)
128
- }) }), ze = () => /* @__PURE__ */ u(n, { content: (e) => /* @__PURE__ */ u(r, {
128
+ }) }), Be = () => /* @__PURE__ */ u(n, { content: (e) => /* @__PURE__ */ u(r, {
129
129
  verticalAlign: e.verticalAlign,
130
+ fontSize: pe,
130
131
  payload: y(e.payload, G.map((e) => e.actualKey))
131
- }) }), Be = ({ actualKey: e, lowerKey: t, upperKey: n }) => t && n ? /* @__PURE__ */ u(f, {
132
+ }) }), Ve = ({ actualKey: e, lowerKey: t, upperKey: n }) => t && n ? /* @__PURE__ */ u(f, {
132
133
  "data-slot": "confidence-cone-band",
133
134
  dataKey: _(e),
134
135
  type: "monotone",
@@ -141,7 +142,7 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
141
142
  ...K,
142
143
  legendType: "none",
143
144
  tooltipType: "none"
144
- }, _(e)) : null, Ve = ({ actualKey: e }) => {
145
+ }, _(e)) : null, He = ({ actualKey: e }) => {
145
146
  let t = N === "line" ? p : f, n = N === "line" ? void 0 : {
146
147
  fill: `var(--color-${o(e)})`,
147
148
  fillOpacity: .15
@@ -164,7 +165,7 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
164
165
  ...K,
165
166
  legendType: "rect"
166
167
  }, e);
167
- }, He = ({ actualKey: e, forecastKey: t }) => {
168
+ }, Ue = ({ actualKey: e, forecastKey: t }) => {
168
169
  let n = F ? {
169
170
  r: 3,
170
171
  fill: "var(--ui-background-surface-primary)",
@@ -185,31 +186,31 @@ var C = c.forwardRef(({ className: h, config: g, palette: C, data: w, xKey: T, s
185
186
  }, t);
186
187
  };
187
188
  return /* @__PURE__ */ u("div", {
188
- ref: De,
189
+ ref: Oe,
189
190
  className: e(h),
190
- ...Ee,
191
+ ...De,
191
192
  children: /* @__PURE__ */ u(t, {
192
193
  ref: J,
193
- config: je,
194
+ config: Me,
194
195
  palette: C,
195
196
  className: "size-full [&_.recharts-label]:fill-foreground",
196
197
  children: /* @__PURE__ */ d(ce, {
197
- data: Ne,
198
+ data: Pe,
198
199
  margin: ae(void 0, Y.margin),
199
200
  children: [
200
201
  z && /* @__PURE__ */ u(se, {
201
- horizontal: be ?? !0,
202
- vertical: xe ?? !1,
203
- strokeDasharray: ye ? "3 3" : void 0
202
+ horizontal: xe ?? !0,
203
+ vertical: Se ?? !1,
204
+ strokeDasharray: be ? "3 3" : void 0
204
205
  }),
205
206
  Ie(),
206
207
  Le(),
207
- Fe.map($),
208
- B && Re(),
209
- V && ze(),
210
- G.map(Be),
208
+ Fe.map(Re),
209
+ B && ze(),
210
+ V && Be(),
211
211
  G.map(Ve),
212
- G.map(He)
212
+ G.map(He),
213
+ G.map(Ue)
213
214
  ]
214
215
  })
215
216
  })
@@ -1 +1 @@
1
- {"version":3,"file":"confidence-cone.js","names":[],"sources":["../../../../src/components/ui/confidence-cone/confidence-cone.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n Area,\n CartesianGrid,\n ComposedChart,\n Line,\n ReferenceArea,\n ReferenceLine,\n Text,\n XAxis,\n YAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAxisDomain,\n resolveAnimation,\n resolveRotatedTickAnchor,\n resolveXAxisTitle,\n resolveYAxisTitle,\n CHART_LABEL_FONT_SIZE,\n type ChartConfig,\n type ChartPalette,\n type ChartLegendContentProps,\n type ChartTooltipContentProps,\n toCssKey,\n type CartesianChartProps,\n type ChartAnimationProps,\n} from '../chart';\nimport {\n mergeXAxisLayoutMargin,\n useXAxisLayout,\n} from '../chart/use-x-axis-layout';\nimport { resolveXAxisTickLabels } from '../chart/chart-format';\n\n// A forecast confidence-cone: a solid line over the known/actual period, a\n// dashed line over the forecast period, and a shaded band (the \"cone\") between\n// a lower and upper bound that typically widens with the horizon — visualizing\n// growing uncertainty. Built on the shared Chart primitives; no new tokens\n// (series colors are caller-supplied via `config`). The whole metric renders in\n// one hue — actual and forecast differ by line style, not color — so the cone\n// band and the forecast line both reuse the actual series' color.\n\n// Each series' band is a synthetic `[lower, upper]` range field per row that a\n// recharts <Area> shades; kept out of the tooltip/legend (see the filters\n// below). One band per series, so the key carries the series' actual key — the\n// whole `__cone` prefix is reserved.\nconst BAND_PREFIX = '__cone';\nconst bandKeyFor = (actualKey: string) => `${BAND_PREFIX}:${actualKey}`;\n\n/**\n * Drop every synthetic cone-band range series from a recharts tooltip/legend\n * payload, keeping the real actual/forecast series (and their order). Applied to\n * both the default tooltip and any caller-supplied `tooltipContent`, so no band\n * surfaces regardless of which path renders or how many series are plotted.\n */\nexport function dropConeBand<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined\n): T[] | undefined {\n return payload?.filter(\n (item) =>\n !(\n typeof item.dataKey === 'string' && item.dataKey.startsWith(BAND_PREFIX)\n )\n );\n}\n\n/**\n * Reduce a legend payload to the metrics the chart plots — one entry per series.\n * A series' actual, forecast and cone are three recharts series painting a\n * single metric in a single hue, so the legend names each metric once, with its\n * actual series' swatch, instead of listing line styles as separate series.\n */\nexport function keepMetricSeries<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined,\n actualKeys: readonly string[]\n): T[] | undefined {\n return payload?.filter(\n (item) =>\n typeof item.dataKey === 'string' && actualKeys.includes(item.dataKey)\n );\n}\n\n/**\n * Wrap a caller-supplied `tooltipContent` so the synthetic cone band is stripped\n * from the payload before it renders, while preserving recharts' own mount\n * semantics — a function is mounted via `createElement` (its own component\n * identity + hook state), an element via `cloneElement`. This mirrors what the\n * pass-through charts get by handing `content` straight to recharts, so a\n * function-form tooltip keeps its state across re-renders here too. The returned\n * component is a stable content type (memoize it on `tooltipContent`).\n */\ntype TooltipContentType = NonNullable<\n React.ComponentProps<typeof ChartTooltip>['content']\n>;\ntype TooltipContentFn = Extract<\n TooltipContentType,\n (...args: never[]) => unknown\n>;\ntype TooltipRenderProps = Parameters<TooltipContentFn>[0];\n\nexport function createConeTooltip(tooltipContent: TooltipContentType) {\n return function ConeTooltip(props: TooltipRenderProps) {\n const merged = {\n ...props,\n payload: dropConeBand(props.payload),\n } as TooltipRenderProps;\n return typeof tooltipContent === 'function'\n ? React.createElement(\n tooltipContent as React.FunctionComponent<TooltipRenderProps>,\n merged\n )\n : React.cloneElement(tooltipContent, merged);\n };\n}\n\n/**\n * One plotted metric: its actual / forecast columns and, optionally, the two\n * bound columns that shade its cone. Omit `lowerKey`/`upperKey` for a band-less\n * metric — a solid line handing off to a bare dashed projection.\n */\nexport interface ConfidenceConeSeries {\n /** Field for the known/actual values — drawn as a solid line with a filled area. */\n actualKey: string;\n /** Field for the projected values — drawn as a dashed line. */\n forecastKey: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n}\n\n/**\n * The x values of the projected period — every row carrying a forecast value for\n * at least one series, in data order. The first is the hand-off point (where the\n * shaded region and divider start); the whole set drives the forecast tick\n * styling, matched by value so tick `interval` can't skew it the way a tick\n * index would. Exported for unit tests; not part of the package's public API.\n */\nexport function forecastPeriodX(\n data: ReadonlyArray<Record<string, string | number | null | undefined>>,\n series: readonly ConfidenceConeSeries[],\n xKey: string\n): Array<string | number | null | undefined> {\n return data\n .filter((row) =>\n series.some(({ forecastKey }) => typeof row[forecastKey] === 'number')\n )\n .map((row) => row[xKey]);\n}\n\n/**\n * Build the X-axis tick renderer that sets the projected columns apart: italic,\n * in the metric's hue. Styled inline rather than through the `fill` attribute\n * recharts hands every tick, so the accent survives the class-based tick color\n * a chart theme may apply. A custom tick owns its own text, so the caller's\n * `xTickFormatter` is applied here — recharts only applies it to default ticks.\n * Exported for unit tests; not part of the package's public API.\n */\nexport function createForecastTick(\n forecastX: ReadonlySet<string | number | null | undefined>,\n color: string,\n tickFormatter?: CartesianChartProps['xTickFormatter']\n) {\n return function ForecastTick({\n payload,\n index,\n ...tickProps\n }: {\n payload?: { value?: string | number };\n index?: number;\n }) {\n const value = payload?.value;\n return (\n <Text\n {...tickProps}\n style={\n value != null && forecastX.has(value)\n ? { fontStyle: 'italic', fill: color }\n : undefined\n }\n >\n {tickFormatter && value != null ? tickFormatter(value, index) : value}\n </Text>\n );\n };\n}\n\n/** A dashed horizontal threshold on the value axis. */\nexport interface ConfidenceConeReferenceLine {\n /** Position on the value (Y) axis. */\n value: number;\n /** Optional caption rendered at the line's right end. */\n label?: string;\n}\n\n/**\n * Every prop except the one-form-or-the-other requirement `ConfidenceConeProps`\n * layers on below. Exported so the stories can type their `Meta` on a single\n * object shape — Storybook can't split a union's required args between `meta.args`\n * and a story's. Not re-exported from `index.ts`; not part of the public API.\n */\nexport interface ConfidenceConeBaseProps\n extends\n Omit<React.ComponentProps<'div'>, 'children'>,\n CartesianChartProps,\n ChartAnimationProps {\n /**\n * The dataviz palette this chart's series are painted from. Series that\n * state no `color` of their own take a stop of it. See `ChartPalette`.\n */\n palette?: ChartPalette;\n /**\n * Row-per-point data — the shared x dimension plus each series' actual /\n * forecast / bound fields. Rows are naturally sparse (a point has either an\n * actual or a forecast + bounds), so missing fields are allowed. Avoid fields\n * starting with `__cone` — that prefix is reserved for the internal\n * prediction-band series.\n */\n data: ReadonlyArray<Record<string, string | number | null | undefined>>;\n /**\n * Per-series map of `label` / `icon` / `tone` for the actual + forecast lines\n * (imported from the shared `Chart` primitives). Series take their colour from\n * the container's `palette`; each entry maps a key to a `label` and an optional\n * `tone`. Each metric renders in one hue: its cone band and forecast line both\n * reuse its actual series' color — actual and forecast differ by line style,\n * not hue.\n */\n config: ChartConfig;\n /** Category / time axis key (the shared dimension across rows). */\n xKey: string;\n /**\n * Plot several metrics against one shared axis — each with its own actual /\n * forecast / bound fields and its own hue (from `config[actualKey]`). Takes\n * precedence over the single-series `actualKey`/`forecastKey`/`lowerKey`/\n * `upperKey` shorthand below; pass one form or the other, not both. One of the\n * two forms is required.\n */\n series?: readonly ConfidenceConeSeries[];\n /**\n * Single-series shorthand — field for the known/actual values, drawn as a\n * solid line with a filled area. Required (with `forecastKey`) unless `series`\n * is set, which supersedes it.\n */\n actualKey?: string;\n /**\n * Single-series shorthand — field for the projected values, drawn as a dashed\n * line. Required (with `actualKey`) unless `series` is set, which supersedes\n * it.\n */\n forecastKey?: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n /**\n * How the known/actual period is drawn: a filled `area` under the line (the\n * default), or a bare `line` — for a chart where the cone is the only shaded\n * region, or where several metrics' fills would muddy each other.\n */\n actualType?: 'area' | 'line';\n /** Stroke width of the actual + forecast lines. */\n strokeWidth?: number;\n /**\n * Mark each data point: a filled dot on the observed values, a hollow one on\n * the projection — so a point reads as measured or predicted at a glance.\n */\n showDots?: boolean;\n /**\n * Italicize the X-axis ticks over the forecast period and paint them in the\n * first series' hue, so the projected columns read as projected even when the\n * shaded region is off.\n */\n styleForecastTicks?: boolean;\n /**\n * One or more dashed horizontal thresholds on the value axis — e.g. a target\n * or a capacity limit. Pass a single object or an array to draw several.\n */\n referenceLine?: ConfidenceConeReferenceLine | ConfidenceConeReferenceLine[];\n /**\n * Set off the forecast period from the actuals with a dashed divider at the\n * hand-off point (the first row with a forecast value) and a subtle shaded\n * band over the forecast region.\n */\n showForecastRegion?: boolean;\n showLegend?: boolean;\n}\n\n/**\n * Which columns to plot has to be spelled out one way or the other: the `series`\n * array, or the flat `actualKey` + `forecastKey` shorthand. Expressed as a union\n * so a chart with neither is a compile error rather than a silent plot of axes\n * and nothing else. Both forms together stay legal — `series` wins (see\n * `plotted`), which is what the multi-series stories rely on to clear the args\n * table.\n */\nexport type ConfidenceConeProps = ConfidenceConeBaseProps &\n (\n | { series: readonly ConfidenceConeSeries[] }\n | { actualKey: string; forecastKey: string }\n );\n\nconst ConfidenceCone = React.forwardRef<HTMLDivElement, ConfidenceConeProps>(\n (\n {\n className,\n config,\n palette,\n data,\n xKey,\n series,\n actualKey,\n forecastKey,\n lowerKey,\n upperKey,\n xAxisLabel,\n yAxisLabel,\n yUnit,\n actualType = 'area',\n strokeWidth = 2,\n showDots = false,\n styleForecastTicks = false,\n referenceLine,\n showForecastRegion = true,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n ...props\n },\n ref\n ) => {\n // The flat *Key props are the single-series shorthand for `series`.\n const plotted = React.useMemo<readonly ConfidenceConeSeries[]>(() => {\n if (series?.length) return series;\n if (!actualKey || !forecastKey) return [];\n return [{ actualKey, forecastKey, lowerKey, upperKey }];\n }, [series, actualKey, forecastKey, lowerKey, upperKey]);\n\n const animation = resolveAnimation({\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n });\n // Memoized so recharts sees a stable content type across renders — a fresh\n // wrapper each render would remount the caller's tooltip and reset its state.\n const customTooltip = React.useMemo(\n () => (tooltipContent ? createConeTooltip(tooltipContent) : undefined),\n [tooltipContent]\n );\n\n const xAxisTitle = resolveXAxisTitle(xAxisLabel);\n const yAxisTitle = resolveYAxisTitle(yAxisLabel);\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n\n // One hue per metric. Each cone and forecast line already paints with its own\n // series' actual color; re-pointing that series' forecast key's `--color-*`\n // at it too means nothing downstream — a custom tooltip, a caller's\n // `var(--color-<forecastKey>)` — can reintroduce a second color.\n const seriesConfig = React.useMemo(() => {\n let next: ChartConfig | undefined;\n for (const { actualKey: aKey, forecastKey: fKey } of plotted) {\n const actual = config[aKey];\n const forecast = config[fKey];\n if (!actual || !forecast) continue;\n next ??= { ...config };\n next[fKey] = {\n label: forecast.label,\n icon: forecast.icon,\n tone: { sameAs: aKey },\n };\n }\n return next ?? config;\n }, [config, plotted]);\n\n const xAxisTickLabels = resolveXAxisTickLabels(\n data.map((row) => row[xKey]),\n xTickFormatter\n );\n const chartContainerRef = React.useRef<HTMLDivElement>(null);\n const xAxisLayout = useXAxisLayout(\n chartContainerRef,\n xAxisAngle,\n xAxisLabel,\n xAxisTickLabels.join('\\u0000')\n );\n\n // Augment each row with one `[lower, upper]` band tuple per coned series for\n // its Area to shade. Rows missing a numeric bound are left un-coned (the\n // band breaks there); a series without bounds gets no band at all.\n const chartData = data.map((row) => {\n const next: Record<string, unknown> = { ...row };\n for (const {\n actualKey: aKey,\n lowerKey: lKey,\n upperKey: uKey,\n } of plotted) {\n if (!lKey || !uKey) continue;\n const lower = row[lKey];\n const upper = row[uKey];\n next[bandKeyFor(aKey)] =\n typeof lower === 'number' && typeof upper === 'number'\n ? [lower, upper]\n : undefined;\n }\n return next;\n });\n\n const forecastX = forecastPeriodX(data, plotted, xKey);\n // Set the projected period off from the actuals with a shaded band + a\n // divider at the hand-off.\n const forecastStart = showForecastRegion ? forecastX[0] : undefined;\n const lastX = data[data.length - 1]?.[xKey];\n\n const renderForecastTick = createForecastTick(\n new Set(forecastX),\n `var(--color-${toCssKey(plotted[0]?.actualKey ?? '')})`,\n xTickFormatter\n );\n\n const referenceLines = referenceLine\n ? Array.isArray(referenceLine)\n ? referenceLine\n : [referenceLine]\n : [];\n\n // Everything from here to the `return` is lifted out of the returned tree\n // only to keep it readable as a flat list of chart children. Nothing in\n // recharts forces the `render*` helpers to be plain functions: axes and\n // series register themselves with the chart's store, and `<Cell>` is the\n // only child still looked up by element type — a component wrapper renders\n // fine (see AreaChart's `AreaFillGradients`). They stay functions because\n // they are declared inside the render body, where a component would get a\n // fresh element type on every render and remount its subtree.\n\n const renderAxes = () => (\n <>\n <XAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n tick={styleForecastTicks ? renderForecastTick : undefined}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n height={xAxisLayout.height}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n hide={!showYAxis}\n tickLine={false}\n axisLine={false}\n unit={yUnit}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n </>\n );\n\n // Set the forecast region off from the actuals (behind everything).\n const renderForecastRegion = () => (\n <>\n {forecastStart != null && lastX != null && (\n <ReferenceArea\n x1={forecastStart}\n x2={lastX}\n fill=\"var(--ui-background-surface-secondary)\"\n fillOpacity={0.5}\n ifOverflow=\"extendDomain\"\n />\n )}\n {forecastStart != null && (\n <ReferenceLine\n x={forecastStart}\n stroke=\"var(--ui-border-on-surface-border)\"\n strokeDasharray=\"4 4\"\n />\n )}\n </>\n );\n\n const renderThreshold = (\n threshold: ConfidenceConeReferenceLine,\n index: number\n ) => (\n <ReferenceLine\n key={`${threshold.label ?? 'threshold'}-${index}`}\n y={threshold.value}\n stroke=\"var(--ui-text-on-surface-secondary)\"\n strokeDasharray=\"4 4\"\n // extendDomain so a threshold beyond the data max stays visible.\n ifOverflow=\"extendDomain\"\n label={\n threshold.label\n ? {\n value: threshold.label,\n position: 'insideTopRight',\n fill: 'var(--ui-text-on-surface-secondary)',\n fontSize: CHART_LABEL_FONT_SIZE,\n }\n : undefined\n }\n />\n );\n\n const renderTooltip = () =>\n customTooltip ? (\n // Strips the synthetic band before the caller's tooltip sees it — the\n // `__cone` series feeds the Area, not the tooltip.\n <ChartTooltip content={customTooltip} />\n ) : (\n <ChartTooltip\n content={(tp) => (\n <ChartTooltipContent\n active={tp.active}\n label={tp.label}\n // The synthetic band feeds the Area, not the tooltip.\n payload={\n dropConeBand(tp.payload) as ChartTooltipContentProps['payload']\n }\n />\n )}\n />\n );\n\n const renderLegend = () => (\n <ChartLegend\n content={(lp) => (\n <ChartLegendContent\n verticalAlign={lp.verticalAlign}\n payload={\n keepMetricSeries(\n lp.payload,\n plotted.map((s) => s.actualKey)\n ) as ChartLegendContentProps['payload']\n }\n />\n )}\n />\n );\n\n // One color per metric — actual and forecast differ by line style, not hue\n // — so a cone reuses its series' actual color.\n const renderConeBand = ({\n actualKey: aKey,\n lowerKey: lKey,\n upperKey: uKey,\n }: ConfidenceConeSeries) =>\n lKey && uKey ? (\n <Area\n key={bandKeyFor(aKey)}\n // The band paints in the same hue, at the same opacity, as the\n // actual series' own area, so nothing on the rendered path tells\n // the two apart. recharts forwards `data-*` onto the path it\n // draws; the tests select the band through this.\n data-slot=\"confidence-cone-band\"\n dataKey={bandKeyFor(aKey)}\n type=\"monotone\"\n stroke=\"none\"\n fill={`var(--color-${toCssKey(aKey)})`}\n fillOpacity={0.15}\n connectNulls={false}\n dot={false}\n activeDot={false}\n {...animation}\n legendType=\"none\"\n tooltipType=\"none\"\n />\n ) : null;\n\n const renderActualMark = ({ actualKey: aKey }: ConfidenceConeSeries) => {\n // An area and a line take the same props here; only the region under the\n // curve (and the mark recharts draws) differ. A `Line` gets no fill at\n // all — `fillOpacity: 0` would also erase its dots.\n const ActualMark = actualType === 'line' ? Line : Area;\n const areaFill =\n actualType === 'line'\n ? undefined\n : { fill: `var(--color-${toCssKey(aKey)})`, fillOpacity: 0.15 };\n // Observed points read as measured: LineChart's dot geometry (r 3, 2px\n // ring) filled with the metric hue. The ring is that same hue, so the\n // mark is solid — and wide enough against the 2px line not to read as a\n // mere thickening of it. `fillOpacity: 1` is load-bearing: recharts\n // merges the parent mark's own presentation props into every dot it\n // draws, so an `<Area>`'s 0.15 would otherwise wash the dot out to a halo.\n const dot = showDots\n ? {\n r: 3,\n fill: `var(--color-${toCssKey(aKey)})`,\n fillOpacity: 1,\n stroke: `var(--color-${toCssKey(aKey)})`,\n strokeWidth: 2,\n }\n : false;\n return (\n <ActualMark\n key={aKey}\n dataKey={aKey}\n type=\"monotone\"\n stroke={`var(--color-${toCssKey(aKey)})`}\n strokeWidth={strokeWidth}\n {...areaFill}\n dot={dot}\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n // The legend names the metric once, so it carries the swatch that\n // stands for the whole series rather than the actual line's style.\n legendType=\"rect\"\n />\n );\n };\n\n const renderForecastLine = ({\n actualKey: aKey,\n forecastKey: fKey,\n }: ConfidenceConeSeries) => {\n // Projected points read as predicted: the same LineChart dot, inverted —\n // the metric's hue as the ring, the surface color as the fill, so the\n // dashed line doesn't show through the middle. (LineChart leaves the fill\n // to recharts, whose `Line` defaults it to `#fff`; the token is that same\n // white in the light theme and also holds up in the dark one.)\n // `strokeDasharray: 'none'` is load-bearing: recharts merges the parent\n // mark's presentation props into every dot, so this line's `5 5` would\n // otherwise break each dot's ring into two arcs.\n const dot = showDots\n ? {\n r: 3,\n fill: 'var(--ui-background-surface-primary)',\n stroke: `var(--color-${toCssKey(aKey)})`,\n strokeWidth: 2,\n strokeDasharray: 'none',\n }\n : false;\n return (\n <Line\n key={fKey}\n dataKey={fKey}\n type=\"monotone\"\n stroke={`var(--color-${toCssKey(aKey)})`}\n strokeWidth={strokeWidth}\n strokeDasharray=\"5 5\"\n dot={dot}\n // Paired with `dot` the way every other chart does it — left unset,\n // the projection would keep recharts' default active dot while the\n // actuals had none (and a different radius when on).\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n />\n );\n };\n\n return (\n <div ref={ref} className={cn(className)} {...props}>\n <ChartContainer\n ref={chartContainerRef}\n config={seriesConfig}\n palette={palette}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <ComposedChart\n data={chartData as readonly unknown[]}\n margin={mergeXAxisLayoutMargin(undefined, xAxisLayout.margin)}\n >\n {showGrid && (\n <CartesianGrid\n horizontal={gridHorizontal ?? true}\n vertical={gridVertical ?? false}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n {renderAxes()}\n {renderForecastRegion()}\n {referenceLines.map(renderThreshold)}\n {showTooltip && renderTooltip()}\n {showLegend && renderLegend()}\n {/* Every cone renders before any line, so the lines draw on top of\n all of them. */}\n {plotted.map(renderConeBand)}\n {plotted.map(renderActualMark)}\n {plotted.map(renderForecastLine)}\n </ComposedChart>\n </ChartContainer>\n </div>\n );\n }\n);\nConfidenceCone.displayName = 'ConfidenceCone';\n\nexport { ConfidenceCone };\n"],"mappings":"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"}
1
+ {"version":3,"file":"confidence-cone.js","names":[],"sources":["../../../../src/components/ui/confidence-cone/confidence-cone.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n Area,\n CartesianGrid,\n ComposedChart,\n Line,\n ReferenceArea,\n ReferenceLine,\n Text,\n XAxis,\n YAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAxisDomain,\n resolveAnimation,\n resolveRotatedTickAnchor,\n resolveXAxisTitle,\n resolveYAxisTitle,\n CHART_LABEL_FONT_SIZE,\n type ChartConfig,\n type ChartLegendFontSize,\n type ChartPalette,\n type ChartLegendContentProps,\n type ChartTooltipContentProps,\n toCssKey,\n type CartesianChartProps,\n type ChartAnimationProps,\n} from '../chart';\nimport {\n mergeXAxisLayoutMargin,\n useXAxisLayout,\n} from '../chart/use-x-axis-layout';\nimport { resolveXAxisTickLabels } from '../chart/chart-format';\n\n// A forecast confidence-cone: a solid line over the known/actual period, a\n// dashed line over the forecast period, and a shaded band (the \"cone\") between\n// a lower and upper bound that typically widens with the horizon — visualizing\n// growing uncertainty. Built on the shared Chart primitives; no new tokens\n// (series colors are caller-supplied via `config`). The whole metric renders in\n// one hue — actual and forecast differ by line style, not color — so the cone\n// band and the forecast line both reuse the actual series' color.\n\n// Each series' band is a synthetic `[lower, upper]` range field per row that a\n// recharts <Area> shades; kept out of the tooltip/legend (see the filters\n// below). One band per series, so the key carries the series' actual key — the\n// whole `__cone` prefix is reserved.\nconst BAND_PREFIX = '__cone';\nconst bandKeyFor = (actualKey: string) => `${BAND_PREFIX}:${actualKey}`;\n\n/**\n * Drop every synthetic cone-band range series from a recharts tooltip/legend\n * payload, keeping the real actual/forecast series (and their order). Applied to\n * both the default tooltip and any caller-supplied `tooltipContent`, so no band\n * surfaces regardless of which path renders or how many series are plotted.\n */\nexport function dropConeBand<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined\n): T[] | undefined {\n return payload?.filter(\n (item) =>\n !(\n typeof item.dataKey === 'string' && item.dataKey.startsWith(BAND_PREFIX)\n )\n );\n}\n\n/**\n * Reduce a legend payload to the metrics the chart plots — one entry per series.\n * A series' actual, forecast and cone are three recharts series painting a\n * single metric in a single hue, so the legend names each metric once, with its\n * actual series' swatch, instead of listing line styles as separate series.\n */\nexport function keepMetricSeries<T extends { dataKey?: unknown }>(\n payload: readonly T[] | undefined,\n actualKeys: readonly string[]\n): T[] | undefined {\n return payload?.filter(\n (item) =>\n typeof item.dataKey === 'string' && actualKeys.includes(item.dataKey)\n );\n}\n\n/**\n * Wrap a caller-supplied `tooltipContent` so the synthetic cone band is stripped\n * from the payload before it renders, while preserving recharts' own mount\n * semantics — a function is mounted via `createElement` (its own component\n * identity + hook state), an element via `cloneElement`. This mirrors what the\n * pass-through charts get by handing `content` straight to recharts, so a\n * function-form tooltip keeps its state across re-renders here too. The returned\n * component is a stable content type (memoize it on `tooltipContent`).\n */\ntype TooltipContentType = NonNullable<\n React.ComponentProps<typeof ChartTooltip>['content']\n>;\ntype TooltipContentFn = Extract<\n TooltipContentType,\n (...args: never[]) => unknown\n>;\ntype TooltipRenderProps = Parameters<TooltipContentFn>[0];\n\nexport function createConeTooltip(tooltipContent: TooltipContentType) {\n return function ConeTooltip(props: TooltipRenderProps) {\n const merged = {\n ...props,\n payload: dropConeBand(props.payload),\n } as TooltipRenderProps;\n return typeof tooltipContent === 'function'\n ? React.createElement(\n tooltipContent as React.FunctionComponent<TooltipRenderProps>,\n merged\n )\n : React.cloneElement(tooltipContent, merged);\n };\n}\n\n/**\n * One plotted metric: its actual / forecast columns and, optionally, the two\n * bound columns that shade its cone. Omit `lowerKey`/`upperKey` for a band-less\n * metric — a solid line handing off to a bare dashed projection.\n */\nexport interface ConfidenceConeSeries {\n /** Field for the known/actual values — drawn as a solid line with a filled area. */\n actualKey: string;\n /** Field for the projected values — drawn as a dashed line. */\n forecastKey: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n}\n\n/**\n * The x values of the projected period — every row carrying a forecast value for\n * at least one series, in data order. The first is the hand-off point (where the\n * shaded region and divider start); the whole set drives the forecast tick\n * styling, matched by value so tick `interval` can't skew it the way a tick\n * index would. Exported for unit tests; not part of the package's public API.\n */\nexport function forecastPeriodX(\n data: ReadonlyArray<Record<string, string | number | null | undefined>>,\n series: readonly ConfidenceConeSeries[],\n xKey: string\n): Array<string | number | null | undefined> {\n return data\n .filter((row) =>\n series.some(({ forecastKey }) => typeof row[forecastKey] === 'number')\n )\n .map((row) => row[xKey]);\n}\n\n/**\n * Build the X-axis tick renderer that sets the projected columns apart: italic,\n * in the metric's hue. Styled inline rather than through the `fill` attribute\n * recharts hands every tick, so the accent survives the class-based tick color\n * a chart theme may apply. A custom tick owns its own text, so the caller's\n * `xTickFormatter` is applied here — recharts only applies it to default ticks.\n * Exported for unit tests; not part of the package's public API.\n */\nexport function createForecastTick(\n forecastX: ReadonlySet<string | number | null | undefined>,\n color: string,\n tickFormatter?: CartesianChartProps['xTickFormatter']\n) {\n return function ForecastTick({\n payload,\n index,\n ...tickProps\n }: {\n payload?: { value?: string | number };\n index?: number;\n }) {\n const value = payload?.value;\n return (\n <Text\n {...tickProps}\n style={\n value != null && forecastX.has(value)\n ? { fontStyle: 'italic', fill: color }\n : undefined\n }\n >\n {tickFormatter && value != null ? tickFormatter(value, index) : value}\n </Text>\n );\n };\n}\n\n/** A dashed horizontal threshold on the value axis. */\nexport interface ConfidenceConeReferenceLine {\n /** Position on the value (Y) axis. */\n value: number;\n /** Optional caption rendered at the line's right end. */\n label?: string;\n}\n\n/**\n * Every prop except the one-form-or-the-other requirement `ConfidenceConeProps`\n * layers on below. Exported so the stories can type their `Meta` on a single\n * object shape — Storybook can't split a union's required args between `meta.args`\n * and a story's. Not re-exported from `index.ts`; not part of the public API.\n */\nexport interface ConfidenceConeBaseProps\n extends\n Omit<React.ComponentProps<'div'>, 'children'>,\n CartesianChartProps,\n ChartAnimationProps {\n /**\n * The dataviz palette this chart's series are painted from. Series that\n * state no `color` of their own take a stop of it. See `ChartPalette`.\n */\n palette?: ChartPalette;\n /**\n * Row-per-point data — the shared x dimension plus each series' actual /\n * forecast / bound fields. Rows are naturally sparse (a point has either an\n * actual or a forecast + bounds), so missing fields are allowed. Avoid fields\n * starting with `__cone` — that prefix is reserved for the internal\n * prediction-band series.\n */\n data: ReadonlyArray<Record<string, string | number | null | undefined>>;\n /**\n * Per-series map of `label` / `icon` / `tone` for the actual + forecast lines\n * (imported from the shared `Chart` primitives). Series take their colour from\n * the container's `palette`; each entry maps a key to a `label` and an optional\n * `tone`. Each metric renders in one hue: its cone band and forecast line both\n * reuse its actual series' color — actual and forecast differ by line style,\n * not hue.\n */\n config: ChartConfig;\n /** Category / time axis key (the shared dimension across rows). */\n xKey: string;\n /**\n * Plot several metrics against one shared axis — each with its own actual /\n * forecast / bound fields and its own hue (from `config[actualKey]`). Takes\n * precedence over the single-series `actualKey`/`forecastKey`/`lowerKey`/\n * `upperKey` shorthand below; pass one form or the other, not both. One of the\n * two forms is required.\n */\n series?: readonly ConfidenceConeSeries[];\n /**\n * Single-series shorthand — field for the known/actual values, drawn as a\n * solid line with a filled area. Required (with `forecastKey`) unless `series`\n * is set, which supersedes it.\n */\n actualKey?: string;\n /**\n * Single-series shorthand — field for the projected values, drawn as a dashed\n * line. Required (with `actualKey`) unless `series` is set, which supersedes\n * it.\n */\n forecastKey?: string;\n /** Field for the cone's lower bound. Omit (with `upperKey`) for no cone. */\n lowerKey?: string;\n /** Field for the cone's upper bound. Omit (with `lowerKey`) for no cone. */\n upperKey?: string;\n /**\n * How the known/actual period is drawn: a filled `area` under the line (the\n * default), or a bare `line` — for a chart where the cone is the only shaded\n * region, or where several metrics' fills would muddy each other.\n */\n actualType?: 'area' | 'line';\n /** Stroke width of the actual + forecast lines. */\n strokeWidth?: number;\n /**\n * Mark each data point: a filled dot on the observed values, a hollow one on\n * the projection — so a point reads as measured or predicted at a glance.\n */\n showDots?: boolean;\n /**\n * Italicize the X-axis ticks over the forecast period and paint them in the\n * first series' hue, so the projected columns read as projected even when the\n * shaded region is off.\n */\n styleForecastTicks?: boolean;\n /**\n * One or more dashed horizontal thresholds on the value axis — e.g. a target\n * or a capacity limit. Pass a single object or an array to draw several.\n */\n referenceLine?: ConfidenceConeReferenceLine | ConfidenceConeReferenceLine[];\n /**\n * Set off the forecast period from the actuals with a dashed divider at the\n * hand-off point (the first row with a forecast value) and a subtle shaded\n * band over the forecast region.\n */\n showForecastRegion?: boolean;\n showLegend?: boolean;\n /**\n * Font size of the legend text. Defaults to `'xs'` — the size the legend has\n * always rendered at. See `ChartLegendFontSize`.\n */\n legendFontSize?: ChartLegendFontSize;\n}\n\n/**\n * Which columns to plot has to be spelled out one way or the other: the `series`\n * array, or the flat `actualKey` + `forecastKey` shorthand. Expressed as a union\n * so a chart with neither is a compile error rather than a silent plot of axes\n * and nothing else. Both forms together stay legal — `series` wins (see\n * `plotted`), which is what the multi-series stories rely on to clear the args\n * table.\n */\nexport type ConfidenceConeProps = ConfidenceConeBaseProps &\n (\n | { series: readonly ConfidenceConeSeries[] }\n | { actualKey: string; forecastKey: string }\n );\n\nconst ConfidenceCone = React.forwardRef<HTMLDivElement, ConfidenceConeProps>(\n (\n {\n className,\n config,\n palette,\n data,\n xKey,\n series,\n actualKey,\n forecastKey,\n lowerKey,\n upperKey,\n xAxisLabel,\n yAxisLabel,\n yUnit,\n actualType = 'area',\n strokeWidth = 2,\n showDots = false,\n styleForecastTicks = false,\n referenceLine,\n showForecastRegion = true,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n legendFontSize,\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n ...props\n },\n ref\n ) => {\n // The flat *Key props are the single-series shorthand for `series`.\n const plotted = React.useMemo<readonly ConfidenceConeSeries[]>(() => {\n if (series?.length) return series;\n if (!actualKey || !forecastKey) return [];\n return [{ actualKey, forecastKey, lowerKey, upperKey }];\n }, [series, actualKey, forecastKey, lowerKey, upperKey]);\n\n const animation = resolveAnimation({\n animate,\n animationDuration,\n animationBegin,\n animationEasing,\n });\n // Memoized so recharts sees a stable content type across renders — a fresh\n // wrapper each render would remount the caller's tooltip and reset its state.\n const customTooltip = React.useMemo(\n () => (tooltipContent ? createConeTooltip(tooltipContent) : undefined),\n [tooltipContent]\n );\n\n const xAxisTitle = resolveXAxisTitle(xAxisLabel);\n const yAxisTitle = resolveYAxisTitle(yAxisLabel);\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n\n // One hue per metric. Each cone and forecast line already paints with its own\n // series' actual color; re-pointing that series' forecast key's `--color-*`\n // at it too means nothing downstream — a custom tooltip, a caller's\n // `var(--color-<forecastKey>)` — can reintroduce a second color.\n const seriesConfig = React.useMemo(() => {\n let next: ChartConfig | undefined;\n for (const { actualKey: aKey, forecastKey: fKey } of plotted) {\n const actual = config[aKey];\n const forecast = config[fKey];\n if (!actual || !forecast) continue;\n next ??= { ...config };\n next[fKey] = {\n label: forecast.label,\n icon: forecast.icon,\n tone: { sameAs: aKey },\n };\n }\n return next ?? config;\n }, [config, plotted]);\n\n const xAxisTickLabels = resolveXAxisTickLabels(\n data.map((row) => row[xKey]),\n xTickFormatter\n );\n const chartContainerRef = React.useRef<HTMLDivElement>(null);\n const xAxisLayout = useXAxisLayout(\n chartContainerRef,\n xAxisAngle,\n xAxisLabel,\n xAxisTickLabels.join('\\u0000')\n );\n\n // Augment each row with one `[lower, upper]` band tuple per coned series for\n // its Area to shade. Rows missing a numeric bound are left un-coned (the\n // band breaks there); a series without bounds gets no band at all.\n const chartData = data.map((row) => {\n const next: Record<string, unknown> = { ...row };\n for (const {\n actualKey: aKey,\n lowerKey: lKey,\n upperKey: uKey,\n } of plotted) {\n if (!lKey || !uKey) continue;\n const lower = row[lKey];\n const upper = row[uKey];\n next[bandKeyFor(aKey)] =\n typeof lower === 'number' && typeof upper === 'number'\n ? [lower, upper]\n : undefined;\n }\n return next;\n });\n\n const forecastX = forecastPeriodX(data, plotted, xKey);\n // Set the projected period off from the actuals with a shaded band + a\n // divider at the hand-off.\n const forecastStart = showForecastRegion ? forecastX[0] : undefined;\n const lastX = data[data.length - 1]?.[xKey];\n\n const renderForecastTick = createForecastTick(\n new Set(forecastX),\n `var(--color-${toCssKey(plotted[0]?.actualKey ?? '')})`,\n xTickFormatter\n );\n\n const referenceLines = referenceLine\n ? Array.isArray(referenceLine)\n ? referenceLine\n : [referenceLine]\n : [];\n\n // Everything from here to the `return` is lifted out of the returned tree\n // only to keep it readable as a flat list of chart children. Nothing in\n // recharts forces the `render*` helpers to be plain functions: axes and\n // series register themselves with the chart's store, and `<Cell>` is the\n // only child still looked up by element type — a component wrapper renders\n // fine (see AreaChart's `AreaFillGradients`). They stay functions because\n // they are declared inside the render body, where a component would get a\n // fresh element type on every render and remount its subtree.\n\n const renderAxes = () => (\n <>\n <XAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n tick={styleForecastTicks ? renderForecastTick : undefined}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={resolveRotatedTickAnchor(xAxisAngle)}\n height={xAxisLayout.height}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n hide={!showYAxis}\n tickLine={false}\n axisLine={false}\n unit={yUnit}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n </>\n );\n\n // Set the forecast region off from the actuals (behind everything).\n const renderForecastRegion = () => (\n <>\n {forecastStart != null && lastX != null && (\n <ReferenceArea\n x1={forecastStart}\n x2={lastX}\n fill=\"var(--ui-background-surface-secondary)\"\n fillOpacity={0.5}\n ifOverflow=\"extendDomain\"\n />\n )}\n {forecastStart != null && (\n <ReferenceLine\n x={forecastStart}\n stroke=\"var(--ui-border-on-surface-border)\"\n strokeDasharray=\"4 4\"\n />\n )}\n </>\n );\n\n const renderThreshold = (\n threshold: ConfidenceConeReferenceLine,\n index: number\n ) => (\n <ReferenceLine\n key={`${threshold.label ?? 'threshold'}-${index}`}\n y={threshold.value}\n stroke=\"var(--ui-text-on-surface-secondary)\"\n strokeDasharray=\"4 4\"\n // extendDomain so a threshold beyond the data max stays visible.\n ifOverflow=\"extendDomain\"\n label={\n threshold.label\n ? {\n value: threshold.label,\n position: 'insideTopRight',\n fill: 'var(--ui-text-on-surface-secondary)',\n fontSize: CHART_LABEL_FONT_SIZE,\n }\n : undefined\n }\n />\n );\n\n const renderTooltip = () =>\n customTooltip ? (\n // Strips the synthetic band before the caller's tooltip sees it — the\n // `__cone` series feeds the Area, not the tooltip.\n <ChartTooltip content={customTooltip} />\n ) : (\n <ChartTooltip\n content={(tp) => (\n <ChartTooltipContent\n active={tp.active}\n label={tp.label}\n // The synthetic band feeds the Area, not the tooltip.\n payload={\n dropConeBand(tp.payload) as ChartTooltipContentProps['payload']\n }\n />\n )}\n />\n );\n\n const renderLegend = () => (\n <ChartLegend\n content={(lp) => (\n <ChartLegendContent\n verticalAlign={lp.verticalAlign}\n fontSize={legendFontSize}\n payload={\n keepMetricSeries(\n lp.payload,\n plotted.map((s) => s.actualKey)\n ) as ChartLegendContentProps['payload']\n }\n />\n )}\n />\n );\n\n // One color per metric — actual and forecast differ by line style, not hue\n // — so a cone reuses its series' actual color.\n const renderConeBand = ({\n actualKey: aKey,\n lowerKey: lKey,\n upperKey: uKey,\n }: ConfidenceConeSeries) =>\n lKey && uKey ? (\n <Area\n key={bandKeyFor(aKey)}\n // The band paints in the same hue, at the same opacity, as the\n // actual series' own area, so nothing on the rendered path tells\n // the two apart. recharts forwards `data-*` onto the path it\n // draws; the tests select the band through this.\n data-slot=\"confidence-cone-band\"\n dataKey={bandKeyFor(aKey)}\n type=\"monotone\"\n stroke=\"none\"\n fill={`var(--color-${toCssKey(aKey)})`}\n fillOpacity={0.15}\n connectNulls={false}\n dot={false}\n activeDot={false}\n {...animation}\n legendType=\"none\"\n tooltipType=\"none\"\n />\n ) : null;\n\n const renderActualMark = ({ actualKey: aKey }: ConfidenceConeSeries) => {\n // An area and a line take the same props here; only the region under the\n // curve (and the mark recharts draws) differ. A `Line` gets no fill at\n // all — `fillOpacity: 0` would also erase its dots.\n const ActualMark = actualType === 'line' ? Line : Area;\n const areaFill =\n actualType === 'line'\n ? undefined\n : { fill: `var(--color-${toCssKey(aKey)})`, fillOpacity: 0.15 };\n // Observed points read as measured: LineChart's dot geometry (r 3, 2px\n // ring) filled with the metric hue. The ring is that same hue, so the\n // mark is solid — and wide enough against the 2px line not to read as a\n // mere thickening of it. `fillOpacity: 1` is load-bearing: recharts\n // merges the parent mark's own presentation props into every dot it\n // draws, so an `<Area>`'s 0.15 would otherwise wash the dot out to a halo.\n const dot = showDots\n ? {\n r: 3,\n fill: `var(--color-${toCssKey(aKey)})`,\n fillOpacity: 1,\n stroke: `var(--color-${toCssKey(aKey)})`,\n strokeWidth: 2,\n }\n : false;\n return (\n <ActualMark\n key={aKey}\n dataKey={aKey}\n type=\"monotone\"\n stroke={`var(--color-${toCssKey(aKey)})`}\n strokeWidth={strokeWidth}\n {...areaFill}\n dot={dot}\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n // The legend names the metric once, so it carries the swatch that\n // stands for the whole series rather than the actual line's style.\n legendType=\"rect\"\n />\n );\n };\n\n const renderForecastLine = ({\n actualKey: aKey,\n forecastKey: fKey,\n }: ConfidenceConeSeries) => {\n // Projected points read as predicted: the same LineChart dot, inverted —\n // the metric's hue as the ring, the surface color as the fill, so the\n // dashed line doesn't show through the middle. (LineChart leaves the fill\n // to recharts, whose `Line` defaults it to `#fff`; the token is that same\n // white in the light theme and also holds up in the dark one.)\n // `strokeDasharray: 'none'` is load-bearing: recharts merges the parent\n // mark's presentation props into every dot, so this line's `5 5` would\n // otherwise break each dot's ring into two arcs.\n const dot = showDots\n ? {\n r: 3,\n fill: 'var(--ui-background-surface-primary)',\n stroke: `var(--color-${toCssKey(aKey)})`,\n strokeWidth: 2,\n strokeDasharray: 'none',\n }\n : false;\n return (\n <Line\n key={fKey}\n dataKey={fKey}\n type=\"monotone\"\n stroke={`var(--color-${toCssKey(aKey)})`}\n strokeWidth={strokeWidth}\n strokeDasharray=\"5 5\"\n dot={dot}\n // Paired with `dot` the way every other chart does it — left unset,\n // the projection would keep recharts' default active dot while the\n // actuals had none (and a different radius when on).\n activeDot={showDots ? { r: 5 } : false}\n connectNulls\n {...animation}\n />\n );\n };\n\n return (\n <div ref={ref} className={cn(className)} {...props}>\n <ChartContainer\n ref={chartContainerRef}\n config={seriesConfig}\n palette={palette}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <ComposedChart\n data={chartData as readonly unknown[]}\n margin={mergeXAxisLayoutMargin(undefined, xAxisLayout.margin)}\n >\n {showGrid && (\n <CartesianGrid\n horizontal={gridHorizontal ?? true}\n vertical={gridVertical ?? false}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n {renderAxes()}\n {renderForecastRegion()}\n {referenceLines.map(renderThreshold)}\n {showTooltip && renderTooltip()}\n {showLegend && renderLegend()}\n {/* Every cone renders before any line, so the lines draw on top of\n all of them. */}\n {plotted.map(renderConeBand)}\n {plotted.map(renderActualMark)}\n {plotted.map(renderForecastLine)}\n </ComposedChart>\n </ChartContainer>\n </div>\n );\n }\n);\nConfidenceCone.displayName = 'ConfidenceCone';\n\nexport { ConfidenceCone };\n"],"mappings":"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"}