Funnel Chart
Grafico de funil SVG com estagios de largura decrescente e metricas por estagio. Ideal para visualizar pipelines de conversao, processos de filtragem e fluxos com perda progressiva.
Uso
Quando e como utilizar o grafico de funil para representar estagios de conversao com perda progressiva.
- CSV — Carrega dados de um arquivo CSV via DataLoader com campos estagio, valor, percentual, conversao e cor.
- Inline — Dados passados diretamente via JavaScript como array de objetos, sem fetch externo.
- HTML estatico — SVG escrito manualmente com trapezoides e classes CSS, sem JavaScript.
Exemplos
Veja abaixo os exemplos interativos do grafico de funil, incluindo orientacao vertical, horizontal, metricas laterais e dark mode.
Anatomia
Estrutura interna do componente e seus elementos.
| Parte | Elemento | Descricao |
|---|---|---|
| Container | .funnel-chart | Wrapper principal com position relative e width 100% |
| Titulo | .funnel-chart__title | Heading centralizado, Space Grotesk 18px w600 |
| Content | .funnel-chart__content | Flex container para SVG e metricas laterais |
| SVG Wrapper | .funnel-chart__svg-wrapper | Wrapper responsivo com overflow hidden |
| SVG | .funnel-chart__svg | SVG com viewBox dinamico e preserveAspectRatio |
| Estagio | .funnel-chart__stage | Trapezoid SVG com fill colorido e hover |
| Label | .funnel-chart__stage-label | Nome do estagio, Inter 13px w500 |
| Valor | .funnel-chart__stage-value | Numero do estagio, Space Grotesk 14px w700 |
| Percentual | .funnel-chart__stage-percent | Percentual em relacao ao total, 12px |
| Conversao | .funnel-chart__conversion | Indicador entre estagios com seta e percentual |
| Metricas | .funnel-chart__metrics | Painel lateral com resumo por estagio |
| Tooltip | .funnel-chart__tooltip | Tooltip absoluto com detalhes do estagio |
| Legenda | .funnel-chart__legend | Flex row centralizada com gap 16px |
| Vazio | .funnel-chart__empty | Estado sem dados, borda dashed e padding 48px |
Trapezoides SVG
Cada estagio do funil e renderizado como um trapezoid SVG cuja largura e proporcional ao valor.
Os estagios sao desenhados como polygons SVG com 4 pontos que formam um trapezoid. A largura do topo de cada estagio e proporcional ao seu valor, e a largura da base e igual a largura do topo do estagio seguinte.
topLeft ────────────── topRight
\ /
\ /
\ /
bottomLeft ── bottomRightA formula para calcular a largura de cada estagio:
const stageWidth = (value / maxValue) * viewBoxWidth;Onde maxValue e o valor do primeiro estagio (topo do funil). Cada trapezoid e centralizado horizontalmente no viewBox, criando o efeito de afunilamento simetrico.
O hover em cada estagio aplica fill-opacity: 0.85 e um leve filter: brightness(1.05) para feedback visual.
Taxa de Conversao
A taxa de conversao entre estagios adjacentes e calculada automaticamente.
A conversao entre dois estagios consecutivos e calculada pela formula:
const conversion = (currentValue / previousValue) * 100;Cada indicador de conversao (.funnel-chart__conversion) e posicionado entre dois estagios e exibe:
- Uma seta SVG apontando para baixo (ou para a direita no modo horizontal)
- O percentual de conversao formatado com uma casa decimal (ex:
78.5%)
| Faixa | Cor do indicador | Significado |
|---|---|---|
| >= 80% | #10B981 (verde) | Alta conversao |
| 50% - 79% | #F59E0B (amarelo) | Conversao moderada |
| < 50% | #EF4444 (vermelho) | Baixa conversao |
Metricas Laterais
O painel de metricas laterais exibe valores complementares por estagio quando showMetrics esta habilitado.
Quando showMetrics: true e passado nas opcoes de display, o componente renderiza um painel lateral (.funnel-chart__metrics) ao lado do SVG com:
- Label do estagio (
.funnel-chart__metric-label) - Valor formatado com separador de milhares (
.funnel-chart__metric-value) - Percentual em relacao ao primeiro estagio
O layout usa display: flex com o SVG ocupando flex: 1 e o painel de metricas com width: 200px. Em telas menores que 640px, o painel move-se para baixo do SVG.
Orientacao
O funil suporta orientacao vertical (padrao) e horizontal.
| Orientacao | Opcao | Descricao |
|---|---|---|
| Vertical | orientation: 'vertical' | Estagios empilhados de cima para baixo (padrao). Largura diminui verticalmente. |
| Horizontal | orientation: 'horizontal' | Estagios lado a lado da esquerda para direita. Altura diminui horizontalmente. |
No modo horizontal, os trapezoides sao rotacionados 90 graus — a altura de cada estagio e proporcional ao valor, e as setas de conversao apontam para a direita. O painel de metricas posiciona-se abaixo do SVG neste modo.
Propriedades
Classes CSS disponiveis para configurar o grafico de funil.
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
.funnel-chart | classe | — | Container principal do grafico de funil. |
.funnel-chart__title | classe | — | Titulo do grafico (18px w600, font-heading). |
.funnel-chart__content | classe | — | Wrapper flex do SVG e metricas laterais. |
.funnel-chart__svg-wrapper | classe | — | Wrapper responsivo do SVG com overflow hidden. |
.funnel-chart__svg | classe | — | SVG principal com viewBox dinamico (width 100%, height auto). |
.funnel-chart__stage | classe | — | Trapezoid SVG de cada estagio com fill colorido. |
.funnel-chart__stage--animated | classe | — | Modificador com animacao de entrada (scale-y de 0 a 1). |
.funnel-chart__stage-label | classe | — | Texto do nome do estagio, centralizado no trapezoid (13px w500). |
.funnel-chart__stage-value | classe | — | Valor numerico do estagio, abaixo do label (14px w700). |
.funnel-chart__stage-percent | classe | — | Percentual do estagio em relacao ao total (12px). |
.funnel-chart__conversion | classe | — | Indicador de conversao entre estagios adjacentes. |
.funnel-chart__conversion-arrow | classe | — | Seta SVG entre estagios com percentual de conversao. |
.funnel-chart__metrics | classe | — | Painel lateral com metricas resumidas por estagio. |
.funnel-chart__metric | classe | — | Item individual de metrica no painel lateral. |
.funnel-chart__metric-label | classe | — | Label da metrica lateral (12px, texto secundario). |
.funnel-chart__metric-value | classe | — | Valor da metrica lateral (16px w700). |
.funnel-chart__tooltip | classe | — | Tooltip absoluto exibido no hover do estagio. |
.funnel-chart__tooltip--visible | classe | — | Modificador que torna o tooltip visivel (opacity 1, pointer-events auto). |
.funnel-chart__legend | classe | — | Legenda horizontal abaixo do SVG com flex-wrap. |
.funnel-chart__legend-item | classe | — | Item da legenda (dot colorido + texto 13px). |
.funnel-chart__legend-dot | classe | — | Circulo colorido 12x12 na legenda. |
.funnel-chart__empty | classe | — | Estado vazio com borda tracejada e texto centralizado. |
Codigo
Snippets prontos para copiar e usar no seu projeto.
HTML estatico (SVG)
<div class="funnel-chart">
<h3 class="funnel-chart__title">Pipeline de Fiscalizacao</h3>
<div class="funnel-chart__content">
<div class="funnel-chart__svg-wrapper">
<svg class="funnel-chart__svg" viewBox="0 0 600 400">
<!-- Estagio 1: Propriedades Cadastradas -->
<polygon class="funnel-chart__stage" points="50,10 550,10 500,100 100,100"
fill="#3B82F6" fill-opacity="0.8"/>
<text class="funnel-chart__stage-label" x="300" y="45" text-anchor="middle">Propriedades Cadastradas</text>
<text class="funnel-chart__stage-value" x="300" y="70" text-anchor="middle">12.450</text>
<text class="funnel-chart__stage-percent" x="300" y="88" text-anchor="middle">100%</text>
<!-- Estagio 2: Vistoriadas -->
<polygon class="funnel-chart__stage" points="100,110 500,110 440,200 160,200"
fill="#8B5CF6" fill-opacity="0.8"/>
<text class="funnel-chart__stage-label" x="300" y="145" text-anchor="middle">Vistoriadas</text>
<text class="funnel-chart__stage-value" x="300" y="170" text-anchor="middle">8.920</text>
<text class="funnel-chart__stage-percent" x="300" y="188" text-anchor="middle">71.6%</text>
<!-- Estagio 3: Conformes -->
<polygon class="funnel-chart__stage" points="160,210 440,210 380,300 220,300"
fill="#10B981" fill-opacity="0.8"/>
<text class="funnel-chart__stage-label" x="300" y="245" text-anchor="middle">Conformes</text>
<text class="funnel-chart__stage-value" x="300" y="270" text-anchor="middle">6.340</text>
<text class="funnel-chart__stage-percent" x="300" y="288" text-anchor="middle">50.9%</text>
<!-- Estagio 4: Certificadas -->
<polygon class="funnel-chart__stage" points="220,310 380,310 350,390 250,390"
fill="#F59E0B" fill-opacity="0.8"/>
<text class="funnel-chart__stage-label" x="300" y="340" text-anchor="middle">Certificadas</text>
<text class="funnel-chart__stage-value" x="300" y="365" text-anchor="middle">3.180</text>
<text class="funnel-chart__stage-percent" x="300" y="383" text-anchor="middle">25.5%</text>
</svg>
</div>
</div>
<div class="funnel-chart__legend">
<span class="funnel-chart__legend-item">
<span class="funnel-chart__legend-dot" style="background: #3B82F6"></span>
Cadastradas
</span>
<span class="funnel-chart__legend-item">
<span class="funnel-chart__legend-dot" style="background: #8B5CF6"></span>
Vistoriadas
</span>
<span class="funnel-chart__legend-item">
<span class="funnel-chart__legend-dot" style="background: #10B981"></span>
Conformes
</span>
<span class="funnel-chart__legend-item">
<span class="funnel-chart__legend-dot" style="background: #F59E0B"></span>
Certificadas
</span>
</div>
</div>DataLoader + Factory
<div id="funnel-container"></div>
<script type="module">
import { DataLoader } from '../core/data-loader.js';
import { renderFunnelChart } from '../components/funnel-chart.js';
const data = await DataLoader.load({
endpoint: '/data/funnel/pipeline-fiscalizacao.csv',
csvOptions: { delimiter: ';' }
});
renderFunnelChart(
document.getElementById('funnel-container'),
data,
{ stage: 'estagio', value: 'valor', percent: 'percentual', conversion: 'conversao', color: 'cor' },
{ title: 'Pipeline de Fiscalizacao — 2025', legend: true, showMetrics: true, orientation: 'vertical' }
);
</script>Auto-init via data attributes
<div data-arenito="funnel-chart"
data-endpoint="/data/funnel/pipeline-fiscalizacao.csv"
data-format="csv"
data-delimiter=";"
data-title="Pipeline de Fiscalizacao"
data-mapping='{"stage":"estagio","value":"valor","percent":"percentual","conversion":"conversao","color":"cor"}'
data-legend="true"
data-show-metrics="true"
data-orientation="vertical">
</div>Estado vazio
<div class="funnel-chart">
<h3 class="funnel-chart__title">Pipeline de Resultados</h3>
<div class="funnel-chart__empty">Nenhum dado encontrado para os filtros selecionados.</div>
</div>Fonte de Dados
O componente aceita dados em CSV com campos separados por ponto-e-virgula, formato padrao brasileiro.
CSV (formato recomendado)
Cada linha do CSV representa um estagio do funil. Os estagios devem estar ordenados do maior para o menor valor.
estagio;valor;percentual;conversao;cor
Propriedades Cadastradas;12450;100;-;#3B82F6
Vistoriadas;8920;71.6;71.6;#8B5CF6
Conformes;6340;50.9;71.1;#10B981
Certificadas;3180;25.5;50.2;#F59E0BMapeamento de campos
| Campo | Chave no mapping | Padrao | Descricao |
|---|---|---|---|
| Estagio | stage | 'estagio' | Nome do estagio exibido no trapezoid |
| Valor | value | 'valor' | Valor numerico que define a largura do estagio |
| Percentual | percent | 'percentual' | Percentual em relacao ao primeiro estagio |
| Conversao | conversion | 'conversao' | Taxa de conversao em relacao ao estagio anterior |
| Cor | color | 'cor' | Cor hexadecimal do fill do trapezoid |
Opcoes de display
| Opcao | Tipo | Padrao | Descricao |
|---|---|---|---|
title | string | — | Titulo exibido acima do grafico |
legend | boolean | true | Exibe a legenda abaixo do SVG |
tooltip | boolean | true | Habilita tooltip no hover dos estagios |
showMetrics | boolean | false | Exibe painel de metricas laterais |
orientation | string | 'vertical' | Orientacao do funil: 'vertical' ou 'horizontal' |
animated | boolean | true | Habilita animacao de entrada nos estagios |
emptyText | string | 'Nenhum dado encontrado.' | Texto do estado vazio |
Dark Mode
O grafico de funil adapta automaticamente ao tema escuro via classe .dark.
No dark mode, os estagios reduzem levemente a opacidade do fill e os indicadores de conversao ajustam seus fundos para manter legibilidade em fundos escuros.
| Propriedade | Light | Dark |
|---|---|---|
| Stage fill-opacity | 0.8 | 0.65 |
| Stage hover opacity | 0.9 | 0.75 |
| Conversion background | --surface-base-neutral-container-default | --surface-base-neutral-container-default |
| Metrics panel background | --surface-base-neutral-container-emphasis | --surface-base-neutral-container-emphasis |
| Tooltip shadow | rgba(0,0,0,0.12) | rgba(0,0,0,0.32) |
| Label color | --text-base-neutral-default | --text-base-neutral-default |
Os tokens semanticos de superficie e texto herdam automaticamente os valores do dark mode. O modificador .funnel-chart__stage--animated mantem a mesma animacao em ambos os temas, ajustando apenas a opacidade final.