---
title: Chart
description: Beautiful charts. Built using Recharts. Copy and paste into your apps.
icon: chart-bar
author:
  name: shadcn
  url: https://github.com/shadcn

mode: wide
---

<PoweredBy
  packages={[
    { name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/chart' },
    { name: 'Recharts', url: 'https://recharts.org/en-US' },
  ]}
/>

For new TanStack Charts compositions, use the separate [TanStack chart](/docs/tanstack-chart) component. Existing Recharts APIs remain unchanged.

### Installation

```package-install
npx shadcn@latest add @redpanda/chart
```

:::info
**Note:** All up-to-date charts can be found [here](https://ui.shadcn.com/charts)
:::

Introducing **Charts**. A collection of chart components that you can copy and paste into your apps.

Charts are designed to look great out of the box. They work well with the other components and are fully customizable to fit your project using the Redpanda UI color system.

[Browse the Charts Library](https://ui.shadcn.com/charts).

## When to use

Use this decision tree to determine when to use Chart components and which type is most appropriate for your data:

```mermaid
graph TD;
    A[❓ Need to visualize data?] -->|Yes| B[Yes];
    A -->|No| C[⚠️ No - use other components];
    B --> D{What type of data?};
    D -->|Time series/trends| E[Time series/trends];
    D -->|Categorical comparison| F[Categorical comparison];
    D -->|Part-to-whole relationships| G[Part-to-whole relationships];
    D -->|Correlation/distribution| H[Correlation/distribution];
    E --> I[✅ Line Chart];
    E --> J[✅ Area Chart for cumulative];
    F --> K[✅ Bar Chart for few categories];
    F --> L[✅ Column Chart for many categories];
    G --> M["✅ Pie Chart for <6 segments"];
    G --> N[✅ Donut Chart for focus on total];
    H --> O[✅ Scatter Plot];
    H --> P[✅ Radar Chart for multivariate];
    I --> Q{Interactive features needed?};
    K --> Q;
    M --> Q;
    O --> Q;
    Q -->|Yes| R[✅ Yes - add Tooltip + Legend];
    Q -->|No| S[✅ No - basic chart only];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class I,J,K,L,M,N,O,P,R,S recommended;
    class C discouraged;
    class A,D,Q decision;
    class B,E,F,G,H neutral;
```

### Chart Type Guidelines

- **Bar/Column Charts**: Comparing quantities across categories, showing rankings or changes over time
- **Line Charts**: Showing trends over time, continuous data, multiple data series comparisons
- **Area Charts**: Cumulative values over time, showing volume and trends together
- **Pie/Donut Charts**: Parts of a whole, percentages, composition (limit to 5-6 segments max)
- **Scatter Plots**: Correlations between two variables, distributions, outlier identification
- **Radar Charts**: Comparing multiple variables across categories, performance metrics

### Charts vs Other Components

- **Use Charts when**: You need to visualize quantitative data, show trends, or help users understand relationships between data points
- **Use Tables when**: Users need to see exact values, perform calculations, or work with detailed records
- **Use Progress/Meters when**: Showing simple completion status or single metric progress
- **Use Statistics Cards when**: Displaying key metrics without requiring trend analysis

## Anatomy

The Chart system is built with composable components using Recharts and a configuration-driven approach:

```
Chart Component Architecture:
┌─────────────────────────────────────────────┐
│ ChartContainer (Context Provider)           │
│ ┌─────────────────────────────────────────┐ │
│ │ ChartConfig (series metadata)           │ │
│ │ - Labels and optional icons             │ │
│ │ - Named theme-token color references    │ │
│ │ - No generated per-instance stylesheet │ │
│ └─────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────┐ │
│ │ ResponsiveContainer (Recharts)          │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Chart Type (Bar/Line/Area/Pie)      │ │ │
│ │ │ ┌─────────────────────────────────┐ │ │ │
│ │ │ │ Data Elements                   │ │ │ │
│ │ │ │ - Bar, Line, Area segments      │ │ │ │
│ │ │ │ - Uses config colors directly │ │ │ │
│ │ │ └─────────────────────────────────┘ │ │ │
│ │ │ ┌─────────────────────────────────┐ │ │ │
│ │ │ │ CartesianGrid (optional)        │ │ │ │
│ │ │ │ - Background grid lines         │ │ │ │
│ │ │ └─────────────────────────────────┘ │ │ │
│ │ │ ┌─────────────────────────────────┐ │ │ │
│ │ │ │ XAxis / YAxis (optional)        │ │ │ │
│ │ │ │ - Labeled axes with formatting  │ │ │ │
│ │ │ └─────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────┐ │
│ │ ChartTooltip (Custom Component)         │ │
│ │ - Appears on hover/focus                │ │
│ │ - Uses config for labels/colors         │ │
│ │ - Supports icons and custom formatting  │ │
│ └─────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────┐ │
│ │ ChartLegend (Custom Component)          │ │
│ │ - Shows data series labels              │ │
│ │ - Color indicators match chart          │ │
│ │ - Positioned above/below chart          │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘

ChartConfig Structure:
{
  dataKey: {
    label: "Human Label",           // For tooltips/legends
    icon: IconComponent,            // Optional icon
    color: "var(--color-chart-1)"    // Pass directly to fill or stroke
  }
}
```

### Component Composition

- **ChartContainer**: Root wrapper providing series metadata and responsive sizing
- **ChartConfig**: Configuration object defining labels, colors, and icons for data keys
- **Recharts Integration**: Direct use of Recharts components (Bar, Line, Area, etc.)
- **Custom Components**: ChartTooltip, ChartLegend for consistent theming
- **Color System**: Named theme tokens passed directly to Recharts; CSS owns theme changes
- **Accessibility**: Built-in screen reader support via accessibilityLayer prop

## Component

We use [Recharts](https://recharts.org/) under the hood.

We designed the `chart` component with composition in mind. **You build your charts using Recharts components and only bring in custom components, such as `ChartTooltip`, when and where you need it**.

```tsx lineNumbers
// [!code word:ChartContainer]
// [!code word:ChartTooltipContent]
import { Bar, BarChart } from 'recharts';

import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/redpanda-ui/components/chart';

const data = [{ name: 'January', value: 186 }];
const config = { value: { label: 'Users', color: 'var(--color-chart-1)' } };

export function MyChart() {
  return (
    <ChartContainer config={config} className="min-h-50 w-full">
      <BarChart data={data}>
        <Bar dataKey="value" fill={config.value.color} />
        <ChartTooltip content={<ChartTooltipContent />} />
      </BarChart>
    </ChartContainer>
  );
}
```

We do not wrap Recharts. This means you're not locked into an abstraction. When a new Recharts version is released, you can follow the official upgrade path to upgrade your charts.

**The components are yours**.

## Chart Color System

Five series colors ship in `theme.css`, with a value per theme: an indigo-to-blue-grey family on a light page, a teal family on a dark one. Each is stepped rather than five separate hues, so a multi-series chart reads as one system. Assign them in order, `chart-1` first, and never cycle: a sixth series is not a generated sixth colour, so fold it into "Other", facet the chart, or split the measure across two charts.

### Current Chart Colors

These colors are already included in your `theme.css` file:

```css title="theme.css"
@theme {
  --color-chart-1: #6172f3;
  --color-chart-2: #3c5686;
  --color-chart-3: #8ea8ee;
  --color-chart-4: #c5d0e4;
  --color-chart-5: #dee8ff;
}

[data-theme='dark'] {
  /* Every rung is declared here: dark builds its family around its own accent — a teal, not the
     light theme's indigo — in the same lightness order, so a series keeps its weight when the theme
     flips. One hue throughout: stepping toward mint bought a fraction more separation between the
     pale rungs and put two of them in the success green's neighbourhood. */
  --color-chart-1: #26b5ac;
  --color-chart-2: #18817a;
  --color-chart-3: #2ed5ca;
  --color-chart-4: #64f0e5;
  --color-chart-5: #ddfbf7;
}
```

### Color Characteristics

- **One family, stepped**: the five step through a single family — indigo to blue-grey on light, one teal on dark — rather than each taking its own hue, so a chart sits inside the rest of the UI instead of competing with it.
- **A value per theme**: all five rungs are re-declared for a dark page. They hold the light theme's lightness _order_, so series 2 stays the heaviest and series 5 the lightest whichever theme is on.
- **Color follows the entity, never its rank** — a filter that drops series must not repaint the survivors.

:::warning
**Give a chart with more than about three series direct labels, not colour alone.** As a
_categorical_ palette this family is weak by design-hold rather than by accident. Measured as
OKLab ΔE between rungs adjacent in lightness, a categorical set wants 15 and neither ramp reaches
it at the pale end: light closes to **7.5** between `chart-4` and `chart-5`, dark to **8.6**
between `chart-3` and `chart-4`. So five series resolve into fewer than five in either theme, and
a set that carries five identities on colour needs five distinct hues — a brand decision rather
than a token one.

The dark ramp also sits nearer the status palette than the old indigo did: `chart-1` is ΔE 8.8
from `success-strong`. A teal accent has nowhere better to go — only hues 299–334 clear 15 against
every status tone, and that is the magenta band this theme deliberately left — so keep a status
colour and a series colour from meeting in the same view where you can.
:::

### Usage in Chart Config

Reference these colors in your chart configuration:

```tsx
import { type ChartConfig } from '@/components/redpanda-ui/components/chart';

const chartConfig = {
  desktop: {
    label: 'Desktop',
    color: 'var(--color-chart-1)', // The series token, not a literal
  },
  mobile: {
    label: 'Mobile',
    color: 'var(--color-chart-2)',
  },
  tablet: {
    label: 'Tablet',
    color: 'var(--color-chart-3)',
  },
} satisfies ChartConfig;
```

Pass `chartConfig.desktop.color` to the corresponding Recharts `fill` or `stroke`.
ChartContainer does not create `--color-desktop` or other series-name aliases.

## Your First Chart

Let's build your first chart. We'll build a bar chart, add a grid, axis, tooltip and legend.

1. Start by defining your data

2. Define your chart config

3. Build your chart

### Add a Grid

Let's add a grid to the chart.

1. Import the `CartesianGrid` component.

2. Add the `CartesianGrid` component to your chart.

### Add an Axis

To add an x-axis to the chart, we'll use the `XAxis` component.

1. Import the `XAxis` component.

2. Add the `XAxis` component to your chart.

### Add Tooltip

So far we've only used components from Recharts. They look great out of the box thanks to some customization in the `chart` component.

To add a tooltip, we'll use the custom `ChartTooltip` and `ChartTooltipContent` components from `chart`.

1. Import the `ChartTooltip` and `ChartTooltipContent` components.

2. Add the components to your chart.

### Add Legend

We'll do the same for the legend. We'll use the `ChartLegend` and `ChartLegendContent` components from `chart`.

1. Import the `ChartLegend` and `ChartLegendContent` components.

2. Add the components to your chart.

Done. You've built your first chart! What's next?

- [Themes and Colors](/docs/chart#theming)
- [Tooltip](/docs/chart#tooltip)
- [Legend](/docs/chart#legend)

## Chart Config

The chart config is where you define the labels, icons and colors for a chart.

It is intentionally decoupled from chart data.

This lets you share metadata and color tokens between charts without changing the data shape.
Each Recharts series still receives its own `fill` or `stroke` explicitly.

```tsx
// [!code word:ChartConfig]
import { Monitor } from 'lucide-react';

import { type ChartConfig } from '@/components/redpanda-ui/components/chart';

const chartConfig = {
  desktop: {
    label: 'Desktop',
    icon: Monitor,
    color: 'var(--color-chart-1)',
  },
} satisfies ChartConfig;
```

## Theming

Use named Redpanda UI color tokens. Their declarations in `theme.css` own light and
dark values, so CSS applies the correct color on the first paint and whenever the
ancestor theme changes. ChartContainer neither generates a stylesheet nor observes
the document theme in JavaScript.

### CSS Variables (Recommended)

The Redpanda UI theme includes optimized chart colors that automatically work with light and dark modes.

1. Use the predefined chart colors from `theme.css`

2. Reference colors in your `chartConfig`

### Using Colors

Pass the configured token directly. A series key is metadata, not a generated CSS variable.

#### Components

```tsx
<Bar dataKey="desktop" fill={chartConfig.desktop.color} />
```

#### Chart Data

```tsx
const chartData = [
  { browser: 'chrome', visitors: 275, fill: 'var(--color-chart-1)' },
  { browser: 'safari', visitors: 200, fill: 'var(--color-chart-2)' },
];
```

#### Tailwind

```tsx
<LabelList className="fill-chart-1" />
```

### Migrating generated chart colors

This release removes the non-deprecated `ChartStyle` export and `ChartConfig.theme`
as an additional breaking styling change. ChartContainer no longer generates
`--color-${series}` aliases. Replace `fill="var(--color-desktop)"` with
`fill={chartConfig.desktop.color}`, and do the equivalent for strokes, gradient
stops, and per-datum fills.

Move former light/dark mappings into named theme-token declarations in your
application's checked theme stylesheet. Use the existing chart tokens where possible;
do not recreate ChartStyle, inject a stylesheet, or introduce a theme-reading effect.
Independent chart instances can share series keys because their Recharts props now
receive their colors directly. `ChartConfig.color` remains optional metadata, not a
CSS declaration; tooltip and legend indicators use it only when their higher-priority
payload color is absent. Caller native styles continue to be forwarded. An explicit
`id` now reaches the native container too; previously it only named the generated
selector. `data-chart` keeps its `chart-` prefix.

See the [breaking toolchain migration](/docs/strict-toolchain-migration#chart-colors-use-theme-tokens-directly)
for the complete release migration.

### Brand Consistency

For maximum brand consistency, use the predefined chart colors which follow the Redpanda UI design system:

```tsx
const chartConfig = {
  primary: { label: 'Primary', color: 'var(--color-chart-1)' },
  secondary: { label: 'Secondary', color: 'var(--color-chart-2)' },
  tertiary: { label: 'Tertiary', color: 'var(--color-chart-3)' },
  quaternary: { label: 'Quaternary', color: 'var(--color-chart-4)' },
  quinary: { label: 'Quinary', color: 'var(--color-chart-5)' },
} satisfies ChartConfig;
```

## Tooltip

A chart tooltip contains a label, name, indicator and value. You can use a combination of these to customize your tooltip.

<ComponentPreview name="chart-bar-tooltip-demo" className="[&_.preview]:py-0" />

You can turn on/off any of these using the `hideLabel`, `hideIndicator` props and customize the indicator style using the `indicator` prop.

Use `labelKey` and `nameKey` to use a custom key for the tooltip label and name.

Chart comes with the `<ChartTooltip>` and `<ChartTooltipContent>` components. You can use these two components to add custom tooltips to your chart.

```tsx
import { ChartTooltip, ChartTooltipContent } from '@/components/redpanda-ui/components/chart';
```

```tsx
<ChartTooltip content={<ChartTooltipContent />} />
```

### Props

Use the following props to customize the tooltip.

| Prop            | Type                     | Description                                  |
| :-------------- | :----------------------- | :------------------------------------------- |
| `labelKey`      | string                   | The config or data key to use for the label. |
| `nameKey`       | string                   | The config or data key to use for the name.  |
| `indicator`     | `dot` `line` or `dashed` | The indicator style for the tooltip.         |
| `hideLabel`     | boolean                  | Whether to hide the label.                   |
| `hideIndicator` | boolean                  | Whether to hide the indicator.               |

### Colors

The indicator uses its explicit color, the datum's fill, or the Recharts payload
color, then falls back to the matching `ChartConfig.color`. Pass the same token
to the plotted series so the indicator and chart agree.

### Custom

To use a custom key for tooltip label and names, use the `labelKey` and `nameKey` props.

```tsx
// [!code word:browser]
const chartData = [
  { browser: 'chrome', visitors: 187, fill: 'var(--color-chart-1)' },
  { browser: 'safari', visitors: 200, fill: 'var(--color-chart-2)' },
];

const chartConfig = {
  visitors: {
    label: 'Total Visitors',
  },
  chrome: {
    label: 'Chrome',
    color: 'var(--color-chart-1)',
  },
  safari: {
    label: 'Safari',
    color: 'var(--color-chart-2)',
  },
} satisfies ChartConfig;
```

```tsx
<ChartTooltip content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />} />
```

This will use `Total Visitors` for label and `Chrome` and `Safari` for the tooltip names.

## Legend

You can use the custom `<ChartLegend>` and `<ChartLegendContent>` components to add a legend to your chart.

```tsx
import { ChartLegend, ChartLegendContent } from '@/components/redpanda-ui/components/chart';
```

```tsx
<ChartLegend content={<ChartLegendContent />} />
```

### Colors

The indicator uses the Recharts payload color, falling back to the matching
`ChartConfig.color`. Pass the configured token to each plotted series.

### Custom

To use a custom key for legend names, use the `nameKey` prop.

```tsx
// [!code word:browser]
const chartData = [
  { browser: 'chrome', visitors: 187, fill: 'var(--color-chart-1)' },
  { browser: 'safari', visitors: 200, fill: 'var(--color-chart-2)' },
];

const chartConfig = {
  chrome: {
    label: 'Chrome',
    color: 'var(--color-chart-1)',
  },
  safari: {
    label: 'Safari',
    color: 'var(--color-chart-2)',
  },
} satisfies ChartConfig;
```

```tsx
<ChartLegend content={<ChartLegendContent nameKey="browser" />} />
```

This will use `Chrome` and `Safari` for the legend names.

### Tooltip formatter migration

`ChartTooltipContent.formatter` follows Recharts: its fifth argument is the
original series payload array, not the current data row. Read the current row
from the third argument's `payload` property. The fourth argument retains the
original series index even when hidden series are not displayed.

## Accessibility

You can turn on the `accessibilityLayer` prop to add an accessible layer to your chart.

This prop adds keyboard access and screen reader support to your charts.

```tsx
<LineChart accessibilityLayer />
```

## Examples

### Default

<ComponentPreview name="chart-bar-demo" className="[&_.preview]:p-4 [&_.preview]:min-h-62.5" />

### With Filter (dates)

<ComponentPreview name="chart-bar-filter-demo" className="[&_.preview]:p-4 [&_.preview]:min-h-62.5" />

## Other chart types

### Line Chart

<ComponentPreview name="chart-line-demo" description="Multi-series line chart for metrics over time." />

### Area Chart

<ComponentPreview name="chart-area-demo" description="Area chart visualising a growth or trend metric." />

### Pie Chart

<ComponentPreview name="chart-pie-demo" description="Pie chart visualising a categorical distribution." />

### Radial Chart

<ComponentPreview name="chart-radial-demo" description="Radial bar chart for compact distribution visuals." />

### Scatter Chart

<ComponentPreview name="chart-scatter-demo" description="Scatter chart visualising two-dimensional correlations." />

## Color Reference

### Predefined Chart Colors

| Variable          | Light Mode                           | Dark Mode                            | Usage                             |
| ----------------- | ------------------------------------ | ------------------------------------ | --------------------------------- |
| `--color-chart-1` | `#6172f3` · `oklch(0.607 0.192 274)` | `#26b5ac` · `oklch(0.700 0.114 188)` | First series — the theme's accent |
| `--color-chart-2` | `#3c5686` · `oklch(0.455 0.085 262)` | `#18817a` · `oklch(0.546 0.089 188)` | Second series — the heaviest rung |
| `--color-chart-3` | `#8ea8ee` · `oklch(0.739 0.106 268)` | `#2ed5ca` · `oklch(0.791 0.129 188)` | Third series                      |
| `--color-chart-4` | `#c5d0e4` · `oklch(0.855 0.030 263)` | `#64f0e5` · `oklch(0.876 0.122 188)` | Fourth series                     |
| `--color-chart-5` | `#dee8ff` · `oklch(0.930 0.033 267)` | `#ddfbf7` · `oklch(0.965 0.032 187)` | Fifth series — the lightest rung  |

Light steps through indigo into blue-grey; dark holds one teal and separates by lightness. Both are
defined in `theme.css`, and both hold the same lightness order so a series keeps its weight across
themes.

## Credits

- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/chart) for the chart component and style.
