Acronis UIKit
Components

SankeyChart

A typed Sankey flow diagram — nodes + links, width proportional to value.

Usage

import { SankeyChart } from '@acronis-platform/ui-react';
import type { ChartConfig } from '@acronis-platform/ui-react';

SankeyChart is a typed composition over the shared Chart primitives, built on recharts' Sankey. Give it a graph (data.nodes + data.links) and a per-node config — it renders a themed flow diagram where each link's width is proportional to its value and each ribbon is tinted by its target node, so you don't hand-compose recharts children. There are no axes or grid; a count/% legend is opt-in via showLegend (see below).

Node colors come from the palette prop, not from config — see Palettes. Node names are the color keys, keyed into config: each entry maps a node to a label and an optional tone that re-points it within the palette, and SankeyChart resolves them into the --color-<name> custom properties the node bars fill from. Names must be unique and CSS-safe.

Examples

A flow of nodes and links, ribbon width proportional to value:

const data = {
  nodes: [{ name: 'all' }, { name: 'certified' }, { name: 'expired' }],
  links: [
    { source: 0, target: 1, value: 209 },
    { source: 0, target: 2, value: 31 },
  ],
};

const config = {
  all: { label: 'All tenants', tone: { status: 'info' } },
  certified: { label: 'Certified', tone: { status: 'info' } },
  expired: { label: 'Expired', tone: { status: 'danger' } },
} satisfies ChartConfig;

<SankeyChart
  config={config}
  palette={{ type: 'status' }}
  data={data}
  className="h-[360px] w-[620px]"
/>;

Tune the geometry with nodePadding / nodeWidth / linkCurvature, auto-order nodes with sort, hide the on-chart labels with showLabels, and show a built-in legend (color swatch + label + value + %) with showLegend:

<SankeyChart
  config={config}
  data={data}
  nodeWidth={16}
  linkCurvature={0.6}
  showLabels={false}
  showLegend
/>;

showLegend provides that count/% legend (each node's value + share of the largest node) — the "Certification compliance" card is just showLabels={false}

  • showLegend. Give a link an explicit color to override its default target tint; an explicit color renders full-opacity to match its node bar, while the default tinted ribbons stay at 35%:
const data = {
  nodes: [{ name: 'all' }, { name: 'certified' }],
  links: [
    { source: 0, target: 1, value: 209, color: 'var(--ui-background-brand-primary-disabled)' },
  ],
};

Tooltip

showTooltip (on by default) shows a hover card for the hovered node or link — a color dot matching the ribbon, the source → target config labels, and the value. Set showTooltip={false} to drop it, or pass tooltipContent to replace the card's content with your own render function while keeping the same trigger behavior:

<SankeyChart
  config={config}
  data={data}
  tooltipContent={({ active, payload }) =>
    active && payload?.length ? (
      <div className="rounded-lg border border-border bg-background px-2.5 py-1.5 text-xs">
        {Number(payload[0]?.value).toLocaleString()} users
      </div>
    ) : null
  }
/>;

The tooltip is pointer-only: recharts' Sankey has no accessibility layer (no keyboard focus), so keep the values reachable in text — showLegend, a caption, or an adjacent table — rather than only on hover.

Accessibility

SankeyChart sets no role and no aria-* of its own, and recharts draws a Sankey into a bare <svg> — an empty <title> / <desc> pair, no role, no tabindex. So the diagram has no accessible name, the plot is not a tab stop, and (as the tooltip note above says) the hover card is a reading a keyboard never reaches.

The root is a plain <div> that spreads the props you pass, so a role and a label land on it:

<SankeyChart
  role="img"
  aria-label="Certification status of 240 tenants: 209 certified, 31 expired"
  config={config}
  data={data}
/>

aria-labelledby works the same way, as does wrapping the chart in a <figure> with a <figcaption>.

A name is not a text alternative, though. A flow diagram is a visual encoding of numbers, so the numbers themselves have to be reachable as text — a caption, a summary sentence, or a table beside the chart. showLegend is the cheapest route: it renders each node's label, value and share as ordinary HTML below the plot rather than inside the SVG. The node labels showLabels draws are real <text> and not pixels, but they sit in the SVG with no structural role and carry no value alongside the name.

Direction (RTL)

Under dir="rtl" the chrome around the plot — the tooltip, SankeyChart's own legend (plain DOM below the diagram), and any readouts you compose alongside them — mirrors on its own, because it is ordinary flow layout built from logical CSS utilities. The plot area deliberately stays left-to-right: recharts places every mark in physical SVG coordinates, so mirroring it would flip the reading order of the data without flipping the geometry that encodes it. ChartContainer holds that in place by pinning .recharts-surface to direction: ltr.

For a Sankey that pin fixes the labels as much as the diagram. The node renderer anchors each label with text-anchor: start or end depending on whether the node has outgoing flow, and those two SVG keywords resolve against the inherited direction — so without the pin an inherited dir="rtl" would mirror every label back across its anchor and lay it over the node it belongs to. With it, the columns run from source to sink left to right and a node's label sits on the side its links choose — to the right of a node with outgoing flow, to the left of a terminal one — which is a property of the flow, not of the reading direction. The pin stops at the surface, so the tooltip and the legend still mirror with the page.

API Reference

Prop

Type

Edit on GitHub

On this page