Skip to content
Extensões

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.

components/funnel-chart.cssAbrir no Figma

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.
Use o Funnel Chart para processos com 3 a 8 estagios onde cada estagio tem um valor menor ou igual ao anterior. Para fluxos ramificados, prefira o Sankey Diagram.

Exemplos

Veja abaixo os exemplos interativos do grafico de funil, incluindo orientacao vertical, horizontal, metricas laterais e dark mode.

Carregando exemplo...

Anatomia

Estrutura interna do componente e seus elementos.

ParteElementoDescricao
Container.funnel-chartWrapper principal com position relative e width 100%
Titulo.funnel-chart__titleHeading centralizado, Space Grotesk 18px w600
Content.funnel-chart__contentFlex container para SVG e metricas laterais
SVG Wrapper.funnel-chart__svg-wrapperWrapper responsivo com overflow hidden
SVG.funnel-chart__svgSVG com viewBox dinamico e preserveAspectRatio
Estagio.funnel-chart__stageTrapezoid SVG com fill colorido e hover
Label.funnel-chart__stage-labelNome do estagio, Inter 13px w500
Valor.funnel-chart__stage-valueNumero do estagio, Space Grotesk 14px w700
Percentual.funnel-chart__stage-percentPercentual em relacao ao total, 12px
Conversao.funnel-chart__conversionIndicador entre estagios com seta e percentual
Metricas.funnel-chart__metricsPainel lateral com resumo por estagio
Tooltip.funnel-chart__tooltipTooltip absoluto com detalhes do estagio
Legenda.funnel-chart__legendFlex row centralizada com gap 16px
Vazio.funnel-chart__emptyEstado 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 ── bottomRight

A formula para calcular a largura de cada estagio:

js
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:

js
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%)
FaixaCor do indicadorSignificado
>= 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.

OrientacaoOpcaoDescricao
Verticalorientation: 'vertical'Estagios empilhados de cima para baixo (padrao). Largura diminui verticalmente.
Horizontalorientation: '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.

PropriedadeTipoDefaultDescrição
.funnel-chartclasseContainer principal do grafico de funil.
.funnel-chart__titleclasseTitulo do grafico (18px w600, font-heading).
.funnel-chart__contentclasseWrapper flex do SVG e metricas laterais.
.funnel-chart__svg-wrapperclasseWrapper responsivo do SVG com overflow hidden.
.funnel-chart__svgclasseSVG principal com viewBox dinamico (width 100%, height auto).
.funnel-chart__stageclasseTrapezoid SVG de cada estagio com fill colorido.
.funnel-chart__stage--animatedclasseModificador com animacao de entrada (scale-y de 0 a 1).
.funnel-chart__stage-labelclasseTexto do nome do estagio, centralizado no trapezoid (13px w500).
.funnel-chart__stage-valueclasseValor numerico do estagio, abaixo do label (14px w700).
.funnel-chart__stage-percentclassePercentual do estagio em relacao ao total (12px).
.funnel-chart__conversionclasseIndicador de conversao entre estagios adjacentes.
.funnel-chart__conversion-arrowclasseSeta SVG entre estagios com percentual de conversao.
.funnel-chart__metricsclassePainel lateral com metricas resumidas por estagio.
.funnel-chart__metricclasseItem individual de metrica no painel lateral.
.funnel-chart__metric-labelclasseLabel da metrica lateral (12px, texto secundario).
.funnel-chart__metric-valueclasseValor da metrica lateral (16px w700).
.funnel-chart__tooltipclasseTooltip absoluto exibido no hover do estagio.
.funnel-chart__tooltip--visibleclasseModificador que torna o tooltip visivel (opacity 1, pointer-events auto).
.funnel-chart__legendclasseLegenda horizontal abaixo do SVG com flex-wrap.
.funnel-chart__legend-itemclasseItem da legenda (dot colorido + texto 13px).
.funnel-chart__legend-dotclasseCirculo colorido 12x12 na legenda.
.funnel-chart__emptyclasseEstado vazio com borda tracejada e texto centralizado.

Codigo

Snippets prontos para copiar e usar no seu projeto.

HTML estatico (SVG)

html
<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

html
<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

html
<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

html
<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.

csv
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;#F59E0B

Mapeamento de campos

CampoChave no mappingPadraoDescricao
Estagiostage'estagio'Nome do estagio exibido no trapezoid
Valorvalue'valor'Valor numerico que define a largura do estagio
Percentualpercent'percentual'Percentual em relacao ao primeiro estagio
Conversaoconversion'conversao'Taxa de conversao em relacao ao estagio anterior
Corcolor'cor'Cor hexadecimal do fill do trapezoid

Opcoes de display

OpcaoTipoPadraoDescricao
titlestringTitulo exibido acima do grafico
legendbooleantrueExibe a legenda abaixo do SVG
tooltipbooleantrueHabilita tooltip no hover dos estagios
showMetricsbooleanfalseExibe painel de metricas laterais
orientationstring'vertical'Orientacao do funil: 'vertical' ou 'horizontal'
animatedbooleantrueHabilita animacao de entrada nos estagios
emptyTextstring'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.

PropriedadeLightDark
Stage fill-opacity0.80.65
Stage hover opacity0.90.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 shadowrgba(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.

Design System interno do GALES