# Area chart

> Volumes over time as filled areas: overlapping gradients, stacked bands for parts of a total, or 100% stacked shares.

- Type: React component (Charts & Stats)
- Access: Pro (the source needs a Wingo UI Pro plan, see https://wingo-ui.com/pricing)
- Version: 1.0.0
- Install: `npx wingo-ui@latest add area-chart`
- Docs: https://wingo-ui.com/components/area-chart

## Interaction

Move the mouse over the plot for a crosshair, a dot on every band and a readout of every visible series (stacked charts list the top band first and add a Total row; percent charts show the value and its share, "$48,920 · 38.1%"). On a phone, tap a month to pin the readout above your finger, drag sideways to scrub (vertical drags still scroll the page), tap the same month again or anywhere outside to clear it. With the keyboard, Tab to the plot, then Left / Right walk the points, Home / End jump to the ends, PageUp / PageDown move by ten, Enter fires onDatumClick, Escape clears; a live region reads each point. Legend entries are buttons: click or tap one to hide or show its series (the stack re-flows with a glide), hover or focus one to highlight it. Switching type between overlap, stacked and percent glides the areas to their new shape and cross-fades the y ticks. Areas rise from the baseline and the lines draw in the first time the chart scrolls into view; reduced motion shows the final chart at once.

## Installation

```bash
npx wingo-ui@latest add area-chart
```

Pro item: run `npx wingo-ui@latest login` once with a Pro account. The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add @wingo-ui/area-chart` (needs the @wingo-ui registry with your API key in components.json)

Files:

- `components/ui/area-chart.tsx`

npm dependencies: `npm i motion d3-shape d3-scale && npm i -D @types/d3-shape @types/d3-scale`

Wingo UI dependencies (installed automatically):

- [Chart kit](https://wingo-ui.com/components/chart-kit) ([Markdown](https://wingo-ui.com/components/chart-kit.md))
- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))
- [UIProvider](https://wingo-ui.com/components/ui-config) ([Markdown](https://wingo-ui.com/components/ui-config.md))
- [useLocale](https://wingo-ui.com/components/use-locale) ([Markdown](https://wingo-ui.com/components/use-locale.md))

## Usage

```tsx
import { AreaChart } from "@/components/ui/area-chart"

const data = [
  { month: "2026-07", direct: 41460, online: 28700, partners: 18070 },
  { month: "2026-08", direct: 38030, online: 27300, partners: 15600 },
  { month: "2026-09", direct: 48920, online: 36400, partners: 22130 },
]

export function RevenueByChannel() {
  return (
    <AreaChart
      data={data}
      xKey="month"
      series={[
        { key: "direct", label: "Direct sales" },
        { key: "online", label: "Online store" },
        { key: "partners", label: "Partners" },
      ]}
      type="stacked"
      valueFormat="currency"
      currency="USD"
      label="Revenue by channel, 2026"
    />
  )
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `data` | `ChartDatum[]` |  | One row per x position: { month: "2026-09", direct: 48920, online: 36400 }. Data order is x order (the chart does not sort). |
| `xKey?` | `string` | `"date"` | The row key for the x axis. ISO days ("2026-09-24") and months ("2026-09") print as local dates. |
| `series?` | `AreaChartSeries[]` |  | Which keys to draw ({ key, label?, color?, name? }), in color and stack order: series 1 is the bottom band. Inferred from the numeric keys of the first rows when omitted. |
| `colors?` | `string[]` |  | Per-position palette overrides: slots ("series-3"), tones ("neutral", "brand", "success") or any css color. |
| `type?` | `"overlap" \| "stacked" \| "percent"` | `"overlap"` | overlap: every area from zero, the first series on top. stacked: bands add up (negative values stack below zero, diverging). percent: 100% stacked shares, y axis 0 to 100 %, the readout and table add each share with one decimal ("38,1 %"), negatives drawn as 0. |
| `fill?` | `"gradient" \| "solid" \| "none"` | `"gradient"` | gradient fades the series color from fillOpacity to transparent; solid is a flat fill at fillOpacity; none draws lines only (always on, whatever showLine says). |
| `fillOpacity?` | `number` | `0.22` | The top of the gradient or the solid fill. Stacked bands add 0.1 so they read as bands; overlapping fills of two or more series never exceed 0.22. |
| `showLine?` | `boolean` | `true` | The line on each area's top edge. Stacked bands keep a thin surface gap between them without it. |
| `curve?` | `"monotone" \| "linear" \| "natural" \| "step"` | `"monotone"` | How points are joined. monotone never overshoots the data. |
| `strokeWidth?` | `number` | `2` | Width of the top lines in px. |
| `connectNulls?` | `boolean` | `false` | Bridge null gaps instead of breaking the area (overlap only; stacked types treat nulls as 0). |
| `height?` | `number` | `240` | Plot height in px, reserved before measuring so nothing jumps. The width always fills the parent. |
| `valueFormat?` | `ChartValueFormat = "number" \| "compact" \| "currency" \| "percent"` | `"number"` | How values print in the readout, the ticks and the table: "128,450", "128K", "$128,450", "12.4%" (percent takes whole numbers). Ticks go compact on their own from 10,000. |
| `currency?` | `string` | `"USD"` | ISO 4217 code for valueFormat="currency", printed with its narrow symbol ("$", "€"). Anything that is not a three-letter code prints as plain numbers with the text as a suffix. |
| `decimals?` | `number` |  | Fraction digits in the readout and the table (ticks stay short). Auto by magnitude. |
| `formatValue?` | `(value: number, context: { series: string; kind: "tooltip" \| "tick" \| "label" \| "table" }) => string` |  | Full control over value text, e.g. v => `${v} units`. Percent ticks and shares keep the kit format. |
| `formatX?` | `(value: unknown, context: "axis" \| "tooltip" \| "table") => string` |  | x labels; default formatChartLabel ("Sep" on the axis, "September 2026" in the readout). |
| `locale?` | `string` | `""` | Intl locale for numbers and dates; empty uses UIProvider's locale, then the page's. |
| `yDomain?` | `AreaChartDomain = [number \| "auto", number \| "auto"]` | `"[\"auto\", \"auto\"]"` | Fixed value bounds. Areas always include zero; percent charts are always 0 to 100. |
| `showGrid?` | `boolean` | `true` | Hairlines at the value ticks. |
| `showXAxis?` | `boolean` | `true` | x labels under the plot, thinned from the newest backwards so they never collide. |
| `showYAxis?` | `boolean` | `true` | Value tick labels. |
| `yAxisSide?` | `"start" \| "end"` | `"start"` | end puts the value ticks on the right (finance style). |
| `showLegend?` | `boolean` | `true` | The legend; only rendered with two or more series (one series is named by the card title). |
| `legendPosition?` | `"top" \| "bottom"` | `"top"` | Legend above or below the plot. It wraps on narrow widths. |
| `legendToggle?` | `boolean` | `true` | Legend entries are buttons that hide and show their series (the last visible series cannot be hidden). |
| `showTooltip?` | `boolean` | `true` | The floating readout. When off, the crosshair, keyboard and live region still work. |
| `tooltipMode?` | `"auto" \| "float" \| "fixed"` | `"auto"` | float rides beside the crosshair, fixed pins above the plot; auto is fixed on touch screens. |
| `referenceLines?` | `{ value: number; label?: string; color?: string }[]` |  | Dashed targets or averages ("Media 261"). In percent charts the value is a share (0 to 100). |
| `animated?` | `boolean` | `true` | Areas rise and lines draw the first time the chart scrolls into view; data, type and legend changes glide. |
| `loading?` | `boolean` | `false` | A skeleton in the plot's shape, same height. |
| `emptyState?` | `ReactNode` |  | Shown when data is empty or every value is null. Default: an icon tile and labels.empty. |
| `label?` | `string` | `""` | Accessible name of the figure and caption of its data table. Empty joins the series names. |
| `description?` | `string` | `""` | A one-sentence takeaway for screen readers (aria-describedby). |
| `surface?` | `string` | `""` | The color behind the chart, used for dot rings and the gaps between stacked bands. Empty = var(--surface). |
| `hiddenSeries?` | `string[]` |  | Hidden series keys (controlled). Pair with onHiddenSeriesChange. |
| `defaultHiddenSeries?` | `string[]` | `"[]"` | Series hidden at first (uncontrolled). |
| `onHiddenSeriesChange?` | `(keys: string[]) => void` |  | Called when a legend toggle hides or shows a series. |
| `activeIndex?` | `number \| null` |  | The inspected x index (controlled), so two charts can share one crosshair. |
| `defaultActiveIndex?` | `number \| null` | `"null"` | The inspected index at first (uncontrolled). |
| `onActiveIndexChange?` | `(index: number \| null) => void` |  | Called while hovering, scrubbing or walking with the keyboard. |
| `onDatumClick?` | `(event: { index: number; datum: ChartDatum; series?: string }) => void` |  | A click on the plot (series = the band under the pointer) or Enter on the inspected point (series = the first visible one). |
| `labels?` | `Partial<AreaChartLabels>` |  | English defaults: empty, loading, table, total, other, inspectHint, showSeries, hideSeries and shareColumn (the percent table's share column). |
| `classNames?` | `Partial<Record<"legend" \| "plot" \| "tooltip" \| "table" \| "area" \| "line" \| "dot" \| "grid" \| "xAxis" \| "yAxis", string>>` |  | Extra classes for the inner parts. |
| `className?` | `string` |  | Extra classes for the figure root, merged last. |

## Parts

### DEFAULT_AREA_CHART_LABELS (constant)

The English strings the chart uses (empty and loading text, the data table, the keyboard hint, show and hide series, the share column of a percent chart). Spread it and override what you translate.

### AreaChartLabels (type)

The shape of labels: the chart kit's shared strings plus shareColumn(series) for the percent table.

### AreaChartSeries (type)

One drawn key: { key, label?, color?, name? }, in color and stack order.

## Examples

- **Overlap of two**: Collected vs. expenses as overlapping gradients.
- **100% stacked**: Channel shares per month, y axis 0 to 100%.
- **Solid bands, no lines**: Stock per warehouse, weekly, with a custom value format.
- **Neutral with an average**: A single monochrome area and a dashed reference line.
- **Loading and empty**: The skeleton and the empty state keep the plot's height.
- **Phone**: Five stacked series at 360px with the pinned readout.

## See also

- [Line chart](https://wingo-ui.com/components/line-chart) ([Markdown](https://wingo-ui.com/components/line-chart.md))
- [Bar chart](https://wingo-ui.com/components/bar-chart) ([Markdown](https://wingo-ui.com/components/bar-chart.md))
- [Donut chart](https://wingo-ui.com/components/donut-chart) ([Markdown](https://wingo-ui.com/components/donut-chart.md))
- [Chart kit](https://wingo-ui.com/components/chart-kit) ([Markdown](https://wingo-ui.com/components/chart-kit.md))
- [Segmented Control](https://wingo-ui.com/components/segmented-control) ([Markdown](https://wingo-ui.com/components/segmented-control.md))

---

Canonical: https://wingo-ui.com/components/area-chart
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
