/

Area Chart

Visualize quantitative data as filled regions under a line. Ideal for showing volume, cumulative totals, and composition over time with stacked or gradient fills.

MonTueWedThuFri1.2K1.4K1.6K1.8K2K2.2K

Quick Start

import { AreaChart } from "@chartts/react"
 
const data = [
  { month: "Jan", users: 1200 },
  { month: "Feb", users: 1800 },
  { month: "Mar", users: 2400 },
  { month: "Apr", users: 2100 },
  { month: "May", users: 3200 },
  { month: "Jun", users: 4100 },
]
 
export function UserGrowthChart() {
  return (
    <AreaChart
      data={data}
      x="month"
      y="users"
      className="h-64 w-full"
    />
  )
}

That renders a filled area chart with smooth curves, axes, tooltips, gradient fill, and responsive scaling. All automatic.

When to Use Area Charts

Area charts are line charts with the region below filled in. The fill adds visual weight, making them better at conveying volume and magnitude than a plain line.

Use an area chart when:

  • Showing volume or magnitude over time (total users, cumulative revenue)
  • Emphasizing the size of a value rather than just its trend
  • Comparing the contribution of multiple series with stacking
  • Your audience should perceive "how much" not just "which direction"

Use a stacked area chart when:

  • Showing how parts compose a total over time (traffic by channel, revenue by product)
  • The total matters as much as the individual parts
  • You have 2 to 5 series (more than 5 becomes hard to read)

Don't use an area chart when:

  • You have multiple overlapping series without stacking (lines will be hidden behind fills)
  • Categories have no natural order (use a bar chart)
  • You want to compare exact values between series (use a grouped bar chart)
  • Series values are on very different scales (the smaller one will be invisible)

Props Reference

PropTypeDefaultDescription
dataT[]requiredArray of data objects
xkeyof TrequiredKey for x-axis values
ykeyof T | (keyof T)[]requiredKey(s) for y-axis values. Pass array for multi-series
stackedbooleanfalseStack areas on top of each other
curve'linear' | 'monotone' | 'step' | 'natural''monotone'Interpolation between points
gradientbooleantrueApply a vertical gradient fill from opaque to transparent
opacitynumber0.3Fill opacity (0 to 1)
animatebooleantrueEnable area reveal animation on mount
classNamestring-Tailwind classes on the root SVG
areaClassNamestring-Tailwind classes on the filled area
lineClassNamestring-Tailwind classes on the top edge line
axisClassNamestring-Tailwind classes on axis elements
gridClassNamestring-Tailwind classes on grid lines
tooltipClassNamestring-Tailwind classes on tooltip
responsivebooleantrueAuto-resize to container width
widthnumberautoFixed width in pixels
heightnumberautoFixed height in pixels

Stacked Areas

Set stacked with multiple y keys to layer areas on top of each other. Each series fills the space between itself and the series below it, and the topmost edge shows the total.

const data = [
  { month: "Jan", organic: 800, paid: 300, referral: 100 },
  { month: "Feb", organic: 950, paid: 450, referral: 200 },
  { month: "Mar", organic: 1100, paid: 600, referral: 350 },
  { month: "Apr", organic: 1250, paid: 700, referral: 400 },
  { month: "May", organic: 1400, paid: 850, referral: 500 },
]
 
<AreaChart
  data={data}
  x="month"
  y={["organic", "paid", "referral"]}
  stacked
  className="h-72"
/>

Without stacked, multiple areas overlap each other. This makes the front-most series obscure those behind it, which is rarely what you want. Use stacked whenever you have more than one series.

Series ordering

The order of keys in the y array determines the stacking order. The first key sits at the bottom, the last key sits at the top. Place the most stable or largest series at the bottom for a cleaner look.

// "organic" is on the bottom, "referral" on top
<AreaChart data={data} x="month" y={["organic", "paid", "referral"]} stacked />

Gradient Fills

The gradient prop controls whether the area fill uses a vertical gradient that fades from the fill color at the top edge to transparent at the baseline. This is enabled by default.

// Gradient fill (default)
<AreaChart data={data} x="month" y="users" gradient />
 
// Solid fill - no gradient
<AreaChart data={data} x="month" y="users" gradient={false} />

Gradient fills make charts feel lighter and more polished. Solid fills are better when you need to clearly show the boundary between stacked series.

Combining gradient with opacity

The opacity and gradient props work together. The opacity value sets the maximum opacity at the top of the gradient, fading to zero at the baseline.

// Subtle fill
<AreaChart data={data} x="month" y="users" gradient opacity={0.15} />
 
// Bold fill
<AreaChart data={data} x="month" y="users" gradient opacity={0.6} />
 
// Fully opaque, no gradient
<AreaChart data={data} x="month" y="users" gradient={false} opacity={1} />

Curve Interpolation

The curve prop controls how the area boundary connects data points. The same options available on LineChart work here.

monotone (default)

Smooth curves that pass through every data point without overshooting. Produces the most natural-looking area charts.

<AreaChart data={data} x="month" y="users" curve="monotone" />

linear

Straight segments between points. Creates a jagged, angular fill. Use when you want precision over aesthetics, or when data changes are abrupt.

<AreaChart data={data} x="month" y="users" curve="linear" />

step

Flat horizontal segments that jump at each data point. The area is filled as rectangular blocks. Use for discrete state changes like pricing tiers, inventory levels, or status counts.

<AreaChart data={data} x="month" y="inventory" curve="step" />

natural

Cubic spline interpolation producing very smooth curves. Can overshoot values between data points. Use when visual smoothness matters more than strict accuracy.

<AreaChart data={data} x="month" y="users" curve="natural" />

Multi-Series

Pass an array of keys to y to render multiple area series on the same chart:

const data = [
  { month: "Jan", desktop: 3200, mobile: 1800, tablet: 600 },
  { month: "Feb", desktop: 3500, mobile: 2200, tablet: 700 },
  { month: "Mar", desktop: 3800, mobile: 2800, tablet: 850 },
]
 
<AreaChart
  data={data}
  x="month"
  y={["desktop", "mobile", "tablet"]}
  stacked
/>

Each series gets a color from the default palette. A legend appears showing which color maps to which series. Override colors per-series with seriesClassName:

<AreaChart
  data={data}
  x="month"
  y={["desktop", "mobile", "tablet"]}
  stacked
  seriesClassName={{
    desktop: "fill-blue-500 stroke-blue-500",
    mobile: "fill-emerald-500 stroke-emerald-500",
    tablet: "fill-amber-400 stroke-amber-400",
  }}
/>

Styling with Tailwind

Every visual element of the chart exposes a className prop. Style area charts the same way you style everything else in your app.

<AreaChart
  data={data}
  x="month"
  y="revenue"
  className="rounded-xl bg-zinc-900/50 p-4"
  areaClassName="fill-cyan-500/20"
  lineClassName="stroke-cyan-400 stroke-2"
  axisClassName="text-zinc-500 text-xs"
  gridClassName="stroke-zinc-800"
  tooltipClassName="bg-zinc-800 text-white rounded-lg shadow-xl px-3 py-2 text-sm"
/>

Dark mode works with Tailwind's dark: variants:

<AreaChart
  areaClassName="fill-blue-500/20 dark:fill-blue-400/20"
  lineClassName="stroke-blue-600 dark:stroke-blue-400"
  axisClassName="text-gray-600 dark:text-gray-400"
/>

Controlling fill opacity with Tailwind

You can use Tailwind opacity modifiers on areaClassName instead of the opacity prop for more granular control:

// Per-class opacity
<AreaChart
  data={data}
  x="month"
  y="users"
  areaClassName="fill-indigo-500/10"
  lineClassName="stroke-indigo-500"
/>

Tooltips

Tooltips appear on hover by default. They show the x-value and all y-values at the hovered position, with a vertical crosshair line.

Disable tooltips:

<AreaChart data={data} x="month" y="users" tooltip={false} />

Custom tooltip format:

<AreaChart
  data={data}
  x="month"
  y="users"
  tooltipFormat={(point) => `${point.users.toLocaleString()} active users`}
/>

For stacked area charts, the tooltip shows each series value and the total:

<AreaChart
  data={data}
  x="month"
  y={["organic", "paid", "referral"]}
  stacked
  tooltipFormat={(point) => ({
    organic: `${point.organic} organic`,
    paid: `${point.paid} paid`,
    referral: `${point.referral} referral`,
    total: `${point.organic + point.paid + point.referral} total`,
  })}
/>

Animation

Areas animate in with a reveal effect on mount. The filled region expands from the baseline upward over 800ms.

Disable animation for instant rendering (useful for SSR or when the chart is below the fold):

<AreaChart data={data} x="month" y="users" animate={false} />

The animation respects prefers-reduced-motion. When the user has motion reduction enabled, charts render immediately without animation.


Accessibility

Area charts include full accessibility support by default:

  • Screen readers: Each data point is announced with its x-value and y-value. For stacked charts, the individual contribution and total are both announced.
  • Keyboard navigation: Tab to focus the chart, then use arrow keys to move between data points. The tooltip follows the focused point.
  • ARIA roles: The chart has role="img" with a descriptive aria-label. Individual areas have role="group" with labels for each series.
  • High contrast: The top edge line ensures the area boundary is visible even at low fill opacity. This helps users who have difficulty distinguishing subtle color variations.

Server-Side Rendering

Area charts render as static SVG on the server. No client JavaScript required for the initial render. This means:

  • Zero layout shift on page load
  • Works in React Server Components
  • Works with renderToString() for non-React environments
  • SEO-friendly (SVG content is in the HTML)
  • Gradient fills are defined as SVG <linearGradient> elements, so they work without JavaScript
// Server component - no "use client" needed
import { AreaChart } from "@chartts/react"
 
export default async function Dashboard() {
  const data = await fetchTrafficData()
  return (
    <AreaChart
      data={data}
      x="date"
      y={["organic", "paid", "direct"]}
      stacked
      animate={false}
    />
  )
}

Real-World Examples

Website traffic by channel

<AreaChart
  data={trafficData}
  x="week"
  y={["organic", "paid", "social", "direct"]}
  stacked
  gradient
  seriesClassName={{
    organic: "fill-emerald-500 stroke-emerald-500",
    paid: "fill-blue-500 stroke-blue-500",
    social: "fill-violet-500 stroke-violet-500",
    direct: "fill-amber-400 stroke-amber-400",
  }}
  className="h-80"
/>

CPU usage over time

<AreaChart
  data={cpuMetrics}
  x="timestamp"
  y="utilization"
  curve="step"
  gradient
  opacity={0.4}
  lineClassName="stroke-red-500 stroke-[1.5]"
  areaClassName="fill-red-500"
  className="h-48"
/>

Revenue vs costs with margin

<AreaChart
  data={financials}
  x="month"
  y={["revenue", "costs"]}
  stacked={false}
  gradient
  opacity={0.2}
  seriesClassName={{
    revenue: "fill-emerald-500 stroke-emerald-500",
    costs: "fill-red-400 stroke-red-400",
  }}
  className="h-72"
/>

Other Charts