Charts /
CH-SPA-05
CH-SPA-05 . family SPA
FLOW MAP
curved width-scaled arrows between supplied places. Needs: base polygons + places + flows [{from, to, value}], <= 8 flows.
flowmagnitude
Use when
- origin-destination stories over real geography
- corridor volumes: what moves where, how much
Do not use when
- more than ~8 flows (spaghetti)
- flows both directions between the same pair (split or net them first)
See instead
Alternatives
- CH-FLO-02 (flows without geography)
- CH-FLO-04 (dense mutual exchange)
Rules
- arrow width proportional to value; the largest flow is labeled
- arrowheads mark direction; curves bend one deterministic way
Never do this
- two-way arrows on one curve
- more than 8 flows
- width not proportional to value
QA before delivering
- width-true arrows
- largest flow labeled
- <= 8 flows
- source present
Data shape
| title | action title with a number |
| source | bottom-left always |
| unit | flow unit |
| note | coordinates are author-supplied unit-square (0-100) geometry; the renderer scales, the author owns projection and aspect |
| regions | base polygons |
| places | [{name, at}] |
| flows | [{from: [x,y], to: [x,y], value}] |
Sample data (golden)
{
"title": "The port feeds the south corridor with 140 loads a week",
"eyebrow": "WEEKLY FLOWS",
"source": "Source: sample dataset v1, 2026-07-12",
"unit": "loads",
"regions": [
{
"name": "North",
"label_at": [
32,
17
],
"polygon": [
[
10,
5
],
[
55,
2
],
[
60,
25
],
[
35,
32
],
[
8,
28
]
]
},
{
"name": "West",
"label_at": [
19,
45
],
"polygon": [
[
8,
28
],
[
35,
32
],
[
30,
60
],
[
5,
58
]
]
},
{
"name": "Central",
"label_at": [
48,
42
],
"polygon": [
[
35,
32
],
[
60,
25
],
[
68,
50
],
[
30,
60
]
]
},
{
"name": "East",
"label_at": [
78,
38
],
"polygon": [
[
60,
25
],
[
92,
20
],
[
95,
55
],
[
68,
50
]
]
},
{
"name": "South",
"label_at": [
58,
72
],
"polygon": [
[
30,
60
],
[
68,
50
],
[
95,
55
],
[
90,
90
],
[
25,
88
]
]
}
],
"places": [
{
"name": "Port",
"at": [
80,
30
]
},
{
"name": "Hub",
"at": [
48,
42
]
},
{
"name": "South site",
"at": [
55,
75
]
},
{
"name": "West site",
"at": [
19,
45
]
},
{
"name": "North site",
"at": [
32,
17
]
}
],
"flows": [
{
"from": [
80,
30
],
"to": [
48,
42
],
"value": 140
},
{
"from": [
48,
42
],
"to": [
55,
75
],
"value": 90
},
{
"from": [
48,
42
],
"to": [
19,
45
],
"value": 45
},
{
"from": [
48,
42
],
"to": [
32,
17
],
"value": 30
},
{
"from": [
80,
30
],
"to": [
55,
75
],
"value": 25
}
]
}