paperchart — sankey
Two columns. Source nodes on the left stack top-to-bottom proportional to their total out-flow. Target nodes on the right stack proportional to their total in-flow. Each flow is a Bézier ribbon between one source and one target; its thickness equals its value.
When to use
- Traffic source → landing bucket attribution.
- Token allocation (query tokens → index postings vs. corrections vs. doc headers).
- Error routing (exception class → handler).
Input shape
{
"data": {
"sources": [
{ "key": "direct", "label": "direct users", "caption": "7.4M sessions/mo", "total": 7400000 },
{ "key": "organic", "label": "organic search", "caption": "Google + Bing", "total": 8000000, "accent": true }
],
"targets": [
{ "key": "docs", "label": "/docs", "caption": "reference" },
{ "key": "api", "label": "/api", "caption": "sdk + http" }
],
"flows": [
{ "from": "direct", "to": "docs", "value": 3800000 },
{ "from": "organic", "to": "docs", "value": 3050000 }
]
}
}
Visual rules
- One source or target node can carry
accent: true; ribbons starting or ending there inherit the accent tint. - Ribbons use multiply/darken blending so overlap is readable.
- Labels sit outside the column bars, never on the ribbons.
CLI
paperchart sankey -i data.json -o sankey.png
paperchart sankey --defaults -o sankey.png