# useChart

Charts are plain SVG themed by IndokuUI, with no extra dependency. Install `@indoku/ui` and import what you need.

`useChart` shares colors, number formatting and legend highlighting between charts and your own markup.

Group: Charts

## Import

```tsx
import { useChart, ChartLegend, sortChartData, chartTokens } from "@indoku/ui"
```

## Examples

### Legend highlighting

Hover a legend item to dim the other series.

```tsx
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
const revenue = [120, 180, 150, 240, 210, 300]
const costs = [80, 110, 100, 150, 140, 170]
const series = [
  { name: "Revenue", values: revenue },
  { name: "Costs", values: costs },
]

const revenue = [120, 180, 150, 240, 210, 300]
const costs = [80, 110, 100, 150, 140, 170]
const series = [
  { name: "Revenue", values: revenue },
  { name: "Costs", values: costs },
]

const costs = [80, 110, 100, 150, 140, 170]
const series = [
  { name: "Revenue", values: revenue },
  { name: "Costs", values: costs },
]

const series = [
  { name: "Revenue", values: revenue },
  { name: "Costs", values: costs },
]

function UseChartLegend() {
  const chart = useChart({ series })
  return (
    <Box maxW="2xl">
      <LineChart series={series} categories={months} highlight={chart.active} />
      <ChartLegend chart={chart} items={series.map((s, i) => ({ name: s.name, color: chart.colors[i] }))} />
    </Box>
  )
}
```

### Formatting

Pass `format` to change how numbers print.

```tsx
function UseChartFormat() {
  const chart = useChart({ format: (v) => `$${v.toFixed(0)}k` })
  return <Text>{chart.format(1234)} and {chart.format(87)}</Text>
}
```

### Sorting

`sortChartData` sorts without mutating.

```tsx
const sales = [
  { name: "Tea", value: 340 },
  { name: "Coffee", value: 910 },
  { name: "Juice", value: 220 },
  { name: "Soda", value: 580 },
]

function UseChartSorting() {
  const sorted = sortChartData(sales, (d) => d.value, "desc")
  return <Box maxW="2xl"><BarChart series={[{ name: "Sales", values: sorted.map((d) => d.value) }]} categories={sorted.map((d) => d.name)} /></Box>
}
```

### Size and spacing tokens

```tsx
function UseChartTokens() {
  return <Text fontSize="sm" fontFamily="mono">sizes {JSON.stringify(chartTokens.size)} spacing {JSON.stringify(chartTokens.spacing)}</Text>
}
```

## Props

### useChart(options)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `series` | `{ name?; color? }[]` |  | Used to resolve colors. |
| `format` | `(v: number) => string` |  | Number formatter. Default: compact. |
| `highlight` | `number \| null` |  | Force the highlighted series. |

### Returned object

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `colors` | `string[]` |  | Resolved series colors. |
| `active / setActive` | `number \| null` |  | Highlighted series. |
| `opacity(i)` | `number` |  | 1, or 0.2 when dimmed. |
| `legendProps(i)` | `object` |  | Spread on your own legend item. |
| `format(v)` | `string` |  | Formatter. |
| `tokens` | `object` |  | chartTokens: size, spacing, padding. |

`*` = required. Style props and HTML attributes are accepted too.

## See also

- Overview: https://ui.indoku.org/docs/chart
