Capítulo 67 de 108
Wrapper fino sobre Recharts v3 que fornece theming consistente (light/dark via CSS vars), tooltip e legend customizados — sem abstrair a API do Recharts. Você compõe o gráfico com componentes Recharts normais e só troca peças (ChartTooltip, ChartLegend) quando precisa.
ChartConfig: objeto que mapeia cada série de dados (desktop, mobile...) para label, icon opcional e color (ou theme: { light, dark }) — desacoplado dos dados do gráfico.ChartContainer: wrapper obrigatório em volta do componente Recharts; precisa de altura definida (min-h-*, h-* ou aspect-*) para o ResponsiveContainer medir corretamente.var(--color-KEY): dentro do ChartContainer, cada chave do chartConfig vira uma CSS custom property acessível como var(--color-desktop), usada em fill/stroke dos componentes Recharts.ChartTooltip / ChartTooltipContent: tooltip customizado; props labelKey, nameKey, indicator (dot | line | dashed), hideLabel, hideIndicator.ChartLegend / ChartLegendContent: legenda customizada; prop nameKey para usar chave de dado diferente do config.accessibilityLayer: prop do componente Recharts (ex. <BarChart accessibilityLayer>) que adiciona navegação por teclado e suporte a leitor de tela.--chart-1 a --chart-5: tokens CSS globais de cor definidos em app/globals.css (:root e .dark), a fonte recomendada de cores para chartConfig.const chartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" },
} satisfies ChartConfig
export function MyChart() {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={chartData}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickFormatter={(v) => v.slice(0, 3)} />
<ChartTooltip content={<ChartTooltipContent />} />
<ChartLegend content={<ChartLegendContent />} />
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
</BarChart>
</ChartContainer>
)
}
@layer base {
:root {
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
}
.dark {
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
}
}
var(--chart-1) no chartConfig.<ChartTooltip
content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />}
/>
labelKey/nameKey para mapear tooltip para chaves de dado diferentes do padrão (browser/visitors em vez do nome da série).| Prop | Type | Description |
|---|---|---|
labelKey | string | Config ou data key para o label |
nameKey | string | Config ou data key para o nome |
indicator | dot | line | dashed | Estilo do indicador visual |
hideLabel | boolean | Oculta o label |
hideIndicator | boolean | Oculta o indicador |
var(--chart-1) em vez de hsl(var(--chart-1)).ChartTooltip.defaultIndex só para estado inicial; estado ativo persistente vive no seu próprio state.layout de <Bar> quando o <BarChart> pai já define layout.min-h-*/aspect-* no ChartContainer.ChartContainer sem altura definida: o ResponsiveContainer interno do Recharts não consegue medir no primeiro render, gráfico não aparece.hsl(var(--chart-1)) em vez de var(--chart-1): quebrado no Recharts v3, que já espera o valor de cor completo na variável.chartConfig é a camada de metadados (label/cor/ícone), desacoplada dos dados reais — pode vir de fonte remota independente do formato do dado.ChartContainer + altura mínima é obrigatório; sem isso o gráfico não renderiza.var(--color-KEY) dentro do container, geradas a partir das chaves do chartConfig.accessibilityLayer é a forma recomendada (não automática) de tornar o gráfico acessível.Card com header/título e descrição.