Sankey and Chord
Flow series: edges fromField → toField weighted by sizeField.
Sankey
Nodes are laid out in columns by topological depth; link thickness is proportional to the flow.
ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'User journey' },
series: [{ type: 'sankey', fromField: 'from', toField: 'to', sizeField: 'value' }],
legend: { enabled: false },
};
}ts
export function getData() {
return [
{ from: 'Traffic', to: 'Organic', value: 620 },
{ from: 'Traffic', to: 'Ads', value: 380 },
{ from: 'Organic', to: 'Sign-up', value: 240 },
{ from: 'Ads', to: 'Sign-up', value: 190 },
{ from: 'Organic', to: 'Bounce', value: 380 },
{ from: 'Ads', to: 'Bounce', value: 190 },
{ from: 'Sign-up', to: 'Subscription', value: 160 },
{ from: 'Sign-up', to: 'Freemium', value: 270 },
];
}Labels and node configuration
label (font, color, formatter({ name, total })), node.width/node.spacing, and linkOpacity:
ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Budget flow' },
subtitle: { text: 'labels with totals, wide nodes, dense links' },
series: [
{
type: 'sankey',
fromField: 'from',
toField: 'to',
sizeField: 'amount',
node: { width: 14, spacing: 24 },
linkOpacity: 0.5,
label: {
fontSize: 12,
fontWeight: 'bold',
formatter: ({ name, total }) => `${name} · ${total}K`,
},
},
],
legend: { enabled: false },
};
}ts
export function getData() {
return [
{ from: 'Salary', to: 'Budget', amount: 220 },
{ from: 'Freelance', to: 'Budget', amount: 60 },
{ from: 'Budget', to: 'Rent', amount: 90 },
{ from: 'Budget', to: 'Food', amount: 70 },
{ from: 'Budget', to: 'Transport', amount: 30 },
{ from: 'Budget', to: 'Savings', amount: 90 },
{ from: 'Savings', to: 'Investments', amount: 60 },
{ from: 'Savings', to: 'Emergency fund', amount: 30 },
];
}Chord
Nodes around a circle, ribbons are the mutual flows.
ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Calls between services' },
series: [{ type: 'chord', fromField: 'from', toField: 'to', sizeField: 'calls' }],
legend: { enabled: false },
};
}ts
export function getData() {
return [
{ from: 'API', to: 'Auth', calls: 320 },
{ from: 'API', to: 'Billing', calls: 180 },
{ from: 'Web', to: 'API', calls: 540 },
{ from: 'Mobile', to: 'API', calls: 410 },
{ from: 'Billing', to: 'Auth', calls: 90 },
{ from: 'Web', to: 'Auth', calls: 130 },
];
}Spacing and labels
nodeSpacing — the gap between arcs (px along the inner radius), linkOpacity — ribbon density, label.formatter receives the node's name and total:
ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'User migration between platforms' },
subtitle: { text: 'nodeSpacing: 28, dense ribbons, labels with totals' },
series: [
{
type: 'chord',
fromField: 'from',
toField: 'to',
sizeField: 'users',
nodeSpacing: 28,
linkOpacity: 0.55,
label: {
fontSize: 12,
formatter: ({ name, total }) => `${name} (${total})`,
},
},
],
legend: { enabled: false },
};
}ts
export function getData() {
return [
{ from: 'Web', to: 'iOS', users: 18 },
{ from: 'Web', to: 'Android', users: 22 },
{ from: 'iOS', to: 'Web', users: 9 },
{ from: 'Android', to: 'Web', users: 12 },
{ from: 'iOS', to: 'Android', users: 6 },
{ from: 'Android', to: 'iOS', users: 7 },
{ from: 'Web', to: 'Desktop', users: 10 },
{ from: 'Desktop', to: 'Web', users: 5 },
];
}Options
Options common to all series (name, showInLegend, tooltip.renderer, …) are covered in Common series options.
| Option | Series | Description |
|---|---|---|
fromField | both | flow graph edges |
toField | both | flow graph edges |
sizeField | both | flow graph edges |
fills | both | node colors cycling through the palette |
Full option list
| Option | Type | Default | Description |
|---|---|---|---|
linkOpacity | both | 0.35 | flow ribbon opacity |
nodeSpacing | chord | 12 | gap between node arcs, px |
label.enabled | boolean | true | node labels |
label.formatter | ({ name, total }) => string | node name | content |
label.fontSize | Pixels | 11 | label font size |
label.fontWeight | string | number | normal | font weight |
label.fontFamily | string | theme font | font family |
label.color | ColorValue | foreground | color |
node.width | Pixels | 14 | sankey node width |
node.spacing | Pixels | 14 | sankey node vertical gap |