AreaChart
A filled trend over time — stacked to show a total, normalized to show share, or overlapping for two or three series. Strokes the top edge of each band so a stack stays readable where two fills meet, and takes `gradient` to fade the fill out toward its baseline.
<UiAreaChart :data="..." :categoryKey="..." :series="..." :ariaLabel="..." />Needs the charts module
This component ships in @jgastager/bundy-ui/charts, a separate module so projects that never draw a chart don't carry the paint classes these need. Nothing extra to install — just add the module entry. See Charts.
Data
requireddata is one object per x position with one field per series — the wide shape your API already returns, so nothing needs melting into long form first.
- Desktop
- Mobile
- Tablet
data stays in the wide shape an API returns ({ month: "Jan", desktop: 120, mobile: 80 }); the component folds it into the long rows the marks want. Rows whose value isn't a finite number are dropped rather than zeroed, so a gap in the data reads as a gap.
There's no animate prop. The marks are plain SVG elements Vue patches directly, so a data change re-renders rather than tweening; what motion there is comes from CSS transitions on hover, which this chart doesn't have.
Category key
requiredcategoryKey sets which field on each row is its x value.
Series
requiredseries is field names, or { key, label, color } objects when the legend needs better words than your column names. Order assigns the default colours and, when stacked, the band order — so put the series that needs reading accurately first, since only the bottom band keeps a flat baseline.
Colors are the library's own semantic ones — primary, secondary, success, warning, error, info, pending, neutral — and any shade of them, primary-400 through primary-950, exactly as the bg-* utilities spell them. Set color per series (or per item) to pin one; leave it unset to take the next slot of the default sequence. neutral and secondary are never handed out automatically, so an unlabelled series never lands on them.
ARIA label
requiredariaLabel sets what the chart shows, in one sentence. Required — an unlabelled chart is an unreadable one.
- Desktop
- Mobile
- Tablet
ARIA description
ariaDescription is the detail the label shouldn't carry — the trend a sighted reader gets from the shape.
- Desktop
- Mobile
- Tablet
Variant
variant decides what the stack means. stacked sits the bands on each other so the top edge is the total — usually the question an area chart is being asked. normalized stacks to a full 100% at every position, turning it into a share-over-time read where the total disappears. overlapped starts every band at zero so they share a baseline; readable for two or three series and no more.
- Desktop
- Mobile
- Tablet
- Desktop
- Mobile
- Tablet
- Desktop
- Mobile
- Tablet
variant decides the baseline, and that decides what's readable. stacked (the default) gives only the bottom band a flat baseline; overlapped gives every band one but only survives two or three series; normalized shows share and hides the total entirely.
Curve
curve sets how the top edge gets between points. smooth is monotone cubic — it rounds corners without bulging past a value the data never contained.
Line
line strokes the *top* edge of each band only — not an outline around the fill, which would trace the baseline and sides too and turn a stack into a set of boxes. Turn it off for a softer read.
- Desktop
- Mobile
- Tablet
- Desktop
- Mobile
- Tablet
line strokes the *top* edge only, not an outline around the fill. That needs the bands pre-stacked: areaY's own boundary stroke would trace the baseline and sides too, and a plain lineY over the raw values wouldn't stack at all.
Gradient
gradient fades each band out toward its baseline, so it reads as weight under the line rather than as a solid slab. Separate from variant on purpose — painting and stacking are different questions, and any variant can be gradient-filled.
- Desktop
- Mobile
- Tablet
gradient fades each band out toward its baseline. It's a separate prop from variant because it's about how a band is painted, not how bands relate — stacked, overlapped and normalized can each be gradient-filled or flat.
Fill opacity
fillOpacity applies to the flat fill under each line. Drop it when the bands overlap and you need to see through them; it does nothing under a gradient fill.
- Desktop
- Mobile
- Tablet
- Desktop
- Mobile
- Tablet
X label
xLabel names what the x ticks are counting, for the cases the surrounding copy doesn't.
Y label
yLabel is the same, for the value axis.
- Desktop
- Mobile
- Tablet
Value format
valueFormat covers the y ticks and the tooltip together, so a formatted axis can never disagree with the panel beside it. A normalized chart formats its own axis as percentages and ignores this for the ticks, since the numbers there are shares rather than amounts.
Category format
categoryFormat rewrites the x tick labels without touching your data — how a key like 2025-03 becomes Mar.
Grid
grid is the horizontal rules from the y ticks. Dropping them keeps the axes.
- Desktop
- Mobile
- Tablet
Tooltip
tooltip is the crosshair and the panel that follows it, dropped together.
- Desktop
- Mobile
- Tablet
Legend
legend is on by default from two series up, and off for one — a single band needs no key. Force it off when the surrounding heading already names what's plotted.
Legend position
legendPosition moves the key above or below the plot. top reads as part of a heading when the chart sits directly under one.
- Desktop
- Mobile
- Tablet
Legend align
legendAlign places the key horizontally — start lines it up with the plot's left edge, which is where the eye already is after reading the axis.
- Desktop
- Mobile
- Tablet
- Desktop
- Mobile
- Tablet
- Desktop
- Mobile
- Tablet
Legend orientation
legendOrientation flows the entries in a row or a column. vertical gives long labels their own line, at the cost of height.
- Desktop · 8,680 visits
- Mobile · 7,630 visits
- Tablet · 1,430 visits
Guides
guides drops the axes and the margins they reserve, so the bands fill the box. That plus a small height is the sparkline shape — an area sparkline reads as volume where a line reads as direction.
guides="false" drops the axes, ticks, labels and grid *and* the margins they reserve, so the marks fill the whole box. That plus a small height is the inline-sparkline shape — there's no separate component for it.
Height
height is the plot's height in pixels. Ignored once aspectRatio is set.
Aspect ratio
aspectRatio sizes the chart from its container's width instead of a fixed height, so it keeps its proportions across breakpoints.
- Desktop
- Mobile
- Tablet
Loading
loading is a skeleton at the chart's exact height. An empty data array gets the empty state instead — both hold the height, so a dashboard doesn't reflow as its panels resolve.
- Desktop
- Mobile
- Tablet
- Desktop
- Mobile
- Tablet
@focus-change
The category under the pointer, or null once it leaves — for driving a readout, a linked row, or a second chart scrubbing alongside this one.
Month:—
- Desktop
- Mobile
- Tablet
API Reference
Generated from the component's source — props, slots and emits as the component actually declares them.
Props
seriesrequiredChartSeriesInput[]ariaLabelrequiredstring"stacked" | "overlapped" | "normalized"'stacked'Emits
focusChange[category: string | null]Types
interface ChartPlot {
x: number;
y: number;
width: number;
height: number;
/** Right edge, since marks need it more often than the width. */
right: number;
/** Bottom edge, which is also the x axis' baseline. */
bottom: number;
}type ChartSeriesInput = string | ChartSeries;type ChartCurveName = "linear" | "smooth" | "step" | "step-before" | "step-after";