Frontends com Vibecoding · Capítulo 15 de 33 · 37 min
Projetar gráficos e painéis pela decisão
O gráfico passa a ser escolhido pela pergunta que responde e a técnica de desenho pelo volume de pontos, com fonte e dono do número a dois cliques.
Este capítulo faz parte do curso gratuito Frontends com Vibecoding.
O velocímetro gasta um quarto da tela para mostrar um único número, porque obriga o olho a estimar ângulo em vez de comparar altura. O bullet chart, uma barrinha deitada com um traço marcando a meta, faz a mesma leitura numa linha fina e vence em qualquer painel de decisão.
Painel é a tela que reúne os poucos números que mandam no seu mês, cada um respondendo a uma pergunta. A pergunta de quem lê escolhe o gráfico, e o volume de pontos escolhe a técnica de desenho. A biblioteca entra por último, nunca por moda do agente (o assistente de IA que escreve código a partir do pedido).
A percepção decide a forma. Cleveland e McGill mediram que o olho compara posição e comprimento com muito mais precisão do que ângulo e área. É por isso que a barra vence a pizza.
Tufte acrescenta a razão dado-tinta: todo traço que não carrega dado é tinta a apagar, e o 3D decorativo é o caso mais caro. Wilkinson descreve qualquer gráfico como dado, marca e escala, sendo a escala a régua do eixo, aquela borda numerada onde o valor é lido.
Daí saem duas exigências para cada peça do painel: uma pergunta por gráfico e o denominador, o número pelo qual você dividiu, escrito à vista de quem lê.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Esses arranjos não são gosto de quem desenha. O estudo Dashboard Design Patterns, de Bach e outros, catalogou 144 painéis reais e encontrou 42 arranjos que se repetem. O problema, portanto, é o mesmo em quase toda empresa.
O painel evolui junto com o problema que ele mede, e a primeira entrega quase nunca é a definitiva. Por isso reserve orçamento para uma segunda rodada, depois que alguém tiver usado o painel para decidir alguma coisa.
Quatro trocas resolvem a maior parte dos pedidos, e cada uma responde melhor a uma pergunta. O bullet chart substitui o velocímetro quando a pergunta é se estamos na meta. O waterfall, a escadinha que mostra o que somou e o que subtraiu, explica a variação da margem degrau a degrau.
Small multiples são a mesma miniatura repetida para cada unidade ou cada mês, lado a lado. Eles substituem o gráfico único com dez linhas embaralhadas, porque o olho compara desenhos vizinhos sem esforço. O slopegraph liga dois períodos por uma reta e mostra quem subiu e quem caiu.
Escreva o período e o denominador dentro do próprio gráfico. Um crescimento de 40% sem base nem período é desenho bonito sem informação, porque quem lê fica sem saber se aquilo é muito ou pouco.
Numa rede de academias, a pizza de matrículas por unidade virou barra ordenada e o velocímetro de meta virou um bullet chart por unidade. O gerente vê em três segundos quem está atrás da meta, e a evasão aparece como cancelamentos divididos pelos ativos do início do mês.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
O volume de pontos decide a técnica de desenho. SVG guarda cada barra como um objeto da própria página. Isso facilita estilo, interação e leitura por quem usa tecnologia assistiva, desde que haja título e descrição.
Canvas desenha pixels soltos, como tinta numa folha, e o navegador deixa de saber o que é cada mancha. Em troca ele aguenta muito mais pontos. Por isso é a escolha de uma série densa, ou seja, uma sequência longa de valores ao longo do tempo.
O preço do canvas é a acessibilidade, que passa a depender de uma tabela equivalente ao lado. Compare uma amostra real nos dois formatos e meça o tempo de desenho no aparelho mais fraco do seu público.
A regra para painel de operação cabe numa frase: tente o ECharts 6.1 antes de inventar moda. Ele aguenta milhões de pontos porque desenha aos poucos, em vez de travar a tela até terminar tudo.
Em projeto React, a base mais usada para montar a tela em pedaços reaproveitáveis, o Recharts já liga a camada de acessibilidade sozinho. O MUI X Charts vence quando o projeto inteiro já roda MUI, e o Highcharts é a escolha corporativa, porque traz acessibilidade e leitura sonora no pacote.
O D3 serve à peça única, com anotação escrita à mão, e nunca a 30 gráficos comuns em cinco dias. O guia de gráficos do hub de design fixa esse padrão para todo painel do projeto, e nenhum painel novo nasce com uma biblioteca diferente da anterior.
Pergunta, gráfico e biblioteca: o mapa de decisão do painel
| Pergunta de quem lê | Gráfico que responde | Biblioteca ou técnica |
|---|---|---|
| Estamos na meta? | Bullet chart | HTML e CSS puro ou SVG à mão |
| O que explica a variação da margem? | Waterfall | HTML e CSS no board; ECharts 6.1 na investigação |
| Como cada unidade evoluiu no ano? | Small multiples | Observable Plot ou Vega-Lite 6.4 |
| Quem subiu e quem caiu entre dois períodos? | Slopegraph | Observable Plot; D3 se a peça leva anotação |
| Como os valores se distribuem? | Beeswarm ou histograma | ECharts 6.1 |
| Realizado, plano e projeção lado a lado? | Tabela de variância | Tabela HTML com algarismos tabulares e folha de impressão |
| Barras num app React? | Barras | Recharts v3; MUI X Charts v9 quando já roda MUI |
| Dezenas de milhares de pontos ao vivo? | Linha em canvas | uPlot (cerca de 40 kB) ou ECharts 6.1 |
| Como o preço andou tick a tick? | Candlestick | Lightweight Charts (35 kB) |
| Uma história anotada para o investidor? | Gráfico anotado | D3 |
Painel corporativo com exigência de acessibilidade e sonificação: Highcharts 12.5. Investigação com anotação e filtro cruzado: ApexCharts 7.1.
Um cartão de indicador dispensa gráfico e ainda assim exige uma escolha de biblioteca. Número que carrega uma vez e fica parado sai em HTML e CSS puro. Número que muda várias vezes na sessão, como o faturamento do dia, ganha com a animação dos dígitos. A direção da rolagem conta a tendência antes de a pessoa ler o valor.
O laboratório abaixo monta três indicadores com o number-flow, um pacote pequeno que anima a troca de dígitos e formata em pt-BR. Pause a atualização, compare com a versão em texto puro ao lado e observe o separador de milhar e a vírgula dos centavos. A regra: número parado fica em CSS, número ao vivo ganha a animação.
Animar indicadores que mudam ao vivo com formato pt-BR
Veja três indicadores fictícios rolarem a cada troca e compare com o número em texto puro. Pause, reinicie e observe o separador de milhar.
Três cartões de indicador mostram faturamento do dia em reais, pedidos e taxa de conversão, com valores fictícios que sobem e descem a cada três segundos. Os dígitos rolam na direção da mudança e a formatação segue o pt-BR, com R$ 1.234,50 e vírgula nos centavos. Um botão pausa a atualização e outro mostra o mesmo número em texto puro ao lado, para comparar as duas formas.
A demonstração interativa carrega quando este trecho entra na tela.
Antes do próximo pedido de painel ao agente, escreva a pergunta que cada peça responde. Troque pizza, velocímetro e 3D por barra, bullet chart e waterfall. Escolha a biblioteca pela tabela desta aula. Deu certo quando qualquer pessoa lê o gráfico e diz o período, o denominador e a decisão sem perguntar nada.
Montar o painel mensal e instalar a biblioteca de gráficos certa
Escolhido o gráfico pela pergunta e a técnica pelo volume, o board mensal pode ser montado em HTML e CSS, com fonte e dono a dois cliques.
O painel mensal do conselho sai em HTML e CSS puro, a dupla que desenha qualquer página, com a fonte e o dono ao lado de cada número. A biblioteca de gráfico entra depois, só na tela de investigação, onde alguém filtra e cruza dados até achar a causa.
Painel de diretoria e painel de operação respondem a públicos diferentes, e confundir os dois é o erro mais caro. O board, o grupo que aprova o mês, quer saber o que aconteceu, o que está em risco e o que fazer. Quem opera quer filtrar, cruzar e descer ao detalhe.
A regra dos dois cliques separa o painel pronto do rascunho. Se o conselheiro não descobre em dois cliques de onde veio o número, o que ele significa e quem responde por ele, a peça volta para a mesa.

Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Quatro peças cobrem quase todo painel mensal, e cada uma responde a uma pergunta. O cartão de indicador dá o nível, o bullet compara realizado com meta e o waterfall explica a variação degrau a degrau. A tabela de variância fecha a conta, com números alinhados e folha de impressão que sai certa.
Dê nome de componente (o bloco de código pronto que se encaixa na tela) a cada peça no pedido ao agente. O vocabulário executivo tem nove nomes: kpi-card, variance-table, waterfall-bridge, executive-callout, risk-matrix, marketing-funnel, decision-card, confidence-badge e methodology-note. Como cada nome tem um trabalho só, o agente para de inventar gráfico onde cabia um cartão.
Para o conselho, o HTML e o CSS puro costumam vencer o gráfico cheio de interação. A página carrega leve, imprime certo e dispensa biblioteca inteira só para mostrar um número e uma seta.
Laboratório ao vivo: kit de board em HTML e CSS
Cenário ilustrativo, números fictícios.
Receita do mês
R$ 812 mil
+6,4% contra o plano
Confiança: alta, dado fechado no ERP
fonte, definição, atualização, dono
Fonte: ERP, tabela de faturamento.
Definição: receita de ordens fechadas.
Atualização: diária, às 6h.
Dono: gerência financeira.
Suporte: onde a contagem animada não roda, o valor final aparece direto.
Realizado contra meta
Ordens fechadas412 de 400
Ticket médio1.971 de 1.908
Retrabalho3,1% de 4,0%
Suporte: barra e traço de meta são caixas comuns, e aparecem em qualquer navegador.
Ponte da margem, do plano ao realizado
Suporte: a ponte sai de cálculo em CSS; em tela estreita ela rola na horizontal.
Tabela de variância
Passe o mouse ou o foco numa linha para destacar o degrau da ponte.
| Indicador | Realizado | Plano | Desvio |
|---|---|---|---|
| Receita | 812 mil | 763 mil | +6,4% |
| Ordens | 412 | 400 | +3,0% |
| Ticket | 1.971 | 1.908 | +3,3% |
| Retrabalho | 3,1% | 4,0% | -0,9 p.p. |
Suporte: sem :has(), a tabela segue completa e só o destaque no degrau não aparece.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Na tela de investigação em React, a base mais usada para montar a tela em pedaços reaproveitáveis, o Recharts é o ponto de partida. Ele desenha em SVG e monta o gráfico encaixando peças prontas de barra, linha e eixo.
A instalação leva cinco passos: instalar o pacote, importar as barras e os eixos, e envolver o gráfico num contêiner que ajusta a largura sozinho. Depois passe a cor da marca pelo token, o valor de cor guardado com nome, como a etiqueta na lata de tinta. A camada de acessibilidade já vem ligada.
O erro mais comum é colocar esse contêiner dentro de uma divisão sem altura: ele tenta ocupar cem por cento de zero e nada aparece. Declare a altura em pixels. O segundo erro é o cinza de fábrica nos rótulos do eixo, a borda numerada onde o valor é lido, que reprova no teste de contraste.
Todo gráfico que sustenta decisão ganha a tabela equivalente, escondida da tela e presente para o leitor de tela, o programa que lê a página em voz alta. Nunca esconda com display:none, porque isso apaga o dado para todo mundo.
O Chartability é a auditoria que cobra isso peça por peça. A leitura sonora que o Highcharts traz entra como canal extra, para quem prefere ouvir a diferença.
Canvas e WebGL desenham pixels e devolvem nada ao leitor de tela. Por isso toda peça desenhada assim precisa, em paralelo, de uma camada com ARIA, as etiquetas invisíveis que descrevem o gráfico em palavras.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
A biblioteca entra quando a pessoa precisa investigar, e não apenas olhar. O ApexCharts 7.1 virou essa superfície. Ele deixa anotar o gráfico, medir distâncias, filtrar um gráfico pelo clique em outro e mandar a visão inteira por um link.
Use o ApexCharts quando o painel precisa dessa interação e você não quer trocar de biblioteca. Painel de operação com muito volume pede ECharts, e série financeira pede o Lightweight Charts, como a aula anterior mostrou.
O laboratório abaixo mostra o que essa escolha muda. Ele importa o ECharts por módulos, só linha, barra, dispersão, eixos, legenda e zoom, para o pacote não carregar o que o painel não usa. Troque o tipo de gráfico e suba o volume para 200 mil pontos: o mostrador de tempo diz quanto o desenho custou no seu aparelho.
Dois detalhes decidem. Na dispersão com 200 mil pontos, a tela recebe os primeiros pontos antes de o desenho terminar: é a renderização progressiva, que o Recharts não tem. O botão de eixo em zero mostra, com os mesmos dados, como o eixo cortado infla a diferença entre duas lojas. Abaixo desse volume, o Recharts continua a escolha mais simples.
Medir o custo de desenhar 200 mil pontos com o ECharts
Troque o tipo de gráfico e o volume de pontos, leia o tempo de desenho e alterne o eixo em zero. Mude o tema do site e veja as cores refazerem.
Um gráfico do ECharts com duas séries fictícias de pedidos por minuto, em linha, barra ou dispersão, com 2 mil, 50 mil ou 200 mil pontos por série. Um mostrador informa o tempo de desenho medido no aparelho, e um botão alterna entre eixo em zero e eixo cortado. As cores vêm das variáveis do tema e trocam junto com o tema escuro; uma tabela com mínimo, máximo e média acompanha o gráfico.
A demonstração interativa carrega quando este trecho entra na tela.
A fórmula de cada indicador vive em código versionado, numa camada semântica (o arquivo único onde a conta mora, como a receita anotada na cozinha). Assim nenhuma tela calcula receita recorrente, custo de aquisição ou retorno de mídia por conta própria.
Cube e dbt integraram as duas plataformas em julho de 2026, e o modelo do dbt passou a valer como fonte única dessas contas. O motivo é a IA: o agente acerta quando lê a fórmula pronta e erra quando traduz a pergunta direto em consulta ao banco.
Quem dispensa a plataforma inteira tem o Boring Semantic Layer, uma camada leve com a mesma ideia e bem menos peça para manter.
Num escritório de contabilidade, a definição de margem passou a viver num arquivo só, lido por todas as telas. Duas empresas atendidas deixaram de receber a mesma conta feita de dois jeitos.
Antes de fechar o próximo painel mensal, nomeie cada peça como componente no pedido ao agente. Exija fonte, definição, data e responsável dentro do próprio cartão, abertos em um clique. Tire a fórmula dos indicadores das telas e faça todas lerem o mesmo arquivo. Deu certo quando dois relatórios diferentes mostram o mesmo número.
Guia prático: número animado só quando é real, com a origem anotada
Número que sobe na tela chama atenção, e é por isso que ele precisa ser verdadeiro. Nos 51 templates medidos em 07/10/2026, sinais de contador animado aparecem em 28. Nos de advocacia e clínica, os números do topo, como anos de atuação, casos conduzidos e taxa de êxito, são exemplos do template: animam bonito e não pertencem a ninguém.
O curso de edição estudado no mesmo dia tem duas regras que valem para painel e página. A primeira: nada na tela que a pessoa não disse ou não aprovou, e o contador para exatamente no número dito. A segunda: dado de terceiros entra real. No estudo, as estrelas de um repositório citado foram consultadas pela API do GitHub no dia da edição, e o número animado foi o daquele dia, com a origem registrada no arquivo de entrega.
O contador também precisa ser determinístico. O material evita o contador que recalcula a cada quadro e usa valores liberados em tempos fixos. Na página, isso quer dizer: o número final já escrito no HTML, duração fixa, nenhum valor aleatório e, com movimento reduzido ligado, o número final direto. O template de painel contábil mostra o outro lado da mesma regra: sem dados, os cartões exibem 0 ou um traço, com uma dica de como começar, em vez de número de exemplo.
// Contador determinístico: o valor final já está no HTML e a origem vai junto.
// <span class="contador" data-final="1284" data-origem="API do GitHub, 07/10/2026">1.284</span>
const fmt = new Intl.NumberFormat("pt-BR");
const reduzir = matchMedia("(prefers-reduced-motion: reduce)").matches;
for (const el of document.querySelectorAll<HTMLElement>(".contador")) {
const final = Number(el.dataset.final);
el.title = `Fonte: ${el.dataset.origem}`;
if (reduzir || !Number.isFinite(final)) continue; // fica o número final escrito
const obs = new IntersectionObserver(([e]) => {
if (!e.isIntersecting) return;
obs.disconnect();
const inicio = performance.now();
const DURACAO = 1200; // fixa
const passo = (agora: number) => {
const p = Math.min((agora - inicio) / DURACAO, 1);
el.textContent = fmt.format(Math.round(final * (1 - (1 - p) ** 3)));
if (p < 1) requestAnimationFrame(passo);
else el.textContent = fmt.format(final); // termina exatamente no valor aprovado
};
requestAnimationFrame(passo);
}, { threshold: 0.6 });
obs.observe(el);
}Do número de exemplo ao número com dono
Cinco passos antes de deixar qualquer número subir na tela.
Passo 1: Liste todo número que aparece na página ou no painel
Peça ao agente a lista de cada número visível, com o arquivo onde está e de onde ele veio. Número sem origem conhecida é número de exemplo até prova em contrário.
Deu certo quando: Cada número tem uma linha com valor, lugar e origem.
Erro comum: Deixar a taxa de êxito que veio no template porque parece plausível.
Passo 2: Consulte o dado de terceiros na fonte, no dia
Estrelas de repositório, avaliação de loja, número de alunos: consulte a fonte oficial na data da publicação, por API quando houver, e anote valor e data.
Deu certo quando: O número publicado bate com a fonte na data anotada.
Erro comum: Copiar o número de uma reportagem antiga e animá-lo como se fosse de hoje.
Passo 3: Escreva o valor final no HTML
O contador parte de um número que já está na página, como no bloco acima. Sem JavaScript, para buscador e com movimento reduzido, aparece o valor certo.
Deu certo quando: Com o JavaScript desligado, a página mostra o número final.
Erro comum: Começar o HTML em 0 e depender da animação para mostrar o valor real.
Passo 4: Deixe a origem a um toque
Fonte e data ficam junto do número: no atributo, num rodapé do cartão ou numa nota. Num painel, o responsável pelo dado também.
Deu certo quando: Quem lê descobre de onde veio o número sem perguntar a ninguém.
Erro comum: Guardar a origem só na conversa com o agente.
Passo 5: Desenhe o estado sem dado
No painel, cartão sem dado mostra traço ou zero com uma dica do que fazer, como o template contábil faz. Nunca preencha com número de exemplo para a tela parecer cheia.
Deu certo quando: O painel vazio orienta o próximo passo e não mostra número inventado.
Erro comum: Publicar a demonstração com dados fictícios que o cliente toma por reais.
No fim você tem: Números animados que terminam no valor aprovado, aparecem certos sem JavaScript e levam fonte e data junto.
Coordenadora de marketing de uma escola de programação online que refaz a faixa de números da página de vendas
Educação online, matrícula
Dor
A faixa exibia alunos formados, nota média e estrelas do repositório aberto da escola, todos animados. Ninguém sabia de quando eram os números, e um deles vinha de uma apresentação de dois anos antes.
Solução
Ela listou os números com o agente, consultou alunos e nota no sistema da escola e as estrelas na API do GitHub no dia, gravou valor e data em cada contador e tirou o número que não tinha fonte.
Resultado
A faixa ficou com três números conferidos e datados, e a atualização passou a ser uma tarefa mensal com a fonte de cada um.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Guia prático: a cor do gráfico medida nos dois temas e lida do CSS
A aula escolheu o gráfico pela pergunta e a biblioteca pelo volume. Este guia cuida da cor: a barra precisa de contraste contra o fundo nos temas claro e escuro, as séries precisam continuar distintas para quem tem daltonismo, e o componente não pode guardar hexadecimal próprio. Você sai medindo a paleta antes de aprovar e ligando a descrição e a textura do ECharts.
Funções, casos de uso e aplicações
Funções
Cor, descrição e movimento no gráfico do painel
| Função ou recurso | O que faz | Quando usar | Referência |
|---|---|---|---|
| Contraste de 3:1 do desenho | Barra, linha e fatia precisam de 3:1 contra a cor vizinha | Todo gráfico que sustenta decisão; se rótulo e valor já dizem tudo, a fatia fica isenta | W3C, WCAG 2.2, critério 1.4.11 |
| aria do ECharts (show e enabled) | Gera uma descrição a partir de título, tipo e dados e põe no aria-label do contêiner | Gráfico com poucos itens; com muitos, escreva a sua em aria.description | Apache ECharts, manual de acessibilidade |
| aria.decal do ECharts | Aplica textura (listras, pontos) sobre cada série | Quando a cor sozinha não separa as séries: impressão em preto e branco, daltonismo | Apache ECharts, manual de acessibilidade |
| Cor lida do token com getComputedStyle | O gráfico pede a cor à variável CSS (o token) em vez de guardar hexadecimal | Painel com tema claro e escuro; refaça a opção do gráfico quando o tema muda | Portal, src/components/admin/charts/EChart.tsx |
| Simulação de daltonismo por pares | Mede a distância entre cada par de cores sob deuteranopia, protanopia e tritanopia | Antes de aprovar a paleta categórica | Portal, src/lib/admin/chart-tokens.ts |
| animation desligada com movimento reduzido | Desenha o gráfico parado para quem pediu menos movimento ao sistema | Todo gráfico animado | Portal, src/components/admin/charts/EChart.tsx |
Cor nunca carrega a informação sozinha: rótulo na ponta e marcador continuam obrigatórios.
Casos de uso
Coordenadora de marketing de uma faculdade a distância em Belo Horizonte
Educação
Dor
No painel de matrículas por canal, as linhas de Google e Meta, azul e violeta, viravam a mesma cor para um diretor com daltonismo, e no tema escuro o cinza da grade sumia.
Solução
Pediu ao agente a paleta como tokens com valor para os dois temas, um teste que mede contraste de 3:1 contra os dois fundos e a distância entre pares sob três tipos de daltonismo, e rótulo na ponta de cada linha.
Resultado
O que observar: o teste passa nos dois temas e o diretor lê o canal certo sem legenda na próxima reunião mensal.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Gestor de tráfego de uma agência em Porto Alegre que entrega relatório mensal em PDF
Marketing digital
Dor
O cliente imprime o relatório em preto e branco, e as quatro séries de investimento por campanha ficam iguais no papel.
Solução
Ligou aria.decal no ECharts, que põe textura diferente em cada série, e manteve a tabela de valores logo abaixo do gráfico.
Resultado
O que observar: na impressão de teste, cada série se distingue pela textura antes de o cliente pedir a versão colorida.
Cenário construído para fins didáticos. Números não correspondem a cliente específico.
Na prática
No /admin deste portal, a paleta de gráficos vive como variáveis --adm-chart-1 a --adm-chart-8 em src/app/admin/admin-tokens.css. O espelho medido dela fica em src/lib/admin/chart-tokens.ts, e um teste compara os dois valor a valor. O registro conta por que a paleta mudou em 06/10/2026: passava no contraste, mas azul e violeta colapsavam sob deuteranopia, porque a matiz some e sobra a luminosidade. A correção espalhou a clareza entre as séries. O invólucro do ECharts lê a cor do token e liga a descrição e o movimento reduzido.
export function opcoesBase(tema: EChartTema, reduzirMovimento: boolean): EChartOption {
return {
color: tema.categorias,
backgroundColor: "transparent",
// descrição gerada pelo ECharts no próprio SVG; a
// tabela irmã da moldura continua sendo a leitura completa.
aria: { enabled: true },
animation: !reduzirMovimento,
animationDuration: 420,
textStyle: { fontFamily: tema.fonte, fontSize: tema.fontePx, color: tema.rotulo },
// ...
};
}// contraste.ts — rode com: npx tsx contraste.ts
// Razão de contraste da WCAG entre duas cores em hexadecimal.
function luminancia(hex: string): number {
const [r, g, b] = [1, 3, 5].map((i) => {
const c = parseInt(hex.slice(i, i + 2), 16) / 255;
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
});
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
function razao(a: string, b: string): number {
const [l1, l2] = [luminancia(a), luminancia(b)].sort((x, y) => y - x);
return (l1 + 0.05) / (l2 + 0.05);
}
const fundos = { claro: "#ffffff", escuro: "#111827" };
const paleta = ["#2563eb", "#7c3aed", "#059669", "#d97706"]; // troque pela sua
for (const cor of paleta) {
for (const [tema, fundo] of Object.entries(fundos)) {
const r = razao(cor, fundo);
// Desenho (barra, linha) pede 3:1; texto pede 4,5:1
console.log(cor, tema, r.toFixed(2), r >= 3 ? "ok" : "REPROVA");
}
}Da paleta bonita à paleta que todo mundo lê
Passo 1: Hexadecimal fora dos componentes
Procure por # nos arquivos de gráfico. Cada cor encontrada vira token com nome de papel: série, meta, melhora, piora, sem dado.
Deu certo quando: A busca por hexadecimal nos componentes de gráfico volta vazia.
Passo 2: Meça cada cor contra os dois fundos
Rode o script de contraste. Desenho pede 3:1; rótulo e eixo, 4,5:1.
Erro comum: Medir só no tema claro e descobrir o escuro na reunião.
Passo 3: Simule daltonismo nos pares
Use o simulador de visão do DevTools do Chrome, na aba Rendering, e olhe os pares vizinhos. Se dois se confundem, mude a clareza de um deles além da matiz.
Passo 4: Ligue descrição e textura
aria.enabled com aria.description em português e aria.decal.show para a versão impressa.
Deu certo quando: O leitor de tela anuncia o gráfico em português, e a impressão em preto e branco separa as séries.
Passo 5: Teste de contraste na esteira
O teste de contraste roda a cada proposta e reprova a cor que cair abaixo do piso.
No fim você tem: A paleta passa nos dois temas e sob daltonismo, e a troca de cor acontece num arquivo só.
Armadilhas
Contraste bom não garante séries distintas
Meça contraste contra o fundo e distância entre os pares, nos dois temas.
- Clareza igual com matiz diferente colapsa sob deuteranopia
- Grade e eixo podem ficar abaixo de 3:1; a série, não
- Descrição automática do ECharts sai em inglês se você não escrever a sua
- Textura ajuda no papel, mas o rótulo na ponta continua
- Hexadecimal no componente ignora a troca de tema
O teste: Imprima o painel em preto e branco: cada série ainda se distingue?
alexandrecaramaschi.com/educacao/frontends-com-vibecoding
Aplicar os recursos ao projeto
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
O Apache ECharts monta gráfico como quem preenche uma ficha: você descreve dados, eixos, séries e interações num único objeto de configuração. Essa ficha se repete com filtros diferentes sem refazer o desenho, o que economiza trabalho em painéis. Escolha o ECharts quando o painel tiver muitas telas parecidas e precisar de exploração.
Imagine vendas por filial na sua rede. Crie uma caixa na página com altura definida, ligue o gráfico a ela com echarts.init, o comando que acende a tela, e mande barras e valores por setOption. Ponha real no eixo e repita a chamada quando o mês mudar.
Abra a página e veja se o gráfico aparece: caixa sem altura definida fica vazia, e esse é o erro comum. Estique a janela e confirme que o desenho acompanha. Navegue pelos filtros só com Tab e Enter, e compare os números com a tabela que originou o painel.
D3 entrega peças soltas, como um kit de marcenaria: escalas convertem números em posições, formas desenham caminhos e seleções colam cada dado num elemento da tela. Você manda no desenho inteiro e, em troca, monta eixo, estado e interação na mão. Vale o esforço quando nenhum gráfico pronto responde à sua pergunta.
Digamos que você compare preços de três fornecedores. scaleLinear vira a régua que transforma reais em altura, e scaleBand reserva uma faixa para cada empresa. Desenhe uma barra por registro com data e join, usando o nome como chave, e atualize rótulo e largura quando a lista mudar.
Escala invertida ou domínio que ignora número negativo troca a conclusão sem avisar. Teste primeiro com dados que você já conhece de cor e confira os dois extremos. Valor ausente merece tratamento à parte, senão vira zero na tela. Para distribuir a figura sem D3, exporte o SVG pronto.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Vega-Lite descreve um gráfico como receita escrita. Num arquivo JSON, texto simples que guarda dados e regras, você diz a marca visual e liga cada campo a posição, cor ou tamanho. A biblioteca calcula o resto. Serve bem quando a mesma análise volta todo mês e precisa sair igual.
Para acompanhar receita mensal, coloque os registros em data.values, marque mark como line e, no encoding, ponha o mês no eixo do tempo e a receita como quantidade. Se quiser comparar filiais, acrescente uma faceta, que reparte o gráfico em painéis pequenos. Guarde o arquivo junto da tabela de origem.
Campo numérico lido como texto muda a escala e põe março antes de fevereiro. Olhe os tipos declarados antes de confiar na linha. Mês sem registro some do gráfico e finge queda; marque esses buracos. No pacote offline, troque endereço remoto de dados por valores dentro do próprio arquivo.
Observable Plot junta marcas, escalas e transformações para você tirar um gráfico do caminho com poucas decisões. Pontos, linhas e barras dividem os mesmos dados e as mesmas dimensões, então a figura sai rápida. Vale para exploração e para ilustrar um texto. A plataforma Observable é outro produto e não é necessária aqui.
Suponha que os prazos de entrega estejam escorregando. Monte Plot.plot com uma marca de pontos, data no eixo horizontal e duração no vertical, e separe as transportadoras em painéis pequenos quando os pontos se embolarem. Escreva a conclusão no próprio título e deixe a tabela dos registros ao lado da figura.
Agrupamento e filtro escondem entrega cancelada ou sem data, e o gráfico continua bonito. Some o total que aparece na figura e compare com o total da base; se der diferente, diga no texto qual recorte você usou. Para ler sem internet, exporte o SVG ou empacote biblioteca e dados.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Chart.js desenha em Canvas, uma tela de pixels que o código pinta ponto a ponto. Você separa o tipo de gráfico, os conjuntos de dados e as opções de aparência em três partes da configuração. É uma escolha tranquila para série e comparação comuns, com atualização e interação já prontas.
Pense num painel de despesas do mês. Crie um elemento canvas, instancie Chart com type igual a bar e passe categorias e valores dentro de data. Comece o eixo numérico em zero, senão a diferença entre barras engana o olho de quem lê. Ao trocar de mês, mude os dados e chame update.
Canvas não conta a um leitor de tela o que está desenhado. Entregue junto uma descrição curta e a tabela com os mesmos números, e veja a tela funcionar com a animação desligada. Defina o tamanho pelo contêiner, destrua a instância antiga ao remontar e guarde a biblioteca localmente.
Recharts monta gráfico com peças de React, o mesmo material da sua tela, e desenha quase tudo em SVG, o formato de imagem que não perde nitidez. Eixo, série e legenda viram componentes que você encaixa. Compensa num produto que já roda em React; para uma figura solta, gerar a imagem antes dá menos manutenção.
Se você acompanha pedidos por semana, ponha BarChart dentro de ResponsiveContainer, o invólucro que mede o espaço disponível. Informe a lista em data e ligue Bar ao campo de quantidade por dataKey. Acrescente XAxis com a semana e YAxis com a unidade escrita por extenso.
Legenda bonita não garante que a pessoa chegue ao número pelo teclado. Percorra o gráfico só com Tab e ofereça resumo e tabela embaixo. O contêiner precisa de altura definida, senão nada aparece. Encurte rótulo longo no celular e empacote React, Recharts e os registros para ler sem rede.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
visx entrega peças de visualização para React, com as contas de escala vindas do mundo do D3. Você desenha a linguagem visual da sua empresa do zero e fica com as decisões de composição e acessibilidade no colo. Escolha quando vários painéis precisam se parecer entre si.
Para mostrar prazo prometido contra prazo cumprido, use uma escala só para os dois valores e ligue os pontos de cada fornecedor por uma linha. Os componentes de eixo e de grupo arrumam a figura, e o React controla o filtro de período. Escreva o número ao lado do ponto.
Rótulo que colide, escala com domínio torto, foco perdido e dado ausente continuam por sua conta ao usar primitivas. Compare o desenho com uma tabela de referência e teste com um fornecedor de nome comprido. Importe só os pacotes usados e deixe os dados prontos dentro do próprio arquivo quando a leitura for sem internet.
uPlot foi feito para séries no tempo: muitos instantes, uma linha por sensor, cursor que corre e janela que você aperta ou alarga. Ele desenha em Canvas e vai rápido porque faz pouco. Em troca, você prepara os dados antes, e a agregação e a explicação das medidas ficam com você.
Digamos que a câmara fria registre temperatura o dia inteiro. Monte a primeira sequência com os instantes e as seguintes com as medições, uma série por sensor, e escreva a unidade na legenda. Falta de coleta precisa aparecer como falta, mantendo cada valor colado ao seu horário.
Duas listas de tamanhos diferentes fazem a leitura de um sensor cair no horário do outro, e o gráfico não reclama. Confira comprimento, ordem e buracos antes de olhar para velocidade. Meça o consumo de memória no próprio equipamento, ofereça resumo e tabela, e guarde os arquivos locais junto do documento.
A biblioteca muda o trabalho de composição
| Abordagem | Exemplos | Você decide |
|---|---|---|
| Configuração de gráfico | ECharts, Chart.js, Plotly | Métrica, interação e entrega |
| Gramática declarativa | Vega-Lite, Plot | Campos e representações |
| Componentes React | Recharts, Nivo | Composição da aplicação |
| Primitivas | D3, visx | Desenho e comportamento |
As famílias têm capacidades sobrepostas; a tabela organiza o nível de composição e não estabelece ranking de qualidade ou desempenho.
Plotly.js traz gráficos de investigação, com zoom e seleção prontos para quem quer garimpar dados. Cada série carrega as próprias propriedades e um objeto de layout cuida de título, eixos e aparência. Essa variedade custa peso no pacote, então decida entre desenho vetorial e aceleração pela placa de vídeo.
Quando a dúvida for se entrega longe demora mais, chame Plotly.newPlot com uma série scatter, que espalha pontos, e mode igual a markers. Passe as listas de distância e de prazo e nomeie as unidades no layout. Selecione um grupo de pontos e deixe o filtro e a tabela à vista.
Nuvem de pontos mostra que duas coisas andam juntas, e só. Olhe primeiro os casos extremos e diga o que você excluiu antes de escrever a conclusão. Série em WebGL, que usa a placa de vídeo, some em máquina sem esse recurso: teste com ela desligada e deixe uma figura estática no pacote.
Highcharts junta gráficos e módulos de acessibilidade, exportação e sonificação, que é transformar dado em som para quem não enxerga a tela. Aqui a decisão passa pelo contrato, e não só pelo recurso. Produto comercial precisa da licença certa; instalar a biblioteca e conseguir desenhar não dá direito de redistribuir.
Ao configurar um orçamento por área, dê nome claro a cada série e ligue o módulo de acessibilidade junto com o gráfico. Escreva a medida e o período, e mantenha a tabela dos valores por perto. Se a tela tiver botão de exportar, escolha os formatos e prepare as dependências locais.
Exportação costuma sair escondida por um servidor de fora mesmo com o gráfico desenhado na sua máquina. Desligue fallbackToExportServer, empacote todas as bibliotecas auxiliares e teste com a rede cortada. Depois confira a licença do seu produto e valide teclado, descrição e arquivo exportado na versão que você instalou.
Se a figura ultrapassar a área visível, deslize para os lados. Pelo teclado, foque a figura e use as setas.
Nivo entrega gráficos prontos como componentes de React, e cada família traz opções próprias de desenho. Você declara dados, margens, eixos e tema, sem montar a composição inteira na mão. Escolha o componente pela pergunta que o gráfico responde e pense desde já em como a figura vai ser impressa.
Imagine os atendimentos por equipe no mês passado. Use o componente de barras, aponte o campo de categoria em indexBy e as medidas em keys, que é a lista de colunas a empilhar. Dê altura ao contêiner quando usar a versão responsiva, combine o tema com as cores do site e mostre os números numa tabela.
Contêiner com altura zero deixa o gráfico invisível, e tema incompleto apaga os eixos no modo escuro. Teste os dois temas, lista vazia e nome de equipe bem comprido. Para leitura sem rede, empacote componentes e registros; abrir o documento não pode depender de um serviço externo que gera imagem.
ColorBrewer é um mostruário de paletas escolhidas conforme o tipo de dado. Escala sequencial mostra intensidade, divergente mostra afastamento de um centro e qualitativa separa categorias que não têm ordem. Case a paleta com a pergunta do gráfico, senão a cor sugere hierarquia que a medida não tem.
Se você mostra taxa de atendimento por região, use a escala sequencial e explique na legenda como a taxa foi calculada. Para desvio em relação à meta, use a divergente com o centro na própria meta. Copie os valores de cor para o código e escreva um rótulo em cada faixa.
Paleta aprovada em um cenário não garante contraste em outro fundo, outro tamanho ou com mais classes. Olhe a figura no tema claro, no escuro e impressa em preto e branco. Repare se a informação sobrevive sem cor, depois revise os limites das faixas e guarde a origem da paleta na configuração.
Laboratório visual: projetar gráficos e painéis pela decisão
Pergunta, métrica, escala e próxima ação
Com a base em zero, o comprimento das barras é proporcional aos valores. Dados fictícios para estudar escala; não representam desempenho de modelos ou resultados de empresas.
Consultar os dados e o método
| Versão | Unidades |
|---|---|
| A | 80 |
| B | 90 |
| C | 100 |
Altura = (valor − início do eixo) ÷ (100 − início do eixo). A troca muda a escala, preservando os dados.
Seu caderno neste capítulo
Abrir o caderno completoSelecione um trecho do capítulo para destacar ou anotar. Nos vídeos e áudios, use Anotar este momento. No teclado, selecione com Shift e as setas e use Alt+Shift+D para destacar ou Alt+Shift+N para anotar.
Salvo neste navegador. Entre na sua conta para levar o caderno a outros aparelhos.
Entre na sua conta para compartilhar o que aprendeu e convidar alguém para estudar com você.
Conexões deste capítulo
Veja o que estudar antes e para onde seguir depois, explore os conceitos e compare abordagens em outros cursos. Sugestões marcadas como “sugerido pelo grafo” vêm dos assuntos em comum, não do índice do curso.
Estude antes
- CursoClaude Code CLI: Programação com IA
- Montar vídeo em React com Remotion e renderizar na sua máquina ou na AWSsugerido pelo grafoApresenta o conceito “React”, usado em “Projetar gráficos e painéis pela decisão”.
- O que é JavaScriptsugerido pelo grafoApresenta o conceito “JavaScript”, usado em “Projetar gráficos e painéis pela decisão”.
- Montar vídeo em HTML com HyperFrames e escolher entre ele e o Remotionsugerido pelo grafoApresenta o conceito “HTML”, usado em “Projetar gráficos e painéis pela decisão”.
Conceitos deste capítulo
O mesmo assunto em outros cursos
- SEO ProgramáticoTestar o template no pior caso e achar o tetoExaminar conexões de Testar o template no pior caso e achar o teto
- Google Analytics 2027Montar o painel executivo dentro do próprio AnalyticsExaminar conexões de Montar o painel executivo dentro do próprio Analytics
- Dados com PythonVisualizações para negóciosExaminar conexões de Visualizações para negócios
- Astra profundoProjetar animações que orientam a açãoExaminar conexões de Projetar animações que orientam a ação
Voltar ao capítulo anterior: Publicar conteúdo encontrável em vários idiomas
Leve uma ideia para a prática
Escolha uma atividade no painel e volte a este curso quando quiser.
Atividades e evolução ficam reunidas no painel da sua conta.
Laboratórios ao vivo deste curso
Cada laboratório monta a biblioteca real dentro da aula, com controles para você mexer e o código do exemplo para copiar. O texto de reserva descreve a demonstração para quem lê sem JavaScript. O link abre o capítulo já no ponto do laboratório.
Base UI
Prenda o foco num diálogo sem escrever o comportamento
Abra a janela Agendar visita, percorra os campos com Tab, feche com Esc e acompanhe no painel onde o foco está e para onde ele volta.
Pacote
Abrir no capítuloConstruir componentes, usar o registro e publicar o catálogo@base-ui/reactLucide e Iconify
Mantenha uma família de ícones coerente e nomeie cada botão
Mude tamanho, traço e cor da barra, veja o símbolo do Iconify acompanhar o Lucide e rode a auditoria de nomes acessíveis.
Pacote
Abrir no capítuloProjetar uma linguagem de ícones e ilustraçãolucide-react, @iconify/reactMotion
Testar os três sinais que autorizam o terceiro degrau
Reproduza a entrada em sequência, aperte o botão com mola e arraste o cartão; ajuste rigidez e amortecimento e veja o que muda.
Pacote
Abrir no capítuloProjetar movimento, assinatura e narrativas por rolagemmotionVidstack
Ver o que separa um player de um vídeo cru
Dê o play, troque a velocidade e ligue a legenda; o painel ao lado mostra o estado que o player publica e que a etiqueta crua esconde.
Pacote
Abrir no capítuloProjetar movimento, assinatura e narrativas por rolagem@vidstack/reactcmdk
Achar um destino entre quarenta digitando três letras
Abra a paleta, digite fat e escolha um item só pelo teclado; o painel embaixo conta o que o filtro deixou passar e quanto tempo levou.
Pacote
Abrir no capítuloConstruir formulários e estados de interaçãocmdknumber-flow
Animar indicadores que mudam ao vivo com formato pt-BR
Veja três indicadores fictícios rolarem a cada troca e compare com o número em texto puro. Pause, reinicie e observe o separador de milhar.
Pacote
Abrir no capítuloProjetar gráficos e painéis pela decisão@number-flow/reactApache ECharts
Medir o custo de desenhar 200 mil pontos com o ECharts
Troque o tipo de gráfico e o volume de pontos, leia o tempo de desenho e alterne o eixo em zero. Mude o tema do site e veja as cores refazerem.
Pacote
Abrir no capítuloProjetar gráficos e painéis pela decisãoechartssharp e svgo
Escolher a variante certa da imagem e conferir o teto de 150 KB
Arraste a largura da tela simulada, troque a densidade entre 1x e 2x e veja qual arquivo o navegador escolhe, quanto ele pesa e se cabe no orçamento.
Pacote
Abrir no capítuloValidar desempenho, autenticação e segurançasharp, svgoReact Flow (xyflow)
Disparar um pedido e ver o orquestrador distribuir, conferir e responder
Alterne paralelo e sequencial, ligue e desligue a verificação e use a medição real; observe o tempo de parede em cada combinação.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robô@xyflow/reactGSAP, Web Workers e number-flow
Dividir mil tarefas entre trabalhadores reais e correr três ritmos de geração
Execute com um trabalhador, depois com quatro e oito, e compare o tempo; em seguida percorra a corrida e separe a espera inicial do ritmo.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robôgsap, @number-flow/reactThree.js com React Three Fiber, drei, Rapier e XR
Carregar o braço robótico, ver a física trabalhar e entrar na cena com o visor
Carregue a cena pelo botão, inicie o ciclo, mostre os ângulos das juntas, troque a câmera e a velocidade; com visor, entre em realidade virtual.
Pacote
Abrir no capítuloConstruir as cenas do orquestrador, do paralelismo e do robôthree, @react-three/fiber, @react-three/drei, @react-three/rapier, @react-three/xrMotion
Ver quatro agentes em raias trocando mensagens e a revisão devolvendo um trecho
Reproduza os 60 s de modelo, percorra o tempo pelo controle e esconda as mensagens para comparar a leitura; repare no tempo de parede contra a soma.
Pacote
Abrir no capítuloEspecificar, medir e produzir as cenas da máquinamotionMediaRecorder, Canvas 2D e Long Animation Frames (plataforma)
Medir o quadro da cena e gravar seis segundos dela em vídeo
Suba as partículas, force um bloqueio de 300 ms e leia o medidor; depois grave seis segundos, veja o codec escolhido e baixe o arquivo.
Pacote
Abrir no capítuloEspecificar, medir e produzir as cenas da máquinasem pacotesigma.js, graphology com ForceAtlas2 e cosmos.gl
Ver o grafo real do curso e um grafo de milhares de nós se organizarem em aglomerados
Rode o layout no grafo real, passe o mouse pelos nós e busque uma entidade; troque para 20 mil nós e leia o medidor; depois carregue o modo massivo na placa de vídeo.
Pacote
Abrir no capítuloAnimar um grafo de conhecimento amplo em movimentosigma, graphology, graphology-layout-forceatlas2, graphology-generators, @cosmos.gl/graph
Capítulos vizinhos em Frontends com Vibecoding
- 13Construir formulários e estados de interação
- 14Publicar conteúdo encontrável em vários idiomas
- 15Projetar gráficos e painéis pela decisão
- 16Dimensionar tabelas e organizar o cálculo das métricas
- 17Escolher mapas, diagramas e cenas espaciais