2

Sankey Chart

PreviousNext

Flow diagrams showing connections between nodes with proportional link widths.

Organic (600)Paid Ads (600)Social (400)Referral (300)Sign Up (800)Purchase (630)Bounce (470)
"use client"

import { SankeyChart } from "@/components/ui/charts"

// Website traffic flow - Sources to Destinations
const nodes = [
  // Sources (left)
  { id: "organic", name: "Organic", color: "#1e40af" },
  { id: "paid", name: "Paid Ads", color: "#2563eb" },
  { id: "social", name: "Social", color: "#3b82f6" },
  { id: "referral", name: "Referral", color: "#60a5fa" },
  // Destinations (right)
  { id: "signup", name: "Sign Up", color: "#1e40af" },
  { id: "purchase", name: "Purchase", color: "#2563eb" },
  { id: "bounce", name: "Bounce", color: "#93c5fd" },
]

const links = [
  // Organic traffic
  { source: "organic", target: "signup", value: 320 },
  { source: "organic", target: "purchase", value: 180 },
  { source: "organic", target: "bounce", value: 100 },
  // Paid ads
  { source: "paid", target: "signup", value: 200 },
  { source: "paid", target: "purchase", value: 250 },
  { source: "paid", target: "bounce", value: 150 },
  // Social
  { source: "social", target: "signup", value: 180 },
  { source: "social", target: "purchase", value: 80 },
  { source: "social", target: "bounce", value: 140 },
  // Referral
  { source: "referral", target: "signup", value: 100 },
  { source: "referral", target: "purchase", value: 120 },
  { source: "referral", target: "bounce", value: 80 },
]

export function SankeyChartDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <SankeyChart
        nodes={nodes}
        links={links}
        nodeWidth={16}
        nodePadding={16}
        width={600}
        height={340}
        margin={{ top: 20, right: 80, bottom: 20, left: 70 }}
      />
    </div>
  )
}

About

The Sankey Chart displays flows between nodes with proportional link widths. Built with D3-Sankey, it supports:

  • Multi-level flows from sources through intermediaries to destinations
  • Custom node colors with the blue color palette
  • Link highlighting on hover to trace flow paths
  • Interactive tooltips showing node and link values
  • Flexible alignment options (left, right, center, justify)

Installation

pnpm dlx shadcn@latest add https://ui.simplifying.ai/r/sankey-chart.json

Usage

import { SankeyChart } from "@/components/ui/charts"
 
const nodes = [
  { id: "source1", name: "Source 1", color: "#2563eb" },
  { id: "source2", name: "Source 2", color: "#3b82f6" },
  { id: "target1", name: "Target 1", color: "#60a5fa" },
  { id: "target2", name: "Target 2", color: "#93c5fd" },
]
 
const links = [
  { source: "source1", target: "target1", value: 50 },
  { source: "source1", target: "target2", value: 30 },
  { source: "source2", target: "target1", value: 40 },
  { source: "source2", target: "target2", value: 20 },
]
 
export function MyChart() {
  return <SankeyChart nodes={nodes} links={links} />
}

Examples

Default

A user journey flow showing traffic sources through landing pages to conversion. Hover over nodes to highlight connected flows.

Organic (600)Paid Ads (600)Social (400)Referral (300)Sign Up (800)Purchase (630)Bounce (470)
"use client"

import { SankeyChart } from "@/components/ui/charts"

// Website traffic flow - Sources to Destinations
const nodes = [
  // Sources (left)
  { id: "organic", name: "Organic", color: "#1e40af" },
  { id: "paid", name: "Paid Ads", color: "#2563eb" },
  { id: "social", name: "Social", color: "#3b82f6" },
  { id: "referral", name: "Referral", color: "#60a5fa" },
  // Destinations (right)
  { id: "signup", name: "Sign Up", color: "#1e40af" },
  { id: "purchase", name: "Purchase", color: "#2563eb" },
  { id: "bounce", name: "Bounce", color: "#93c5fd" },
]

const links = [
  // Organic traffic
  { source: "organic", target: "signup", value: 320 },
  { source: "organic", target: "purchase", value: 180 },
  { source: "organic", target: "bounce", value: 100 },
  // Paid ads
  { source: "paid", target: "signup", value: 200 },
  { source: "paid", target: "purchase", value: 250 },
  { source: "paid", target: "bounce", value: 150 },
  // Social
  { source: "social", target: "signup", value: 180 },
  { source: "social", target: "purchase", value: 80 },
  { source: "social", target: "bounce", value: 140 },
  // Referral
  { source: "referral", target: "signup", value: 100 },
  { source: "referral", target: "purchase", value: 120 },
  { source: "referral", target: "bounce", value: 80 },
]

export function SankeyChartDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <SankeyChart
        nodes={nodes}
        links={links}
        nodeWidth={16}
        nodePadding={16}
        width={600}
        height={340}
        margin={{ top: 20, right: 80, bottom: 20, left: 70 }}
      />
    </div>
  )
}

Energy Flow

Visualize energy distribution from multiple sources (coal, gas, nuclear, renewables) through electricity generation to consumption sectors.

Coal (350)Natural Gas (280)Nuclear (200)Hydro (120)Solar (80)Wind (70)Electricity (1,100)Residential (320)Commercial (280)Industrial (350)Transport (150)
"use client"

import { SankeyChart } from "@/components/ui/charts"

// Energy flow from sources to sectors
const nodes = [
  { id: "coal", name: "Coal", color: "#1e40af" },
  { id: "gas", name: "Natural Gas", color: "#2563eb" },
  { id: "nuclear", name: "Nuclear", color: "#3b82f6" },
  { id: "hydro", name: "Hydro", color: "#60a5fa" },
  { id: "solar", name: "Solar", color: "#93c5fd" },
  { id: "wind", name: "Wind", color: "#bfdbfe" },
  { id: "electricity", name: "Electricity", color: "#2563eb" },
  { id: "residential", name: "Residential", color: "#1e40af" },
  { id: "commercial", name: "Commercial", color: "#3b82f6" },
  { id: "industrial", name: "Industrial", color: "#60a5fa" },
  { id: "transport", name: "Transport", color: "#93c5fd" },
]

const links = [
  { source: "coal", target: "electricity", value: 350 },
  { source: "gas", target: "electricity", value: 280 },
  { source: "nuclear", target: "electricity", value: 200 },
  { source: "hydro", target: "electricity", value: 120 },
  { source: "solar", target: "electricity", value: 80 },
  { source: "wind", target: "electricity", value: 70 },
  { source: "electricity", target: "residential", value: 320 },
  { source: "electricity", target: "commercial", value: 280 },
  { source: "electricity", target: "industrial", value: 350 },
  { source: "electricity", target: "transport", value: 150 },
]

export function SankeyChartEnergyDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <SankeyChart
        nodes={nodes}
        links={links}
        nodeWidth={16}
        nodePadding={14}
        width={600}
        height={340}
        margin={{ top: 20, right: 90, bottom: 20, left: 90 }}
      />
    </div>
  )
}
const nodes = [
  { id: "coal", name: "Coal", color: "#1e40af" },
  { id: "gas", name: "Natural Gas", color: "#2563eb" },
  { id: "electricity", name: "Electricity", color: "#3b82f6" },
  { id: "residential", name: "Residential", color: "#60a5fa" },
  // ...
]
 
const links = [
  { source: "coal", target: "electricity", value: 350 },
  { source: "electricity", target: "residential", value: 320 },
  // ...
]
 
<SankeyChart nodes={nodes} links={links} nodeWidth={24} nodePadding={20} />

Budget Allocation (Gradient)

Show budget flow with custom link colors to differentiate flow types. Links can have their own colors independent of nodes.

Total Revenue (1,000)Operating Expenses (450)Capital Expenses (200)Net Profit (350)Salaries (250)Marketing (120)R&D (80)Equipment (120)Facilities (80)Dividends (150)Reinvestment (200)
"use client"

import { SankeyChart } from "@/components/ui/charts"

// Budget allocation with gradient links
const nodes = [
  { id: "revenue", name: "Total Revenue", color: "#1e40af" },
  { id: "opex", name: "Operating Expenses", color: "#2563eb" },
  { id: "capex", name: "Capital Expenses", color: "#3b82f6" },
  { id: "profit", name: "Net Profit", color: "#60a5fa" },
  { id: "salaries", name: "Salaries", color: "#93c5fd" },
  { id: "marketing", name: "Marketing", color: "#bfdbfe" },
  { id: "rd", name: "R&D", color: "#1e40af" },
  { id: "equipment", name: "Equipment", color: "#2563eb" },
  { id: "facilities", name: "Facilities", color: "#3b82f6" },
  { id: "dividends", name: "Dividends", color: "#60a5fa" },
  { id: "reinvest", name: "Reinvestment", color: "#93c5fd" },
]

const links = [
  { source: "revenue", target: "opex", value: 450, color: "#3b82f6" },
  { source: "revenue", target: "capex", value: 200, color: "#60a5fa" },
  { source: "revenue", target: "profit", value: 350, color: "#93c5fd" },
  { source: "opex", target: "salaries", value: 250, color: "#2563eb" },
  { source: "opex", target: "marketing", value: 120, color: "#3b82f6" },
  { source: "opex", target: "rd", value: 80, color: "#60a5fa" },
  { source: "capex", target: "equipment", value: 120, color: "#3b82f6" },
  { source: "capex", target: "facilities", value: 80, color: "#60a5fa" },
  { source: "profit", target: "dividends", value: 150, color: "#93c5fd" },
  { source: "profit", target: "reinvest", value: 200, color: "#bfdbfe" },
]

export function SankeyChartGradientDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <SankeyChart
        nodes={nodes}
        links={links}
        nodeWidth={14}
        nodePadding={14}
        width={600}
        height={360}
        linkOpacity={0.6}
        margin={{ top: 20, right: 90, bottom: 20, left: 100 }}
      />
    </div>
  )
}
const links = [
  { source: "revenue", target: "opex", value: 450, color: "#3b82f6" },
  { source: "revenue", target: "capex", value: 200, color: "#60a5fa" },
  { source: "revenue", target: "profit", value: 350, color: "#93c5fd" },
  // ...
]
 
<SankeyChart nodes={nodes} links={links} linkOpacity={0.6} />

Minimal

A simple two-level flow for basic source-to-destination visualization. Perfect for conversion funnels or simple categorization.

DesktopMobileTabletConversionsBounced
"use client"

import { SankeyChart } from "@/components/ui/charts"

// Simple two-level flow
const nodes = [
  { id: "source1", name: "Desktop", color: "#2563eb" },
  { id: "source2", name: "Mobile", color: "#3b82f6" },
  { id: "source3", name: "Tablet", color: "#60a5fa" },
  { id: "target1", name: "Conversions", color: "#1e40af" },
  { id: "target2", name: "Bounced", color: "#93c5fd" },
]

const links = [
  { source: "source1", target: "target1", value: 420 },
  { source: "source1", target: "target2", value: 180 },
  { source: "source2", target: "target1", value: 280 },
  { source: "source2", target: "target2", value: 320 },
  { source: "source3", target: "target1", value: 90 },
  { source: "source3", target: "target2", value: 110 },
]

export function SankeyChartMinimalDemo() {
  return (
    <div className="mx-auto w-full max-w-md">
      <SankeyChart
        nodes={nodes}
        links={links}
        nodeWidth={16}
        nodePadding={20}
        width={400}
        height={240}
        showValues={false}
        margin={{ top: 16, right: 80, bottom: 16, left: 70 }}
      />
    </div>
  )
}
<SankeyChart
  nodes={nodes}
  links={links}
  nodeWidth={20}
  nodePadding={25}
  showValues={false}
/>

Multi-level Journey

Complex user journey tracking across four levels: traffic sources, entry pages, user actions, and final outcomes.

Google (500)Facebook (300)Twitter (150)Direct (400)Homepage (780)Blog (220)Products (350)Browse (600)Search (280)Add to Cart (730)Purchase (450)Abandon (680)Subscribe (120)
"use client"

import { SankeyChart } from "@/components/ui/charts"

// Complex multi-level user journey
const nodes = [
  // Level 1 - Traffic Sources
  { id: "google", name: "Google", color: "#1e40af" },
  { id: "facebook", name: "Facebook", color: "#2563eb" },
  { id: "twitter", name: "Twitter", color: "#3b82f6" },
  { id: "direct", name: "Direct", color: "#60a5fa" },
  // Level 2 - Entry Pages
  { id: "home", name: "Homepage", color: "#93c5fd" },
  { id: "blog", name: "Blog", color: "#bfdbfe" },
  { id: "product", name: "Products", color: "#1e40af" },
  // Level 3 - Actions
  { id: "browse", name: "Browse", color: "#2563eb" },
  { id: "search", name: "Search", color: "#3b82f6" },
  { id: "add_cart", name: "Add to Cart", color: "#60a5fa" },
  // Level 4 - Outcomes
  { id: "purchase", name: "Purchase", color: "#1e40af" },
  { id: "abandon", name: "Abandon", color: "#93c5fd" },
  { id: "subscribe", name: "Subscribe", color: "#2563eb" },
]

const links = [
  // Traffic to Entry
  { source: "google", target: "home", value: 300 },
  { source: "google", target: "product", value: 200 },
  { source: "facebook", target: "home", value: 180 },
  { source: "facebook", target: "blog", value: 120 },
  { source: "twitter", target: "blog", value: 100 },
  { source: "twitter", target: "home", value: 50 },
  { source: "direct", target: "home", value: 250 },
  { source: "direct", target: "product", value: 150 },
  // Entry to Actions
  { source: "home", target: "browse", value: 400 },
  { source: "home", target: "search", value: 280 },
  { source: "blog", target: "subscribe", value: 120 },
  { source: "blog", target: "browse", value: 100 },
  { source: "product", target: "add_cart", value: 250 },
  { source: "product", target: "browse", value: 100 },
  // Actions to Outcomes
  { source: "browse", target: "add_cart", value: 300 },
  { source: "browse", target: "abandon", value: 300 },
  { source: "search", target: "add_cart", value: 180 },
  { source: "search", target: "abandon", value: 100 },
  { source: "add_cart", target: "purchase", value: 450 },
  { source: "add_cart", target: "abandon", value: 280 },
]

export function SankeyChartMultilevelDemo() {
  return (
    <div className="mx-auto w-full max-w-2xl">
      <SankeyChart
        nodes={nodes}
        links={links}
        nodeWidth={12}
        nodePadding={10}
        width={600}
        height={380}
        linkOpacity={0.45}
        margin={{ top: 20, right: 80, bottom: 20, left: 80 }}
      />
    </div>
  )
}
<SankeyChart
  nodes={nodes}
  links={links}
  nodeWidth={16}
  nodePadding={14}
  linkOpacity={0.45}
  width={1000}
  height={500}
/>

API Reference

PropTypeDefaultDescription
nodesSankeyNode[]requiredArray of node definitions
linksSankeyLink[]requiredArray of link connections
widthnumber800Chart width in pixels
heightnumber500Chart height in pixels
marginobject{ top: 20, right: 120, bottom: 20, left: 20 }Chart margins
nodeWidthnumber15Width of node rectangles
nodePaddingnumber20Vertical spacing between nodes
nodeAlign"left" | "right" | "center" | "justify""justify"Node alignment algorithm
linkOpacitynumber0.5Opacity of link paths
showLabelsbooleantrueShow node labels
showValuesbooleantrueShow values in labels
showTooltipbooleantrueEnable hover tooltips

Data Types

interface SankeyNode {
  id: string // Unique identifier for the node
  name?: string // Display name (defaults to id)
  color?: string // Node color (hex, e.g., "#2563eb")
}
 
interface SankeyLink {
  source: string // Source node id
  target: string // Target node id
  value: number // Flow value (determines link width)
  color?: string // Optional link color override
}

Customization

Node Alignment

Control how nodes are positioned horizontally:

// Left-aligned: sources on left edge
<SankeyChart nodes={nodes} links={links} nodeAlign="left" />
 
// Right-aligned: sinks on right edge
<SankeyChart nodes={nodes} links={links} nodeAlign="right" />
 
// Center-aligned: balanced distribution
<SankeyChart nodes={nodes} links={links} nodeAlign="center" />
 
// Justified (default): spread across full width
<SankeyChart nodes={nodes} links={links} nodeAlign="justify" />

Custom Colors

Set colors directly on nodes and links for full control:

const nodes = [
  { id: "a", name: "Node A", color: "#1e40af" },
  { id: "b", name: "Node B", color: "#2563eb" },
  { id: "c", name: "Node C", color: "#3b82f6" },
]
 
const links = [
  { source: "a", target: "c", value: 100, color: "#60a5fa" },
  { source: "b", target: "c", value: 50, color: "#93c5fd" },
]

Adjusting Density

Control spacing between nodes for different data densities:

// Sparse layout (few nodes)
<SankeyChart nodes={nodes} links={links} nodePadding={30} nodeWidth={24} />
 
// Dense layout (many nodes)
<SankeyChart nodes={nodes} links={links} nodePadding={8} nodeWidth={12} />

Accessibility

  • Nodes and links are interactive with clear hover states
  • Tooltips provide detailed flow information
  • Color palette maintains sufficient contrast
  • Labels positioned for readability without overlap

Notes

  • Sankey charts are ideal for visualizing flows, conversions, and resource distribution.
  • All link values should be positive numbers representing flow quantities.
  • The chart automatically calculates node heights based on incoming and outgoing flows.
  • For best results, organize your data in a logical left-to-right flow structure.
  • Avoid creating circular flows (e.g., A→B→A) as the layout algorithm doesn't support cycles.
  • Use consistent color schemes to help users trace flows through the diagram.
  • For complex multi-level flows, consider increasing chart width and adjusting nodePadding for clarity.