Como fazer desenhos com retangulos usando coordenadas SVG
Vou direto ao ponto. A semana passada passei três horas debugando um arquivo SVG que parecia simples — um gráfico de barras feito com retangulos. O problema não era a sintaxe, era o sistema de coordenadas. Cada retângulo tinha o atributo x e y configurados de formas diferentes, alguns partindo do canto superior esquerdo, outros invertendo o eixo Y por causa de um transform que eu não tinha colocado. Resultado: barras aparecendo em lugares errados ou com altura negativa. O que aprendi é que para desenhos com retangulos funcionarem direito, você precisa dominar três coisas: a origem do canvas, a direção dos eixos e a diferença entre width/height e rx/ry quando quer cantos arredondados. Vou explicar como funciona na prática.
Desenhos com retangulos: estrutura básica
O elemento SVG <rect> tem cinco atributos essenciais. x e y definem o ponto de origem no canto superior esquerdo do retângulo. width e height são as dimensões. Se você omitir algum desses quatro, o retângulo some da tela ou vira uma linha — sim, isso já me aconteceu. Aqui está um exemplo mínimo que funciona:
<svg width="400" height="300" viewBox="0 0 400 300">
<rect x="50" y="50" width="200" height="150" fill="#336699" />
</svg>
Isso desenha um retângulo azul-escuro começando 50 pixels da borda esquerda e 50 pixels do topo. Simples. Mas a complexidade aparece quando você começa a criar grids, gráficos ou layouts com múltiplos retangulos.
O problema prático que ninguém conta
Quando você trabalha com muitos retangulos num mesmo SVG, a manutenção vira um pesadelo se não usar variáveis ou cálculos. Eu descobri isso na prática montando um dashboard com 48 barras verticais. Cada barra era um <rect> manual. Qualquer mudança no espaçamento exigia editar 48 linhas. A solução foi usar um pré-processador simples em Python que gera o SVG a partir de um arquivo CSV com as dimensões. O script que eu uso calcula automaticamente o x de cada retângulo baseado no índice, deixa o y fixo e ajusta o height conforme o valor no dado. Isso corta o tempo de produção de um gráfico simples de duas horas para quinze minutos, dependendo da configuração.
import csv
def generate_barchart(csv_path, svg_width=800, bar_spacing=10):
with open(csv_path) as f:
reader = csv.DictReader(f)
values = [float(row['value']) for row in reader]
max_val = max(values) if values else 1
chart_height = svg_width * 0.6
bar_width = (svg_width - (len(values) + 1) * bar_spacing) // len(values)
lines = ['<svg width="{}" height="{}" viewBox="0 0 {} {}" xmlns="http://www.w3.org/2000/svg">'.format(
svg_width, int(chart_height + 100), svg_width, int(chart_height + 100))]
for i, val in enumerate(values):
x = bar_spacing + i * (bar_width + bar_spacing)
y = chart_height - (val / max_val) * chart_height
h = (val / max_val) * chart_height
lines.append(' <rect x="{}" y="{}" width="{}" height="{}" fill="#2E86AB"/>'.format(
x, int(y), bar_width, int(h)))
lines.append('</svg>')
return '\n'.join(lines)
Esse código não é bonito, mas funciona. Ele resolve o problema de coordenadas manualmente e garante que todos os retangulos estejam alinhados corretamente.
Pegadinhas comuns em desenhos com retangulos
Primeiro erro: esquecer que o y cresce para baixo no SVG. Em matemática tradicional, o eixo Y sobe. No SVG, desce. Se você tentar traduzir gráficos cartesianos sem ajustar isso, todos os retangulos aparecem espelhados. A correção é subtrair a posição Y desejada da altura total do canvas. Segundo erro: usar rx e ry sem verificar a compatibilidade. Cantos arredondados funcionam na maioria dos navegadores modernos, mas em SVGs inline dentro de frameworks React, o atributo rx pode ser ignorado se o elemento pai tiver overflow: hidden configurado de forma estranha. Teste sempre no navegador alvo antes de confiar no resultado.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Terceiro erro: não definir viewBox. Sem ele, o SVG tenta se adaptar ao tamanho da tela de forma imprevisível. Retangulos podem ficar esticados ou cortados. Sempre inclua viewBox="0 0 largura altura" junto com width e height explícitos no elemento <svg>.
Alternativas quando retangulos não são suficientes
Se o seu desenho com retangulos está ficando complicado demais — muitos elementos sobrepostos, coordenadas calculadas manualmente — considere usar <path> no lugar. Um path pode descrever retângulos com arcos, linhas e curvas na mesma entidade. Isso reduz o número de nós no SVG e facilita a manutenção. Outra alternativa é usar uma biblioteca como D3.js. Ela abstrai o cálculo de coordenadas e gera o SVG automaticamente. Claro, isso adiciona uma dependência externa e aumenta o tempo de carregamento, mas para projetos grandes vale a pena.
Se você quer algo entre o manual e o pesado, <g> (grupo) com transformações pode ajudar. Agrupe retangulos relacionados e aplique translate, scale ou rotate no grupo inteiro. Isso evita repetir cálculos para cada elemento.
Download do gerador de gráficos em SVG
O script Python completo com tratamento de erros, suporte a cores personalizadas e geração de legenda está disponível para download. Basta baixar o arquivo svg_barchart_generator.py e executar:
python svg_barchart_generator.py dados.csv --output grafico.svg --width 800 --color "#2E86AB"
O arquivo CSV de entrada precisa ter duas colunas: label (texto) e value (número). O gerador cuida do resto, incluindo o alinhamento dos retangulos e a escala automática. Se você estiver usando Windows e não tiver Python instalado, existe uma versão compilada svg_barchart_generator.exe que funciona sem dependências. Basta extrair e executar.
Quando desenhos com retangulos dão errado mesmo seguindo o tutorial
Às vezes o problema não está no código, mas no contexto de renderização. Se o SVG está dentro de um iframe com allow-same-origin desabilitado, alguns navegadores bloqueiam estilos inline. Se está sendo usado em PDFs gerados via wkhtmltoimage, retangulos com fill-opacity podem aparecer sólidos em vez de transparentes. São edge cases que não aparecem em tutoriais genéricos, mas que custaram horas do meu tempo. A lição prática é: teste sempre no ambiente final de uso, não apenas no navegador local. Um SVG que funciona perfeitamente em Chrome pode se comportar diferente em um visualizador PDF ou num framework de dashboard como Grafana ou Metabase.
<!-- Exemplo de retangulos com transparência que funciona no navegador mas pode falhar em PDFs -->
<rect x="10" y="10" width="100" height="50" fill="#FF6B6B" fill-opacity="0.5" />
<rect x="50" y="30" width="100" height="50" fill="#4ECDC4" fill-opacity="0.5" />
Esses dois retângulos se sobrepõem criando uma cor diferente na interseção. No navegador isso funciona. No PDF, cada um pode aparecer com opacidade total, destruindo o efeito visual esperado.