Skip to content
Extensões

Sankey Diagram

Diagrama de fluxo SVG com paths proporcionais conectando fontes a destinos. Ideal para visualizar distribuicao de recursos, orcamentos e fluxos entre categorias.

components/sankey-diagram.cssAbrir no Figma

Uso

Quando e como utilizar o diagrama Sankey para representar fluxos proporcionais entre origens e destinos.

  • JSON — Carrega dados de um endpoint JSON via DataLoader com mapeamento de campos source/target/value.
  • Inline — Dados passados diretamente via JavaScript como array de objetos, sem fetch externo.
  • HTML estatico — SVG escrito manualmente com paths e retangulos usando classes CSS, sem JavaScript.
Use o Sankey Diagram para fluxos com ate 3 niveis de profundidade. Para fluxos lineares simples, prefira o componente Stepper ou Journey Map.

Exemplos

Veja abaixo os exemplos interativos do diagrama Sankey, incluindo variantes de dados, tooltips e dark mode.

Carregando exemplo...

Anatomia

Estrutura interna do componente e seus elementos.

ParteElementoDescricao
Container.sankey-diagramWrapper principal com position relative e width 100%
Titulo.sankey-diagram__titleHeading centralizado, Space Grotesk 18px w600
SVG Wrapper.sankey-diagram__svg-wrapperWrapper responsivo com overflow hidden
SVG.sankey-diagram__svgSVG com viewBox dinamico e preserveAspectRatio
Node Rect.sankey-diagram__node-rectRetangulo do no com fill colorido e border-radius
Node Label.sankey-diagram__node-labelTexto do nome do no, Inter 13px w500
Node Value.sankey-diagram__node-valueValor numerico, Space Grotesk 12px w700
Link.sankey-diagram__linkPath Bezier cubico com fill-opacity 0.3 e hover 0.5
Tooltip.sankey-diagram__tooltipTooltip absoluto com source, target e valor
Legenda.sankey-diagram__legendFlex row centralizada com gap 16px e flex-wrap
Legend Item.sankey-diagram__legend-itemDot colorido + texto 13px
Vazio.sankey-diagram__emptyEstado sem dados, borda dashed e padding 48px

SVG Internals

Como as curvas Bezier, o layout dos nos e a renderizacao multi-coluna funcionam internamente.

Curvas Bezier

Os links entre nos sao desenhados como paths SVG com curvas Bezier cubicas (C). O ponto de controle horizontal e posicionado a 50% da distancia entre o no de origem e o no de destino, criando uma curva suave e proporcional.

M x0,y0 C cx0,y0 cx1,y1 x1,y1

Onde cx0 = x0 + (x1 - x0) * 0.5 e cx1 = x1 - (x1 - x0) * 0.5. A espessura do path e proporcional ao valor do fluxo.

Layout dos nos

Os nos sao distribuidos automaticamente em colunas verticais. A altura de cada retangulo e proporcional a soma dos valores de entrada e saida do no. Os nos dentro de cada coluna sao empilhados verticalmente com um gap configuravel (padrao 8px).

Multi-coluna

O diagrama suporta ate 3 niveis de profundidade (colunas), posicionados automaticamente no eixo X do viewBox:

ColunaPosicao XConteudo
0Extremo esquerdoNos de origem (sources)
1CentroNos intermediarios
2Extremo direitoNos de destino (targets)

A largura de cada coluna de nos e fixa (padrao 24px). O espaco entre colunas e calculado como (viewBoxWidth - 3 * nodeWidth) / 2.

Layout de Nos

Como os nos sao classificados e posicionados em colunas automaticamente.

O algoritmo de posicionamento classifica cada no com base nas conexoes do dataset:

TipoColunaRegra
Source0No que aparece apenas como source nos dados
Intermediary1No que aparece como target de um fluxo e source de outro
Target2No que aparece apenas como target nos dados

A classificacao e automatica — basta que os dados contenham registros onde o mesmo nome aparece em ambos os campos source e target para criar nos intermediarios.

Exemplo de fluxo multi-nivel:

Orcamento Total → Sanidade Animal → Vacinacao
                                   → Monitoramento
                → Defesa Vegetal  → Controle de Pragas

Neste caso, "Orcamento Total" e coluna 0, "Sanidade Animal" e "Defesa Vegetal" sao coluna 1, e "Vacinacao", "Monitoramento" e "Controle de Pragas" sao coluna 2.

Propriedades

Classes CSS disponiveis para estruturar e estilizar o diagrama Sankey.

PropriedadeTipoDefaultDescrição
.sankey-diagramclasseContainer principal do diagrama de fluxo.
.sankey-diagram__titleclasseTitulo centralizado acima do SVG (18px w600).
.sankey-diagram__svg-wrapperclasseWrapper responsivo com overflow hidden e aspect-ratio.
.sankey-diagram__svgclasseSVG principal com viewBox dinamico (width 100%, height auto).
.sankey-diagram__node-rectclasseRetangulo de cada no com fill colorido e border-radius 4px.
.sankey-diagram__node-labelclasseTexto do nome do no, posicionado ao lado do retangulo (13px w500).
.sankey-diagram__node-valueclasseValor numerico do no, abaixo do label (12px w700).
.sankey-diagram__linkclassePath SVG com curva Bezier conectando fonte ao destino (fill-opacity 0.3).
.sankey-diagram__tooltipclasseTooltip absoluto exibido no hover do link ou no.
.sankey-diagram__tooltip--visibleclasseModificador que torna o tooltip visivel (opacity 1, pointer-events auto).
.sankey-diagram__legendclasseLegenda horizontal abaixo do SVG com flex-wrap.
.sankey-diagram__legend-itemclasseItem da legenda (dot colorido + texto 13px).
.sankey-diagram__legend-dotclasseCirculo colorido 12x12 na legenda.
.sankey-diagram__emptyclasseEstado vazio com borda tracejada e texto centralizado.

Codigo

Snippets prontos para copiar e usar no seu projeto.

HTML estatico (SVG)

html
<div class="sankey-diagram">
  <h3 class="sankey-diagram__title">Distribuicao Orcamentaria</h3>
  <div class="sankey-diagram__svg-wrapper">
    <svg class="sankey-diagram__svg" viewBox="0 0 800 400">
      <!-- Nos coluna 0 (sources) -->
      <rect class="sankey-diagram__node-rect" x="0" y="20" width="24" height="360"
        fill="#3B82F6" rx="4"/>
      <text class="sankey-diagram__node-label" x="32" y="200">Orcamento Total</text>
      <text class="sankey-diagram__node-value" x="32" y="218">R$ 10.000</text>

      <!-- Nos coluna 1 (intermediarios) -->
      <rect class="sankey-diagram__node-rect" x="388" y="20" width="24" height="180"
        fill="#3B82F6" rx="4"/>
      <text class="sankey-diagram__node-label" x="420" y="110">Sanidade Animal</text>

      <rect class="sankey-diagram__node-rect" x="388" y="220" width="24" height="160"
        fill="#10B981" rx="4"/>
      <text class="sankey-diagram__node-label" x="420" y="300">Defesa Vegetal</text>

      <!-- Links (paths Bezier) -->
      <path class="sankey-diagram__link" d="M24,20 C200,20 200,20 388,20
        L388,200 C200,200 200,380 24,380 Z" fill="#3B82F6" fill-opacity="0.3"/>
    </svg>
  </div>
  <div class="sankey-diagram__legend">
    <span class="sankey-diagram__legend-item">
      <span class="sankey-diagram__legend-dot" style="background: #3B82F6"></span>
      Sanidade Animal
    </span>
    <span class="sankey-diagram__legend-item">
      <span class="sankey-diagram__legend-dot" style="background: #10B981"></span>
      Defesa Vegetal
    </span>
  </div>
</div>

DataLoader + Factory

html
<div id="sankey-container"></div>

<script type="module">
  import { DataLoader } from '../core/data-loader.js';
  import { renderSankeyDiagram } from '../components/sankey-diagram.js';

  const data = await DataLoader.load({
    endpoint: '/data/sankey/orcamento-distribuicao.json'
  });

  renderSankeyDiagram(
    document.getElementById('sankey-container'),
    data,
    { source: 'source', target: 'target', value: 'value', color: 'color' },
    { title: 'Distribuicao Orcamentaria — 2025', legend: true, tooltip: true }
  );
</script>

Auto-init via data attributes

html
<div data-arenito="sankey-diagram"
     data-endpoint="/data/sankey/orcamento-distribuicao.json"
     data-format="json"
     data-title="Distribuicao Orcamentaria"
     data-mapping='{"source":"source","target":"target","value":"value","color":"color"}'
     data-legend="true"
     data-tooltip="true">
</div>

Estado vazio

html
<div class="sankey-diagram">
  <h3 class="sankey-diagram__title">Fluxo de Recursos</h3>
  <div class="sankey-diagram__empty">Nenhum dado encontrado para os filtros selecionados.</div>
</div>

Fonte de Dados

O componente espera dados em formato JSON como um array de objetos com campos source, target, value e color.

JSON (formato recomendado)

Cada objeto no array representa um fluxo (link) entre dois nos. O componente constroi os nos automaticamente a partir dos nomes unicos em source e target.

json
[
    { "source": "Orcamento Total", "target": "Sanidade Animal", "value": 4500, "color": "#3B82F6" },
    { "source": "Orcamento Total", "target": "Defesa Vegetal", "value": 3200, "color": "#10B981" },
    { "source": "Orcamento Total", "target": "Inspecao", "value": 2300, "color": "#F59E0B" },
    { "source": "Sanidade Animal", "target": "Vacinacao", "value": 2000, "color": "#3B82F6" },
    { "source": "Sanidade Animal", "target": "Monitoramento", "value": 2500, "color": "#3B82F6" },
    { "source": "Defesa Vegetal", "target": "Controle de Pragas", "value": 1800, "color": "#10B981" },
    { "source": "Defesa Vegetal", "target": "Certificacao", "value": 1400, "color": "#10B981" }
]

Mapeamento de campos

CampoChave no mappingPadraoDescricao
Origemsource'source'Nome do no de origem do fluxo
Destinotarget'target'Nome do no de destino do fluxo
Valorvalue'value'Valor numerico que define a espessura do link
Corcolor'color'Cor hexadecimal do link e dos nos relacionados

Opcoes de display

OpcaoTipoPadraoDescricao
titlestringTitulo exibido acima do diagrama
legendbooleantrueExibe a legenda abaixo do SVG
tooltipbooleantrueHabilita tooltip no hover de links e nos
nodeWidthnumber24Largura dos retangulos dos nos em pixels
nodeGapnumber8Espacamento vertical entre nos na mesma coluna
linkOpacitynumber0.3Opacidade dos paths de link (0 a 1)
emptyTextstring'Nenhum dado encontrado.'Texto do estado vazio

Dark Mode

O diagrama adapta automaticamente ao tema escuro via classe .dark.

No dark mode, os links reduzem a opacidade para evitar que cores vibrantes dominem a interface em fundo escuro. Os nos mantem suas cores mas com leve ajuste de brilho.

PropriedadeLightDark
Link fill-opacity0.30.2
Link hover opacity0.50.4
Node rect opacity1.00.85
Tooltip background--surface-base-neutral-container-default--surface-base-neutral-container-default
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, sem necessidade de ajuste manual nos labels e tooltips.

Design System interno do GALES