Skip to main content
Nexus Design System
GitHub

Chart

Plot rows of data with BarChart, LineChart, AreaChart or PieChart. Each key in series is one series, colored in order. For a chart they don't cover, compose Recharts parts inside ChartContainer and set each series' label and color in config.

'use client';

import { BarChart } from '@/components/nxds/components/chart/chart';

const visitors = [
  { month: 'Jan', desktop: 186, mobile: 80 },
  { month: 'Feb', desktop: 305, mobile: 200 },
  { month: 'Mar', desktop: 237, mobile: 120 },
  { month: 'Apr', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'Jun', desktop: 264, mobile: 140 },
];

export default function ChartBars() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <BarChart data={visitors} xKey="month" series={['desktop', 'mobile']} />
    </div>
  );
}

Installation

npx nxds-cli@latest add chart

Run npx nxds-cli@latest init first if nxds isn’t set up in your app yet. See Install.

Usage

import {
  AreaChart,
  BarChart,
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
  LineChart,
  PieChart,
} from '@/components/nxds/components/chart/chart';

Composition

BarChart
LineChart
AreaChart
PieChart
ChartContainer
├── ChartTooltip
│   └── ChartTooltipContent
└── ChartLegend
    └── ChartLegendContent

Examples

Stacked bar chart

Stack the series in one bar per category with stacked.

'use client';

import { BarChart } from '@/components/nxds/components/chart/chart';

const visitors = [
  { month: 'Jan', desktop: 186, mobile: 80 },
  { month: 'Feb', desktop: 305, mobile: 200 },
  { month: 'Mar', desktop: 237, mobile: 120 },
  { month: 'Apr', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'Jun', desktop: 264, mobile: 140 },
];

export default function ChartStackedBars() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <BarChart
        data={visitors}
        xKey="month"
        series={['desktop', 'mobile']}
        stacked
      />
    </div>
  );
}

Horizontal bar chart

Run the bars left to right with orientation="horizontal". The categories move to the y-axis.

'use client';

import { BarChart } from '@/components/nxds/components/chart/chart';

const browsers = [
  { browser: 'Chrome', visitors: 275 },
  { browser: 'Safari', visitors: 200 },
  { browser: 'Firefox', visitors: 187 },
  { browser: 'Edge', visitors: 173 },
  { browser: 'Other', visitors: 90 },
];

export default function ChartHorizontalBars() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <BarChart
        data={browsers}
        xKey="browser"
        series={['visitors']}
        orientation="horizontal"
        legend={false}
      />
    </div>
  );
}

Line chart

'use client';

import { LineChart } from '@/components/nxds/components/chart/chart';

const visitors = [
  { month: 'Jan', desktop: 186, mobile: 80 },
  { month: 'Feb', desktop: 305, mobile: 200 },
  { month: 'Mar', desktop: 237, mobile: 120 },
  { month: 'Apr', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'Jun', desktop: 264, mobile: 140 },
];

export default function ChartLines() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <LineChart data={visitors} xKey="month" series={['desktop', 'mobile']} />
    </div>
  );
}

Area chart

Fade each area toward the axis with fill="gradient".

'use client';

import { AreaChart } from '@/components/nxds/components/chart/chart';

const visitors = [
  { month: 'Jan', desktop: 186, mobile: 80 },
  { month: 'Feb', desktop: 305, mobile: 200 },
  { month: 'Mar', desktop: 237, mobile: 120 },
  { month: 'Apr', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'Jun', desktop: 264, mobile: 140 },
];

export default function ChartAreas() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <AreaChart
        data={visitors}
        xKey="month"
        series={['desktop', 'mobile']}
        fill="gradient"
        stacked
      />
    </div>
  );
}

Pie chart

Plot one value per row with PieChart. donut cuts out the middle.

'use client';

import { PieChart } from '@/components/nxds/components/chart/chart';

const browsers = [
  { browser: 'Chrome', visitors: 275 },
  { browser: 'Safari', visitors: 200 },
  { browser: 'Firefox', visitors: 187 },
  { browser: 'Edge', visitors: 173 },
  { browser: 'Other', visitors: 90 },
];

export default function ChartDonut() {
  return (
    <div className="nx:w-[400px] nx:max-w-full">
      <PieChart data={browsers} nameKey="browser" valueKey="visitors" donut />
    </div>
  );
}

Series labels and colors

Each series is labelled by its key and colored in order. Set a label or color for a key in config.

'use client';

import { LineChart } from '@/components/nxds/components/chart/chart';

const visitors = [
  { month: 'Jan', desktop: 186, mobile: 80 },
  { month: 'Feb', desktop: 305, mobile: 200 },
  { month: 'Mar', desktop: 237, mobile: 120 },
  { month: 'Apr', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'Jun', desktop: 264, mobile: 140 },
];

export default function ChartSeriesLabels() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <LineChart
        data={visitors}
        xKey="month"
        series={['desktop', 'mobile']}
        config={{
          desktop: { label: 'Desktop visitors' },
          mobile: {
            label: 'Mobile visitors',
            color: 'var(--nx-color-chart-categorical-4)',
          },
        }}
        dots
      />
    </div>
  );
}

Custom bar chart

Compose Recharts parts inside ChartContainer for a chart the data charts don't cover, such as a patterned series.

'use client';

import { useId } from 'react';

import { CheckerboardIcon } from '@phosphor-icons/react/ssr';
import * as Recharts from 'recharts';

import {
  type ChartConfig,
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
} from '@/components/nxds/components/chart/chart';

const data = [
  { month: 'January', desktop: 186, mobile: 80 },
  { month: 'February', desktop: 305, mobile: 200 },
  { month: 'March', desktop: 237, mobile: 120 },
  { month: 'April', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'June', desktop: 264, mobile: 140 },
];

const config = {
  desktop: {
    label: 'Desktop (solid)',
    color: 'var(--nx-color-chart-categorical-1)',
  },
  mobile: {
    label: 'Mobile (patterned)',
    color: 'var(--nx-color-chart-categorical-2)',
    icon: CheckerboardIcon,
  },
} satisfies ChartConfig;

const shortMonth = (value: string) => value.slice(0, 3);

function BarExample() {
  const mobilePattern = useId();
  return (
    <ChartContainer config={config}>
      <Recharts.BarChart accessibilityLayer data={data}>
        <defs>
          <pattern
            id={mobilePattern}
            width={6}
            height={6}
            patternUnits="userSpaceOnUse"
          >
            <rect width={6} height={6} fill="var(--color-mobile)" />
            <path
              d="M0 0L6 6M-3 3L3 9M3 -3L9 3"
              stroke="var(--nx-color-container)"
              strokeWidth={1.5}
            />
          </pattern>
        </defs>
        <Recharts.CartesianGrid vertical={false} />
        <Recharts.XAxis
          dataKey="month"
          tickLine={false}
          axisLine={false}
          tickMargin={8}
          tickFormatter={shortMonth}
        />
        <ChartTooltip content={<ChartTooltipContent indicator="dashed" />} />
        <ChartLegend content={<ChartLegendContent />} />
        <Recharts.Bar
          dataKey="desktop"
          fill="var(--color-desktop)"
          radius={4}
        />
        <Recharts.Bar
          dataKey="mobile"
          fill={`url(#${mobilePattern})`}
          radius={4}
        />
      </Recharts.BarChart>
    </ChartContainer>
  );
}

export default function ChartBarChartStory() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <BarExample />
    </div>
  );
}

This example also needs:

npm install @phosphor-icons/react@^2.1.10

Custom area chart

Plot two series as areas, with a tooltip and a legend.

'use client';

import { CheckerboardIcon } from '@phosphor-icons/react/ssr';
import * as Recharts from 'recharts';

import {
  type ChartConfig,
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
} from '@/components/nxds/components/chart/chart';

const data = [
  { month: 'January', desktop: 186, mobile: 80 },
  { month: 'February', desktop: 305, mobile: 200 },
  { month: 'March', desktop: 237, mobile: 120 },
  { month: 'April', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'June', desktop: 264, mobile: 140 },
];

const config = {
  desktop: {
    label: 'Desktop (solid)',
    color: 'var(--nx-color-chart-categorical-1)',
  },
  mobile: {
    label: 'Mobile (patterned)',
    color: 'var(--nx-color-chart-categorical-2)',
    icon: CheckerboardIcon,
  },
} satisfies ChartConfig;

const shortMonth = (value: string) => value.slice(0, 3);

function AreaExample() {
  return (
    <ChartContainer config={config}>
      <Recharts.AreaChart
        accessibilityLayer
        data={data}
        margin={{ left: 12, right: 12 }}
      >
        <Recharts.CartesianGrid vertical={false} />
        <Recharts.XAxis
          dataKey="month"
          tickLine={false}
          axisLine={false}
          tickMargin={8}
          tickFormatter={shortMonth}
        />
        <ChartTooltip content={<ChartTooltipContent indicator="dot" />} />
        <ChartLegend content={<ChartLegendContent />} />
        <Recharts.Area
          dataKey="desktop"
          type="natural"
          fill="var(--color-desktop)"
          fillOpacity={0.4}
          stroke="var(--color-desktop)"
        />
        <Recharts.Area
          dataKey="mobile"
          type="natural"
          fill="var(--color-mobile)"
          fillOpacity={0.4}
          stroke="var(--color-mobile)"
          strokeDasharray="6 4"
        />
      </Recharts.AreaChart>
    </ChartContainer>
  );
}

export default function ChartAreaChartStory() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <AreaExample />
    </div>
  );
}

This example also needs:

npm install @phosphor-icons/react@^2.1.10

Custom line chart

Plot two series as lines, with a tooltip and a legend.

'use client';

import { CheckerboardIcon } from '@phosphor-icons/react/ssr';
import * as Recharts from 'recharts';

import {
  type ChartConfig,
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
} from '@/components/nxds/components/chart/chart';

const data = [
  { month: 'January', desktop: 186, mobile: 80 },
  { month: 'February', desktop: 305, mobile: 200 },
  { month: 'March', desktop: 237, mobile: 120 },
  { month: 'April', desktop: 173, mobile: 190 },
  { month: 'May', desktop: 209, mobile: 130 },
  { month: 'June', desktop: 264, mobile: 140 },
];

const config = {
  desktop: {
    label: 'Desktop (solid)',
    color: 'var(--nx-color-chart-categorical-1)',
  },
  mobile: {
    label: 'Mobile (patterned)',
    color: 'var(--nx-color-chart-categorical-2)',
    icon: CheckerboardIcon,
  },
} satisfies ChartConfig;

const shortMonth = (value: string) => value.slice(0, 3);

function LineExample() {
  return (
    <ChartContainer config={config}>
      <Recharts.LineChart
        accessibilityLayer
        data={data}
        margin={{ left: 12, right: 12 }}
      >
        <Recharts.CartesianGrid vertical={false} />
        <Recharts.XAxis
          dataKey="month"
          tickLine={false}
          axisLine={false}
          tickMargin={8}
          tickFormatter={shortMonth}
        />
        <ChartTooltip content={<ChartTooltipContent indicator="line" />} />
        <ChartLegend content={<ChartLegendContent />} />
        <Recharts.Line
          dataKey="desktop"
          type="natural"
          stroke="var(--color-desktop)"
          strokeWidth={2}
          dot={false}
        />
        <Recharts.Line
          dataKey="mobile"
          type="natural"
          stroke="var(--color-mobile)"
          strokeDasharray="6 4"
          strokeWidth={2}
          dot={false}
        />
      </Recharts.LineChart>
    </ChartContainer>
  );
}

export default function ChartLineChartStory() {
  return (
    <div className="nx:w-[600px] nx:max-w-full">
      <LineExample />
    </div>
  );
}

This example also needs:

npm install @phosphor-icons/react@^2.1.10

Props

AreaChart

AreaChart props
PropTypeDefaultDescription
categoryAxisbooleantrue

Shows the axis with each row's category.

classNamestringNo default documentedNo description
configChartConfigNo default documented

Label, icon and color for each series, keyed by its key. Without one, a series is labelled by its key.

curve"linear" | "natural" | "monotone" | "step""natural"

How each area's edge joins its points.

dataRequiredChartDatum[]No default documented

The rows to plot, one per category.

fill"solid" | "gradient""solid"

gradient fades each area toward the axis.

gridbooleantrue

Draws grid lines across the values.

indicator"dashed" | "line" | "dot""dot"

The tooltip's mark beside each value.

legendbooleantrue

Shows a legend under the chart.

seriesRequiredstring[]No default documented

The keys in each row to plot. Each key is one series, colored in order. The palette has five colors, so a sixth series repeats the first series' color.

stackedbooleanfalse

Stacks the series on top of each other.

tooltipbooleantrue

Shows a tooltip on hover.

valueAxisbooleanfalse

Shows the axis with the value scale.

xKeyRequiredstringNo default documented

The key in each row that holds its category, such as month.

BarChart

BarChart props
PropTypeDefaultDescription
categoryAxisbooleantrue

Shows the axis with each row's category.

classNamestringNo default documentedNo description
configChartConfigNo default documented

Label, icon and color for each series, keyed by its key. Without one, a series is labelled by its key.

dataRequiredChartDatum[]No default documented

The rows to plot, one per category.

gridbooleantrue

Draws grid lines across the values.

indicator"dashed" | "line" | "dot""dashed"

The tooltip's mark beside each value.

legendbooleantrue

Shows a legend under the chart.

orientation"horizontal" | "vertical""vertical"

The direction the bars run. horizontal bars grow left to right.

radiusnumber4

Corner radius of each bar, in px. A stack rounds only its outer end.

seriesRequiredstring[]No default documented

The keys in each row to plot. Each key is one series, colored in order. The palette has five colors, so a sixth series repeats the first series' color.

stackedbooleanfalse

Stacks the series in one bar per category.

tooltipbooleantrue

Shows a tooltip on hover.

valueAxisbooleanfalse

Shows the axis with the value scale.

xKeyRequiredstringNo default documented

The key in each row that holds its category, such as month.

ChartContainer

ChartContainer props
PropTypeDefaultDescription
configRequiredChartConfigNo default documentedNo description

ChartLegend

ChartLegend adds no props of its own; it accepts the props of the element or primitive it wraps.

ChartLegendContent

ChartLegendContent props
PropTypeDefaultDescription
classNamestringNo default documentedNo description
hideIconbooleanfalseNo description
nameKeystringNo default documentedNo description
verticalAlign"bottom" | "top""bottom"No description

ChartTooltip

ChartTooltip adds no props of its own; it accepts the props of the element or primitive it wraps.

ChartTooltipContent

ChartTooltipContent props
PropTypeDefaultDescription
activebooleanNo default documentedNo description
classNamestringNo default documentedNo description
colorstringNo default documentedNo description
formatterChartTooltipFormatterNo default documentedNo description
hideIndicatorbooleanfalseNo description
hideLabelbooleanfalseNo description
indicator"dashed" | "line" | "dot""dot"No description
labelKeystringNo default documentedNo description
nameKeystringNo default documentedNo description

LineChart

LineChart props
PropTypeDefaultDescription
categoryAxisbooleantrue

Shows the axis with each row's category.

classNamestringNo default documentedNo description
configChartConfigNo default documented

Label, icon and color for each series, keyed by its key. Without one, a series is labelled by its key.

curve"linear" | "natural" | "monotone" | "step""natural"

How each line joins its points.

dataRequiredChartDatum[]No default documented

The rows to plot, one per category.

dotsbooleanfalse

Marks each data point with a dot.

gridbooleantrue

Draws grid lines across the values.

indicator"dashed" | "line" | "dot""line"

The tooltip's mark beside each value.

legendbooleantrue

Shows a legend under the chart.

seriesRequiredstring[]No default documented

The keys in each row to plot. Each key is one series, colored in order. The palette has five colors, so a sixth series repeats the first series' color.

tooltipbooleantrue

Shows a tooltip on hover.

valueAxisbooleanfalse

Shows the axis with the value scale.

xKeyRequiredstringNo default documented

The key in each row that holds its category, such as month.

PieChart

PieChart props
PropTypeDefaultDescription
classNamestringNo default documentedNo description
configChartConfigNo default documented

Label, icon and color for each slice, keyed by its name. Without one, a slice is labelled by its name.

dataRequiredChartDatum[]No default documented

The slices to plot, one row each. The palette has five colors, so a sixth slice repeats the first slice's color.

donutbooleanfalse

Cuts out the middle, so the pie becomes a ring.

labelsbooleanfalse

Writes each slice's value beside it.

legendbooleantrue

Shows a legend under the chart.

nameKeyRequiredstringNo default documented

The key in each row that holds the slice's name, such as browser.

tooltipbooleantrue

Shows a tooltip on hover.

valueKeyRequiredstringNo default documented

The key in each row that holds the slice's value.

Vue Chart is coming soon

Chart isn't in the Vue package yet. The React version is ready to use today.