TanStack
Mark Reference

Sankey Diagram Mark

sankeyDiagram lays out a directed weighted graph in final plot pixels, then composes ordinary marks over its nodes and links. Source rows stay semantic; the application does not clone D3 records, resolve mutated endpoints, or materialize positioned DTOs.

ts
import { defineChart, link, rect, text } from '@tanstack/charts'
import { sankeyDiagram } from '@tanstack/charts/network/sankey'

const chart = defineChart({
  marks: [
    sankeyDiagram({
      nodes,
      links,
      nodeKey: 'id',
      source: 'source',
      target: 'target',
      value: 'value',
      align: 'left',
      nodeWidth: ({ width }) => Math.max(12, width * 0.025),
      nodePadding: ({ height }) => Math.max(12, height * 0.06),
      inset: 24,
      marks: ({ nodes: layoutNodes, links: layoutLinks }) =>
        [
          link(layoutLinks, {
            x1: 'x1',
            y1: 'y1',
            x2: 'x2',
            y2: 'y2',
            key: 'key',
            strokeWidth: (flow) => Math.max(1, flow.width),
            lineCap: 'butt',
          }),
          rect(layoutNodes, {
            x1: 'x0',
            x2: 'x1',
            y1: 'y0',
            y2: 'y1',
            key: 'key',
            inset: 0,
          }),
          text(layoutNodes, {
            x: 'x',
            y: 'y',
            text: (node) => node.data.label,
            key: 'key',
          }),
        ] as const,
    }),
  ],
  guides: false,
})

The exact @tanstack/charts/network/sankey subpath keeps d3-sankey and the resolved flow adapter out of root, universal, force-layout, and ordinary-mark bundles. The Charts package owns d3-sankey; the application needs no direct dependency unless its own source imports that module.

Graph input

nodes and links accept iterables. nodeKey identifies each node; source and target read those keys from each link; value reads its nonnegative weight.

ts
sankeyDiagram({
  nodes,
  links,
  nodeKey: 'id',
  source: 'from',
  target: 'to',
  value: 'amount',
  marks,
})

Keys must be strings or finite numbers. Graph validation rejects duplicate node keys, missing endpoints, duplicate authored link keys, and negative or nonfinite values. A nonempty graph must contain at least one positive link; zero-valued links may coexist with positive flow. The layout also rejects cycles.

Use linkKey when links can be reordered or when several links share the same endpoints. Without it, a unique raw id field is used when every link has one; otherwise keys use source, target, and parallel-link occurrence.

Input rows are never mutated. Accessors run when the mark is created; repeated responsive layout passes use fresh private graph records.

Options

OptionTypeDefaultMeaning
nodesIterable<TNode>RequiredSemantic node rows
linksIterable<TLink>RequiredSemantic weighted edges
nodeKeyTransformValue<TNode, ChartKey>RequiredNode identity
sourceTransformValue<TLink, ChartKey>RequiredSource-node identity
targetTransformValue<TLink, ChartKey>RequiredTarget-node identity
valueTransformValue<TLink, number>RequiredNonnegative link weight
linkKeyTransformValue<TLink, ChartKey>InferredStable link identity
alignleft | right | center | justifyjustifyHorizontal node-layer alignment
nodeSortSankeyNodeComparator<TNode> | nullD3 orderSame-column ordering; null preserves input order
linkSortSankeyLinkComparator<TNode, TLink> | nullD3 orderLink ordering inside each node; null preserves input order
nodeWidthnumber | (chart: ChartBounds) => number24Positive final-pixel node width
nodePaddingnumber | (chart: ChartBounds) => number8Nonnegative final-pixel separation within a layer
insetnumber | SankeyInset | responsive callback0Final-pixel inset from the resolved plot bounds
iterationsnumber6Nonnegative integer relaxation-pass count
marks(context: SankeyDiagramContext) => nonempty marksRequiredOrdinary marks over final-pixel node and link rows
idstringLayer-derivedStable parent mark identity
motionChartMotionDefinitionNoneParent motion policy merged with each child's motion policy

Responsive nodeWidth, nodePadding, and inset callbacks receive the final ChartBounds. Insets may be one number or separate top, right, bottom, and left values. The remaining extent must fit the node width and have a positive height.

Child marks

The marks callback receives { id, chart, nodes, links }. It must return at least one ordinary mark. Positional channels in those child marks are already final pixels, so a Sankey definition needs no x or y scale and normally hides Cartesian guides.

The callback may run more than once while responsive margins and guides converge. Keep it synchronous, deterministic, and free of input mutation or external side effects.

Use the callback for presentation that belongs to the visualization: link curve and paint, node color, label side and wording, backdrops, or a title. Those decisions remain visible beside the marks rather than becoming hidden layout data preparation.

Child scene keys, mark IDs, and interaction points are scoped under the Sankey mark. Color channels, layout labels, focus states, and child motion retain their ordinary behavior. A child cannot itself require resolved mark layout; nested responsive layout passes are rejected.

Every SankeyNode<TNode, TLink> contains:

  • kind: 'node', stable key, index, depth, height, and layer;
  • aggregate value;
  • final-pixel x0, x1, y0, y1, and center x, y;
  • direct raw data, source, and sourceIndexes lineage; and
  • immutable incomingLinks and outgoingLinks.

Every SankeyLink<TNode, TLink> contains:

  • kind: 'link', stable key, raw data, sourceRows, and sourceIndexes;
  • sourceKey, targetKey, node indexes, and resolved sourceNode and targetNode;
  • semantic value; and
  • final-pixel width, x1, y1, x2, and y2.

The output rows and their lineage arrays are immutable. Node and link visual, sort, tooltip, and motion callbacks can reach the original row through data.

Types

The exact entry exports sankeyDiagram, SankeyAlignment, SankeyInset, SankeyLayoutValue, SankeyEndpointContext, SankeyNodeContext, SankeyLinkContext, SankeyNode, SankeyLink, SankeyDiagramContext, SankeyNodeComparator, SankeyLinkComparator, and SankeyDiagramOptions.

See Rules, Links, Arrows, Vectors, and Ticks for link curves and paint, and Networks and Hierarchies for the catalog cases.