Gráficos de painel sem uma única dependência
Construímos as linhas de tendência, os sparklines e as barras por categoria do nosso painel como SVG simples embutido. Sem biblioteca de gráficos, algumas centenas de linhas ao todo, modo escuro de borla. Eis a defesa dos gráficos feitos à mão, e de quando não os deve fazer de todo.
Quando acrescentámos um painel de inventário, o movimento óbvio era instalar uma biblioteca de gráficos. As mais conhecidas são excelentes. Também são grandes, têm opinião sobre temas, e foram feitas para aguentar mil casos quando nós precisávamos de quatro: uma linha de tendência com duas séries, um sparkline por linha, uma barra de nível de stock e uma repartição por categoria. Escrevemo-los antes como SVG embutido, e o conjunto todo ficou mais pequeno do que as definições de tipos da maioria das bibliotecas.

Um gráfico é um caminho
Tire as ferramentas do meio e um gráfico de linhas é uma cadeia de caracteres: um caminho SVG construído a partir dos seus valores. Mapeie o índice de cada ponto para x, cada valor para y, e junte-os. A única subtileza que vale a pena escrever é o espaçamento: mapeie o valor máximo uns pixels abaixo do topo, ou o traço do pico fica cortado ao meio pelo viewBox.
const W = 300, H = 80, PAD = 3; // top pad so the peak stroke is not clippedconst max = Math.max(1, ...values);const x = (i) => (i / (values.length - 1)) * W;const y = (v) => PAD + (H - PAD) * (1 - v / max); const d = values .map((v, i) => `${i === 0 ? 'M' : 'L'}${x(i).toFixed(1)} ${y(v).toFixed(1)}`) .join(' '); // <path d={d} fill="none" stroke="var(--color-primary)" strokeWidth="2" />O modo escuro não custa nada
A vitória discreta é o tema. Os nossos tokens de design são variáveis CSS, e os traços e preenchimentos de SVG aceitam-nas como qualquer outra propriedade. stroke="var(--color-primary)" quer dizer que o gráfico se recolore no instante em que o tema muda, sem configuração de tema ao nível do gráfico, sem paleta duplicada e sem divergências entre os gráficos e o resto da interface. Quando mais tarde afinámos a nossa paleta escura, os gráficos acompanharam sem lhes tocarmos.

As pontas são suas
As bibliotecas são generosas em funcionalidades e avarentas nos casos limite que só a si dizem respeito. O que deve fazer um sparkline com um único ponto de dados? O que diz o gráfico de tendência quando um negócio é novinho em folha e todos os valores são zero? Os componentes feitos à mão tornam estas decisões explícitas e baratas: um estado vazio honesto com uma frase, uma linha reta em vez de uma falha, um resumo em texto ao lado de cada gráfico para os leitores de ecrã, e uma única media query prefers-reduced-motion que desliga a animação de desenho.
- Dê a todos os gráficos um aria-label e um resumo em linguagem simples. O SVG é decoração; a frase é que são os dados.
- Anime os traços com stroke-dashoffset para o efeito de desenho, e ponha isso atrás de prefers-reduced-motion.
- Mantenha as contas e a marcação juntas. Um componente de gráfico que se lê de cima a baixo num ecrã é um gráfico que se consegue corrigir às 23 horas.
- Desenhe primeiro o estado vazio. As contas novas veem-no mais do que qualquer outro estado.
Quando deve usar uma biblioteca
Fazer à mão deixa de ser esperto no momento em que os requisitos ganham dentes. Zoom e seleção por arrasto, escalas logarítmicas, áreas empilhadas com interpolação como deve ser, eixos com colocação inteligente de marcas, desenho em canvas para dezenas de milhares de pontos: são problemas resolvidos, e resolvê-los outra vez à mão é como uma funcionalidade de dois dias se torna um passatempo de dois meses. A nossa regra é simples. Se o gráfico é apresentação, escreva o SVG. Se o gráfico é um instrumento que o utilizador opera, aceite a dependência e agradeça a quem a mantém.
A melhor biblioteca de gráficos para quatro gráficos pequenos acabou por ser um ciclo for.