Area Chart

A composable area chart with gradient fills, tooltips, and hover interactions

Preview

Installation

pnpm dlx shadcn@latest add https://ui.bklit.com/r/area-chart.json

Usage

The Area Chart uses the same composable API as the Line Chart. Build charts by combining components:

import { AreaChart, Area, Grid, XAxis, ChartTooltip } from "@bklitui/ui/charts";

const data = [
  { date: new Date("2025-01-01"), revenue: 12000, costs: 8500 },
  { date: new Date("2025-01-02"), revenue: 13500, costs: 9200 },
  // ... more data
];

export default function RevenueChart() {
  return (
    <AreaChart data={data}>
      <Grid horizontal />
      <Area dataKey="revenue" fill="var(--chart-line-primary)" />
      <Area dataKey="costs" fill="var(--chart-line-secondary)" />
      <XAxis />
      <ChartTooltip />
    </AreaChart>
  );
}

Components

AreaChart

The root component that provides context to all children. It shares the same props as LineChart.

PropTypeDefaultDescription
dataRecord<string, unknown>[]requiredArray of data points
xDataKeystring"date"Key in data for x-axis values
marginPartial<Margin>{ top: 40, right: 40, bottom: 40, left: 40 }Chart margins
animationDurationnumber1100Animation duration in ms
aspectRatiostring"2 / 1"CSS aspect ratio
classNamestring""Additional CSS class

Area

Renders a filled area on the chart with a gradient fill.

PropTypeDefaultDescription
dataKeystringrequiredKey in data for y values
fillstringvar(--chart-line-primary)Gradient fill color
fillOpacitynumber0.4Fill opacity at the top
strokestringSame as fillLine stroke color
strokeWidthnumber2Line stroke width
curveCurveFactorycurveMonotoneXD3 curve function
animatebooleantrueEnable grow animation
showLinebooleantrueShow stroke line on top
showHighlightbooleantrueShow highlight on hover
gradientToOpacitynumber0Opacity at bottom of gradient

Examples

Single Area

A minimal area chart with one metric:

<AreaChart data={data}>
  <Area dataKey="value" fill="#3b82f6" />
  <ChartTooltip />
</AreaChart>

Stacked Appearance

Layer multiple areas to show composition. Note: This creates a visual layering effect, not true stacking:

<AreaChart data={data}>
  <Grid horizontal />
  <Area
    dataKey="total"
    fill="var(--chart-line-primary)"
    fillOpacity={0.2}
  />
  <Area
    dataKey="completed"
    fill="#10b981"
    fillOpacity={0.4}
  />
  <XAxis />
  <ChartTooltip />
</AreaChart>

Custom Gradient

Control the gradient fade with gradientToOpacity:

// Solid fill (no gradient fade)
<Area
  dataKey="revenue"
  fill="#3b82f6"
  fillOpacity={0.3}
  gradientToOpacity={0.3}
/>

// Soft gradient (default)
<Area
  dataKey="revenue"
  fill="#3b82f6"
  fillOpacity={0.4}
  gradientToOpacity={0}
/>

// Strong contrast gradient
<Area
  dataKey="revenue"
  fill="#3b82f6"
  fillOpacity={0.6}
  gradientToOpacity={0.05}
/>

Area Without Stroke Line

Hide the top line for a softer appearance:

<AreaChart data={data}>
  <Area
    dataKey="value"
    fill="var(--chart-line-primary)"
    fillOpacity={0.5}
    showLine={false}
  />
  <ChartTooltip />
</AreaChart>

Different Curves

The Area component supports different curve interpolations:

import { curveMonotoneX, curveLinear, curveStep, curveBasis } from "@visx/curve";

// Smooth monotonic (default) - prevents overshooting
<Area dataKey="value" curve={curveMonotoneX} />

// Linear - straight lines between points
<Area dataKey="value" curve={curveLinear} />

// Step - discrete steps
<Area dataKey="value" curve={curveStep} />

// Basis - very smooth, may not pass through points
<Area dataKey="value" curve={curveBasis} />

With Custom Tooltip

<AreaChart data={data}>
  <Grid horizontal />
  <Area dataKey="revenue" fill="var(--chart-line-primary)" />
  <XAxis />
  <ChartTooltip
    rows={(point) => [
      {
        color: "var(--chart-line-primary)",
        label: "Revenue",
        value: `$${point.revenue?.toLocaleString()}`,
      },
    ]}
  />
</AreaChart>

Dashboard Metrics Card

import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { AreaChart, Area, ChartTooltip } from "@bklitui/ui/charts";

export function MetricsCard({ title, data, dataKey, color }) {
  const latestValue = data[data.length - 1]?.[dataKey] ?? 0;

  return (
    <Card>
      <CardHeader className="pb-2">
        <CardTitle className="text-sm font-medium text-muted-foreground">
          {title}
        </CardTitle>
        <div className="text-2xl font-bold">
          ${latestValue.toLocaleString()}
        </div>
      </CardHeader>
      <CardContent>
        <AreaChart
          data={data}
          aspectRatio="3 / 1"
          margin={{ top: 5, right: 5, bottom: 5, left: 5 }}
        >
          <Area
            dataKey={dataKey}
            fill={color}
            fillOpacity={0.3}
            strokeWidth={1.5}
            showHighlight={false}
          />
          <ChartTooltip showDatePill={false} />
        </AreaChart>
      </CardContent>
    </Card>
  );
}

Comparison Chart

Compare two time series with different colored areas:

<AreaChart data={comparisonData}>
  <Grid horizontal />
  <Area
    dataKey="thisYear"
    fill="var(--chart-line-primary)"
    fillOpacity={0.4}
    strokeWidth={2}
  />
  <Area
    dataKey="lastYear"
    fill="var(--chart-line-secondary)"
    fillOpacity={0.2}
    strokeWidth={1.5}
  />
  <XAxis />
  <ChartTooltip
    rows={(point) => [
      { color: "var(--chart-line-primary)", label: "This Year", value: point.thisYear },
      { color: "var(--chart-line-secondary)", label: "Last Year", value: point.lastYear },
    ]}
  />
</AreaChart>

Combining with Line Chart

You can mix Area and Line components in the same chart using the LineChart container:

import { LineChart, Line, Area, Grid, ChartTooltip } from "@bklitui/ui/charts";

<LineChart data={data}>
  <Grid horizontal />
  {/* Background area for context */}
  <Area
    dataKey="baseline"
    fill="var(--chart-grid)"
    fillOpacity={0.3}
    showLine={false}
  />
  {/* Main line for the primary metric */}
  <Line dataKey="actual" stroke="var(--chart-line-primary)" />
  <ChartTooltip />
</LineChart>

Theming

The Area Chart uses the same CSS variables as the Line Chart:

:root {
  --chart-background: oklch(1 0 0);
  --chart-foreground: oklch(0.145 0.004 285);
  --chart-foreground-muted: oklch(0.55 0.014 260);
  --chart-line-primary: oklch(0.623 0.214 255);
  --chart-line-secondary: oklch(0.705 0.015 265);
  --chart-crosshair: oklch(0.4 0.1828 274.34);
  --chart-grid: oklch(0.9 0 0);
}

.dark {
  --chart-background: oklch(0.145 0 0);
  --chart-foreground: oklch(0.45 0 0);
  --chart-crosshair: oklch(0.45 0 0);
  --chart-grid: oklch(0.25 0 0);
}

Dependencies

This component requires the same packages as the Line Chart:

pnpm add @visx/shape @visx/curve @visx/scale @visx/gradient @visx/responsive @visx/event @visx/grid d3-array motion react-use-measure