<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# Chart

A chart drawn in the theme's colors, which people can use without seeing it: a figure named by its `title`, a summary for screen readers, and a table of every value (visible with `showTable`). The plot is a tab stop, and the arrow keys move its tooltip from point to point. Each series is labeled in a legend with its own marker shape, so color is never the only cue.

```tsx
import { Chart } from "@/components/ouro/chart/chart";
```

## Example

```tsx
<Chart
  title="Recipes cooked per month"
  data={months}
  categoryKey="month"
  config={{ cooked: { label: "Cooked" }, saved: { label: "Saved", tone: "chart-2" } }}
/>
```

## Usage

Pass `type` for bars, lines or areas, one per series in `config`. For anything else, pass a recharts chart as children with `<ChartTooltip />` and `<ChartLegend />` inside it, as in shadcn's charts; it draws with `var(--color-<key>)`. The marks Chart draws itself appear at once; your own `<Line>` or `<Bar>` keeps recharts' draw-in unless you pass `isAnimationActive={false}`.

Built on recharts, which Bundlephobia measures at about 150 KB gzip (566 KB minified) for the whole package; a bundler that drops what Chart does not import adds less to the page that renders it. Load it with `next/dynamic` or `React.lazy` when the chart is below the fold.

Colors come from the theme's `--chart-1` to `--chart-5`, which must reach 3:1 against the background for the marks to be seen (WCAG's non-text contrast).

## Use instead when

- Use `Progress` instead for one value out of a total, and a table alone when readers need exact figures more than the shape of the data.

## Props

Type: `ChartProps<Row>`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `categoryKey` (required) | `keyof Row & string` |  | The key in each row that names its category: the x axis and the table's first column. |
| `children` | `ReactNode` |  | A recharts chart (`<LineChart>`) for anything `type` cannot draw. It gets `data`, the title as its name and the theme colors as `var(--color-<key>)`; add `<ChartTooltip />` and `<ChartLegend />` inside it. |
| `className` | `string` |  | Layout only: the chart's height (`h-64`, `aspect-square`), margins. The plot is 16:9 until you set a height. Appearance classes warn in development. |
| `config` (required) | `ChartConfig<Row>` |  | The series to draw, by their key in each row, with their labels and tones. |
| `data` (required) | `readonly Row[]` |  | The rows to draw, one per category (a month, a recipe). |
| `description` | `ReactNode` |  | A line under the title, such as the period: "January to June". |
| `formatValue` | `((value: number, series: string) => string)` | `"1,250"` | Writes a value for the axis, the tooltip and the table, for other languages or units. `series` is the value's key in `config`, and `""` for the y axis, which all series share. |
| `hideTitle` | `boolean` |  | Hides the title visually; screen readers still hear it. |
| `ref` | `Ref<HTMLElement>` |  | Reaches the rendered element. |
| `showTable` | `boolean` |  | Shows the data table under the chart. It is always there for screen readers. |
| `summary` | `((info: ChartSummaryInfo) => string)` | (info) => "Bar chart of Cooked and Saved by Month, 3 points. The table that follows lists every value." | What screen readers hear about the chart after its title, for other languages. |
| `title` (required) | `string` |  | What the chart shows: "Recipes cooked per month". Its name for screen readers, shown above it. Required. |
| `type` | `"area" \| "line" \| "bar"` | `"bar"` | What to draw when there are no children: bars, lines or areas, one per series. |

## Native attributes

Also accepts the attributes in React's `HTMLAttributes` (`id`, `aria-*`, event handlers), passed to the rendered element, except those named on this page.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`). Your classes always win over Ouro UI's: Chart merges `className` last with `cn` (tailwind-merge), so a class that conflicts with its own replaces it.[^layout-classes]

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

## Types

### `ChartConfig`

The series a chart draws, by their key in each row, as in shadcn's `ChartConfig`. Each key also names a CSS variable, `--color-<key>`, for recharts children (`fill="var(--color-cooked)"`). A label for `categoryKey` names the category column.

```ts
type ChartConfig<Row extends object = Record<string, unknown>> = { [Key in keyof Row & string]?: ChartSeries };
```

### `ChartSeries`

One series in a chart's `config`: its label and the theme tone it is drawn in.

```ts
interface ChartSeries {
  /** What the series is called in the legend, the tooltip and the data table: "Recipes cooked". */
  label: string;
  /**
   * The theme color: `chart-1` to `chart-5`, or a tone that means something (`destructive`
   * for failures). Without it, series take `chart-1`, `chart-2` and so on, in order.
   */
  tone?: ChartTone | (string & { 'Use "chart-1" to "chart-5", "primary", "destructive", "success" or "warning"': never }) | undefined;

  /** Not a prop. Colors come from the theme: `{ label: "Cooked", tone: "chart-1" }`. */
  color?: { 'Colors come from the theme. Use { label: "Cooked", tone: "chart-1" }': never };
  /** Not a prop. Light and dark colors come from the theme's chart tokens: `{ label: "Cooked", tone: "chart-1" }`. */
  theme?: { 'Colors come from the theme. Use { label: "Cooked", tone: "chart-1" }': never };
}
```

[^layout-classes]: test:registry/ouro/components/ouro/chart/chart.test.tsx::Chart > forwards a ref and lets app layout classes win verify:testExists(registry/ouro/components/ouro/chart/chart.test.tsx::Chart > forwards a ref and lets app layout classes win)
