KDS
Data

Chart

Sistema de visualização de dados — ChartContainer, tooltips, legendas, e os 6 tipos de gráficos (Area, Bar, Line, Pie, Radar, Radial).

Overview

Chart é o sistema de visualização de dados do KDS. Ele não inventa um motor próprio: empacota o Recharts num conjunto de componentes opinados (ChartContainer, ChartTooltip, ChartLegend, mais o helper ChartStyle) que tipam, normalizam estilo e plugam direto na arquitetura de tokens canônica — os 5 esquemas cromáticos descritos na seção de Tokens / Chart.

A escolha por Recharts é deliberada. Ele cobre sem fricção os 6 tipos clássicos de gráfico (Area, Bar, Line, Pie, Radar, Radial) que rodam 90% dos dashboards de produto, expõe API declarativa em JSX que combina com as convenções do KDS, e tem footprint razoável quando comparado a alternativas full-canvas como ECharts.

Para visualizações fora dessa cobertura — geomaps, sankey complexos, force-directed networks — esse primitivo não é o caminho; saia da abstração e instale a biblioteca apropriada (Visx, ECharts, Mapbox) na própria página, sem tentar moldar Chart para o que ele não foi feito.

Anatomy

ChartContainer (config + responsive wrapper)
└─ Recharts chart (AreaChart | BarChart | LineChart | PieChart | RadarChart | RadialBarChart)
   ├─ CartesianGrid / PolarGrid       ← grade (opcional)
   ├─ XAxis / YAxis / PolarAngleAxis  ← eixos
   ├─ ChartTooltip
   │  └─ ChartTooltipContent          ← tooltip estilizado
   ├─ ChartLegend
   │  └─ ChartLegendContent           ← legenda estilizada
   └─ Area | Bar | Line | Pie | Radar | RadialBar  ← séries

ChartContainer cuida de três coisas: contexto (passa o config para tooltip e legenda), responsividade (envolve em ResponsiveContainer do Recharts) e geração de variáveis CSS (ChartStyle) para que cada série tenha cor consistente em light e dark mode. Tudo o que vai dentro é Recharts puro — você compõe a visualização exatamente como faria no Recharts standalone, sem camadas extras de DSL.

Subcomponents

SubcomponenteO que fazOnde fica na anatomia
ChartContainerProvê contexto (config), responsividade e estilos CSS para cada série. Recebe children Recharts.Raiz do gráfico
ChartStyleInjeta as variáveis CSS de cor por série derivadas do config. Renderizado internamente por ChartContainer.Dentro do container, invisível
ChartTooltipRe-export tipado de Recharts.Tooltip. Aceita content para estilização.Filho direto do chart Recharts
ChartTooltipContentConteúdo do tooltip alinhado ao KDS (border, sombra, indicador de série).Como content de ChartTooltip
ChartLegendRe-export tipado de Recharts.Legend. Aceita content.Filho direto do chart Recharts
ChartLegendContentItem de legenda com swatch de cor e label do config.Como content de ChartLegend
ChartConfigTipo TS para o objeto de configuração: { <key>: { label, color, icon } }.No tipo do componente que usa Chart

Usage

A composição mínima leva ChartContainer envolvendo uma chart do Recharts, com tooltip e legenda nos slots correspondentes:

Receita mensal
AreaChart simples — uma série, tooltip habilitado, sem legenda
Receita cresceu 83% no período
Janeiro – Setembro 2025
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig
} from "@kalvner/kds/data/chart";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";

const config = {
  revenue: { label: "Receita", color: "var(--color-chart-cat-1)" }
} satisfies ChartConfig;

export function MonthlyRevenue({ data }) {
  return (
    <ChartContainer config={config} className="h-[220px] w-full">
      <AreaChart data={data}>
        <CartesianGrid strokeDasharray="3 3" vertical={false} />
        <XAxis dataKey="month" tickLine={false} axisLine={false} />
        <YAxis hide />
        <ChartTooltip content={<ChartTooltipContent />} />
        <Area
          dataKey="revenue"
          type="monotone"
          stroke="var(--color-chart-cat-1)"
          fill="var(--color-chart-cat-1)"
          fillOpacity={0.3}
        />
      </AreaChart>
    </ChartContainer>
  );
}

Setup

Importe os subcomponentes do subpath canônico @kalvner/kds/data/chart. Isso garante tree-shaking — você só carrega o que usa.

Importe os blocos do Recharts (AreaChart, Bar, Line etc) diretamente de recharts. O KDS não re-exporta o Recharts; usar a biblioteca direto deixa o tipo e a documentação intactos.

Defina o config mapeando cada dataKey para { label, color }. Use var(--color-chart-cat-N) ou outro token do KDS — nunca hex hardcoded.

Componha a chart Recharts dentro de ChartContainer, plugando ChartTooltip e ChartLegend nos slots correspondentes para herdar o estilo do KDS.

Chart variants

Áreas comunicam tendência ao longo do tempo com noção visual de volume. Use quando o "quanto" importa tanto quanto o "para onde".

Area Chart
Receita mensal — últimos 9 meses
Crescimento de 5,2% este mês
Janeiro – Setembro 2025
Area Chart - Stacked
Receita realizada vs meta — empilhadas
Receita superou meta em todos os meses
Janeiro – Setembro 2025
Area Chart - Gradient
Visitantes únicos — Q3 2025
Tendência de alta nos últimos 3 meses
Julho – Setembro 2025
Area Chart - Step
Releases por sprint — últimas 9 sprints
12 releases nas últimas 9 semanas
Janeiro – Setembro 2025

Barras são o default seguro para comparação categórica. Quando em dúvida entre Bar, Pie ou Line, escolha Bar — ele lê bem com qualquer quantidade razoável de itens e qualquer escala.

Bar Chart
Receita mensal — últimos 9 meses
Tendência de alta este mês
Janeiro – Setembro 2025
Bar Chart - Horizontal
Sessões por canal de aquisição
Orgânico domina o tráfego
Setembro 2025
Bar Chart - Stacked
Receita realizada vs meta — empilhadas
Pro segmento crescendo mais rápido
Janeiro – Setembro 2025
Bar Chart - Mixed
Sessões por canal — destaque para Orgânico
Maioria do tráfego concentrado em 1 canal
Setembro 2025

Linhas são imbatíveis para tendência temporal com várias séries co-existindo. Ao contrário de Area, não comunicam volume — apenas direção e velocidade da mudança.

Line Chart
Cadastros semanais — últimas 8 semanas
Cadastros +69% nas últimas 8 semanas
Setembro – Novembro 2025
Line Chart - Multiple
Funil semanal — cadastros, ativações, pagamentos
Pagamentos mais que dobraram no período
Setembro – Novembro 2025
Line Chart - Dashed
Cadastros realizados vs ativações projetadas
Projeção de ativações dentro do esperado
Setembro – Novembro 2025

Pies funcionam apenas para composição com até 5 fatias. Acima disso, fatias finas viram ruído e a leitura desmorona — Bar horizontal é estritamente melhor.

Mais de 5 fatias num pie é anti-pattern. Se a distribuição tem 6+ categorias significativas, troque para BarChart horizontal — você não perde leitura nem semântica.

Pie Chart
Distribuição de clientes por plano
Free representa 64% da base
Total de 7.152 clientes ativos
Pie Chart - Donut
Distribuição de clientes por plano
Pro segmento dobrou em 6 meses
Janeiro – Setembro 2025
Pie Chart - With label
Total de clientes com KPI centralizado
Base 1.152 clientes acima do trimestre anterior
Janeiro – Setembro 2025
Pie Chart - Legend
Distribuição de clientes com legenda
Free segmento estável em 60%+
Setembro 2025

Radars comparam um sujeito em várias dimensões na mesma escala. Auditorias técnicas (Lighthouse), scorecards de produto e perfis de habilidade são casos de uso clássicos.

Radar Chart
Scorecard técnico — auditoria atual
Acessibilidade lidera com 91 pontos
Auditoria de Setembro 2025
Radar Chart - Multiple
Scorecard técnico — antes vs depois
Performance subiu 12 pontos no trimestre
Junho vs Setembro 2025

Barras radiais são gauges modernos — comunicam progresso ou conclusão de forma compacta. Funcionam particularmente bem em tiles de KPI.

Radial Chart
Funil de onboarding — taxa por etapa
Convite de time é o maior gargalo
Coorte de Setembro 2025
Radial Chart - With label
Conclusão média de onboarding centralizada
Conclusão média subiu 8 pontos
Coorte de Setembro 2025

ChartConfig

ChartConfig é o tipo do objeto que descreve cada série da chart — label exibido em tooltip e legenda, cor (token CSS), e ícone opcional. As chaves precisam casar com os dataKey usados nas séries Recharts.

Prop

Type

import type { ChartConfig } from "@kalvner/kds/data/chart";

const config = {
  revenue: {
    label: "Receita",
    color: "var(--color-chart-cat-1)"
  },
  target: {
    label: "Meta",
    color: "var(--color-chart-cat-2)"
  }
} satisfies ChartConfig;

Tooltip & Legend

Os helpers ChartTooltipContent e ChartLegendContent aceitam variações para casos diferentes. Use o que melhor responde à pergunta "o que o leitor precisa saber ao passar o mouse?".

SubcomponenteVariaçãoQuando usar
ChartTooltipContentdefaultMúltiplas séries, label do eixo X importante (ex. "Mar 2026").
ChartTooltipContenthideLabelPies e radials onde o nome da fatia já é suficiente — sem header.
ChartTooltipContentindicator="line"Quando a série usa linha (não barra) — alinha a forma do indicador.
ChartTooltipContentindicator="dashed"Mesmo que line, mas para séries projetadas / pontilhadas.
ChartLegendContentdefaultMúltiplas séries cartesianas (Bar/Line/Area).
ChartLegendContentnameKey="plan"Pies — pega o label da chave do datapoint, não do dataKey.
ChartLegendContenthideIconQuando você quer só os labels textuais (raro — perde affordance de cor).

When to use

A escolha entre os 6 tipos depende da forma do dado — não do gosto. A matriz abaixo é a heurística canônica do KDS, com link para o esquema cromático recomendado em cada caso.

Pergunta do leitorTipo de gráficoEsquema de cor
"Como evoluiu ao longo do tempo, e qual o volume?"Area (single ou stacked)Categorical
"Qual a tendência ao longo do tempo, com várias séries?"Line (multiple)Categorical
"Como categorias se comparam em magnitude?"Bar verticalCategorical ou Sequential
"Como categorias com nomes longos se comparam?"Bar horizontalCategorical
"Qual a composição (parte/todo) com até 5 fatias?"Pie ou DonutCategorical
"Como esse sujeito se comporta em N dimensões?"RadarCategorical ou Comparison
"Quanto está concluído de uma meta?"RadialSequential ou Status
"Qual está em destaque vs as outras?"Bar ou LineComparison
"Estados discretos (sucesso/erro/aviso)?"Bar ou tileStatus
"Variação acima/abaixo de baseline?"Bar ou LineDivergent

When not to use

  • Geomaps — choropleth, bubble maps, point maps. Use uma lib dedicada (Mapbox GL, Leaflet, react-simple-maps).
  • Networks / sankey / hierarquias — Recharts não tem cobertura decente; instale Visx ou ECharts pontualmente para esses casos.
  • Heatmaps densos (matrizes >50×50) — performance e leitura caem; use ECharts ou D3 puro.
  • Charts críticos para acessibilidade plena — quando o gráfico é o conteúdo principal de uma página e precisa ser navegável por leitor de tela com semântica de tabela, considere renderizar também uma <table> correspondente em vez de depender só de SVG.

Best practices

Cor é o eixo de informação mais escasso da visualização — gaste com intenção. Cada cor adicional num gráfico aumenta carga cognitiva linear e degrada leitura para usuários com deficiência de cor.

Do

  • Use sempre tokens KDS (var(--color-chart-cat-N), --color-chart-status-*, etc) para cores de série. O sistema garante consistência multi-tema e segurança para daltonismo.
  • Limite Categorical a 5-6 séries — acima disso, agrupe ("Outros") ou troque para small multiples (vários gráficos pequenos).
  • Reserve Status para gráficos que encodam significado (sucesso/erro). Em charts puramente categóricos, usar verde = "bom" polui a leitura.
  • Mantenha a altura do ChartContainer fixa, mesmo durante loading. Layout shift em dashboards é particularmente desagradável.
  • Tooltips com hideLabel em pies e radials — o nome da fatia já é informação suficiente, o header redundante pesa.

Don't

  • Não use Pie com mais de 5 fatias — fatias finas viram ruído. Migre para Bar horizontal.
  • Não chumbe hex hardcoded em séries — viola a arquitetura de tokens e quebra dark mode.
  • Não confie só em cor para diferenciar séries críticas. Reforce com forma (sólido/tracejado), label direto na linha, ou ícone via config.icon.
  • Não empilhe Bar/Area quando a soma não tem significado real — o leitor vai inferir uma métrica composta que você não pretendeu comunicar.
  • Não use Divergent sem ponto central explícito (zero, baseline, média) — sem o pivô, a paleta vira só "duas cores".

Accessibility

Charts em SVG têm limitações herdadas: leitores de tela leem o SVG como uma lista de elementos, não como uma tabela tabular. O Chart KDS dá ferramentas para mitigar — não milagres.

RecursoComo aplicar
Color-blind safetyOs esquemas KDS já evitam os pares conflitantes (Red-Green em Divergent é proibido — usamos Red-Blue). Veja chart color schemes.
Reforço além de corUse config.icon na legenda, varie strokeDasharray em linhas, ou rotule séries direto no gráfico. Cor sozinha falha para 8% dos homens.
Aria labelsAdicione role="img" e aria-label no wrapper externo do ChartContainer descrevendo a métrica e o resumo: "Receita mensal: cresceu de R$ 18 mil em janeiro para R$ 33 mil em setembro.".
Fallback textualEm painéis críticos, renderize uma <table> visualmente oculta (sr-only) com os mesmos dados — leitores de tela preferem tabelas a SVG.
Tooltip e focoRecharts emite eventos de mouse e teclado, mas a navegação por teclado em séries não é trivial. Para dashboards críticos, considere eixos clicáveis e legendas como controles.
ContrasteTokens do KDS atendem WCAG AA contra fundo claro e escuro. Se redefinir cores ad-hoc, valide o contraste manualmente.
  • Tokens · Chart — os 5 esquemas canônicos com guia de uso por tipo de dado
  • Tokens · Sequential — gradiente de uma matiz para dados ordenados
  • Tokens · Categorical — hues distintos para categorias nominais
  • Tokens · Status — estado semântico discreto
  • Recharts — biblioteca subjacente, para composição de chart-types não cobertos aqui
  • ChartConfig type — exportado de @kalvner/kds/data/chart
  • Chart color schemes foundations (vault interno) — fundamentação acadêmica e de mercado dos 5 esquemas

On this page