A new layout mode, ADDITIVE: three new FORMATS with `sideLanes`; every existing format takes exactly its old path. Every name horizontal, on the left and right of the map in two staggered columns per side (rows alternate, so each column keeps a full line pitch and each row holds one name). Co-located groups form a cluster with one leader and a bracketed block. Crossing-free by construction: one vertical split sends each cluster to the nearer side; each leader is a short stub to its own lane, a horizontal run to the map edge, and a fan to its block, with lanes placed farthest-from-the-edge first and clamped between their neighbours, and fans in the lanes' order. The renderer measures and returns its crossing count. A real photo (never the placeholder) sits outside its name where the format allows. The type is the largest that fits the rows and columns, capped per format (nameMaxPt). On these sheets only: pins stay at their true positions (no settle pass), the map frame takes the country's own shape centred in the band with a thin margin, and the side-lane styles are emitted. India (855 groups, live data): 60x96 20.7 pt names + 7.9 mm photos; 66x66 14.6 pt + 5.5 mm; 36x60 12.6 pt, no photos; 0 crossings on all three; 4 s per render where the numbered path took 65 s. Re-pinned. |
||
|---|---|---|
| .. | ||
| api | ||
| charts | ||
| colors | ||
| components | ||
| composables | ||
| constants | ||
| dashboards | ||
| data | ||
| elements | ||
| i18n | ||
| layouts | ||
| lists | ||
| maps | ||
| packet | ||
| packets | ||
| scripts | ||
| stores | ||
| styles | ||
| utils | ||
| vendor/cldr | ||
| index.js | ||
| ProfileLoader.vue | ||
| README.md | ||
library/ (@map) — the shared map template
The other half of the architecture (see ../plugin-designs/README.md):
every map in plugin-designs/<your-map>/ composes the reusable, parameterized pieces that live here.
Fix something here and every map benefits on the next build; break something here and every map
breaks — read components/WARNING.md before touching shared pieces.
| Folder | What lives there |
|---|---|
ProfileLoader.vue |
The root of every bundle: parses profile-config, loads the profile, provides the stores + config |
components/ |
Shared UI — map, legends, controls, popup (PeopleGroupDetail), tables, charts, hints (README) |
composables/ |
Shared logic — map engine (useMapInstance), provider switch, shadow-DOM styles, theming |
stores/ |
Per-instance Pinia stores (ui / map / data) — provided by ProfileLoader, injected by children |
api/ |
Data-source registry (sources.json) + fetch layer — the JAMstack runtime wiring |
colors/ |
Color sets maps opt into via profile-config.colorSet |
i18n/ |
The shared string catalogs (all maps speak the same languages) |
data/ |
Small shared datasets baked at build time (big served data lives in ../data/) |
constants/ |
Shared constants |
scripts/ |
Maintainer pipelines (posters, research) — not part of any bundle |
The rule of thumb (same as WARNING.md): custom code in your app-profile, reusable code here — and things only move from the first to the second once they've earned it.