Race charts — paste a table, get a race
The charts kit turns a table into an animated race chart — ranked bars, columns or lines that reorder over time as the data changes. Declare a racechart, paste the data with racedata (a value per period per row; icons ride the bars), and play with race. Bars get rescaling gridlines + a live Total; raceline/racepanel add a companion line or a multi-line history panel below the bars. See the charts guide.
Each block is the whole file — copy it into x.manic and run manic x.manic (live) or --record out (video).
charts-gdp-race
The flagship bar-chart race: the world’s biggest economies, GDP 1990→2026, with country flags riding the bars. Watch China climb from #7 to #2 as the bars reorder, the axis rescales with gridlines, and the year + Total tick — all from one pasted data block.
// charts-gdp-race.manic — an animated BAR-CHART RACE from a pasted data block.
//
// The `charts` kit turns a table into bars that actually REORDER as the numbers
// change — the viral data-viz format, but true to the data and self-contained in
// one script. Paste your data into `racedata` (one row per entity: label, an icon
// shorthand, then a value per period), then `race` plays the whole thing —
// re-ranking, sliding bars to their new slots, rescaling the axis, and ticking the
// year + values. Bars are rounded, gradient-filled; flags are imported SVG.
//
// Nominal GDP, US$ trillion, 1990 → 2026 (approx.) — watch China climb from the
// bottom to #2, Japan slide, and India rise.
//
// manic examples/charts-gdp-race.manic
canvas("16:9");
template("blank");
racechart(gdp, "bar", "1990 1995 2000 2005 2010 2015 2020 2026",
"The World's Biggest Economies — GDP 1990 to 2026 ($T)");
// paste your table: label, ICON, then one value per period.
// separators are forgiving — commas here, but tabs / spaces / newlines all work.
//
// the ICON column takes ANY svg, not just flags:
// us a flag shorthand → asset:svg/flags/us.svg
// rocket / heart / trophy an emoji/icon alias → asset:svg/emoji|lucide/…
// asset:svg/lucide/lightbulb.svg an explicit set path
// logos/acme.svg your OWN file (any path ending in .svg)
// omit the icon entirely and the row is just label + values.
//
// NOTE: a few flags whose stars are drawn with SVG <use> (e.g. cn — China) render
// imperfectly for now (tracked); most flags and all icons/emoji render cleanly.
racedata(gdp, "
USA, us, 5.96, 7.64, 10.25, 13.04, 15.05, 18.24, 21.06, 30.34
China, cn, 0.36, 0.73, 1.21, 2.29, 6.09, 11.06, 14.69, 20.50
Japan, jp, 3.13, 5.55, 4.97, 4.83, 5.76, 4.44, 5.06, 4.40
Germany, de, 1.60, 2.59, 1.95, 2.85, 3.40, 3.36, 3.89, 4.90
India, in, 0.32, 0.36, 0.47, 0.82, 1.68, 2.10, 2.67, 4.60
UK, gb, 1.09, 1.33, 1.66, 2.54, 2.49, 2.93, 2.70, 3.90
France, fr, 1.27, 1.60, 1.36, 2.20, 2.65, 2.44, 2.63, 3.30
Brazil, br, 0.46, 0.77, 0.65, 0.89, 2.21, 1.80, 1.48, 2.40
");
race(gdp, 14);
charts-column-race
A COLUMN race (vertical bars), built with the per-series raceseries input: men’s tennis
Grand Slam titles 2005→2024, Djokovic climbing to overtake Federer and Nadal, with flags.
// charts-column-race.manic — a COLUMN chart race (vertical bars), built with the
// per-series `raceseries` input (the computed/loop sibling of `racedata`). A sport
// race: the men's tennis Grand Slam count, 2005 → 2024 — watch Djokovic climb from
// nothing to overtake Federer and Nadal. Flags are imported SVG (rs/es/ch/gb).
//
// manic examples/charts-column-race.manic
canvas("16:9");
template("blank");
racechart(gs, "column", "2005 2009 2013 2017 2021 2024",
"Men's Tennis — Grand Slam Titles, 2005 to 2024");
// one entity per player: raceseries(chart, "name", "flag", "v0 v1 …")
raceseries(gs, "Federer", "ch", "5 15 17 19 20 20");
raceseries(gs, "Nadal", "es", "4 6 13 16 20 22");
raceseries(gs, "Djokovic", "rs", "0 1 6 12 20 24");
raceseries(gs, "Murray", "gb", "0 0 2 3 3 3");
race(gs, 10);
charts-line-race
A LINE race: each series draws its line on left-to-right as the years tick, value/label/flag riding the leading tip; the race is which line climbs highest. Fixed axis, decluttered tips.
// charts-line-race.manic — a LINE chart race. Each series draws its line on
// (left → right) as the years tick, with the value, label and flag riding the
// leading tip; the "race" is which line climbs highest. Fixed y-axis (line charts
// don't rescale), L-shaped axes, flags are imported SVG.
//
// manic examples/charts-line-race.manic
canvas("16:9");
template("blank");
racechart(gdp, "line", "1990 2000 2010 2020 2026",
"GDP Over Time — a Line Race ($T)");
racedata(gdp, "
USA, us, 5.96, 10.25, 15.05, 21.06, 30.34
China, cn, 0.36, 1.21, 6.09, 14.69, 20.50
Japan, jp, 3.13, 4.97, 5.76, 5.06, 4.40
Germany, de, 1.60, 1.95, 3.40, 3.89, 4.90
India, in, 0.32, 0.47, 1.68, 2.67, 4.60
");
race(gdp, 10);
charts-bar-line
The bar+line combo: a GDP bar race with a companion raceline across the top showing the
auto-summed world Total, drawn on with a marker and live readout, synced to the race.
// charts-bar-line.manic — a BAR race with a companion LINE (the classic combo).
//
// The bars race as usual (reordering by value), and `raceline` draws a synced line
// across the top strip — here the running TOTAL, auto-summed from the bars (pass
// your own "v0 v1 …" to track a different metric). The line draws on, a marker
// rides its leading point, and a live readout counts up — all locked to the race.
//
// manic examples/charts-bar-line.manic
canvas("16:9");
template("blank");
racechart(gdp, "bar", "1990 2000 2010 2020 2026",
"World GDP — Who's Biggest, and the Total Growing ($T)");
racedata(gdp, "
USA, us, 5.96, 10.25, 15.05, 21.06, 30.34
China, cn, 0.36, 1.21, 6.09, 14.69, 20.50
Japan, jp, 3.13, 4.97, 5.76, 5.06, 4.40
Germany, de, 1.60, 1.95, 3.40, 3.89, 4.90
India, in, 0.32, 0.47, 1.68, 2.67, 4.60
");
// the companion line across the top — a running total of all bars (auto-summed)
raceline(gdp, "World total");
race(gdp, 12);
charts-german-elections
Bar race + a multi-line history racepanel below (the Flourish bar+line layout), from a
REAL CSV: German federal election vote share 1949→2021, 7 parties, missing early years as
0, Total 100. Every party is a bar up top and a color-matched line in the history panel.
// charts-german-elections.manic — a BAR race from real CSV data (German federal
// election vote share, %, 1949-2021). Transcribed from Data.1785183258253.csv:
// the empty separator column is dropped and missing early years (parties that
// didn't exist yet) are 0. Watch CDU/CSU and SPD trade the lead while the Greens,
// Left and AfD climb from nothing.
//
// manic examples/charts-german-elections.manic
canvas("16:9");
template("blank");
racechart(de, "bar", "1949 1953 1957 1961 1965 1969 1972 1976 1980 1983 1987 1990 1994 1998 2002 2005 2009 2013 2017 2021",
"German Federal Elections — Vote Share %, 1949 to 2021");
racedata(de, "
CDU/CSU, 31, 45.2, 50.2, 45.3, 47.6, 46.1, 44.9, 48.6, 44.5, 48.8, 44.3, 43.8, 41.4, 35.1, 38.5, 35.2, 33.8, 41.5, 32.9, 24.1
SPD, 29.2, 28.8, 31.8, 36.2, 39.3, 42.7, 45.8, 42.6, 42.9, 38.2, 37, 33.5, 36.4, 40.9, 38.5, 34.2, 23, 25.7, 20.5, 25.7
FDP, 11.9, 9.5, 7.7, 12.8, 9.5, 5.8, 8.4, 7.9, 10.6, 7, 9.1, 11, 6.9, 6.2, 7.4, 9.8, 14.6, 4.8, 10.7, 11.5
Green, 0, 0, 0, 0, 0, 0, 0, 0, 1.5, 5.6, 8.3, 5.1, 7.3, 6.7, 8.6, 8.1, 10.7, 8.4, 8.9, 14.8
Left, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.4, 4.4, 5.1, 4, 8.7, 11.9, 8.6, 9.2, 4.9
AfD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.7, 12.6, 10.3
Other, 27.6, 16.3, 10.2, 5.6, 3.6, 5.4, 0.9, 0.9, 0.5, 0.4, 1.3, 4.2, 3.6, 6, 3, 4, 6, 6.3, 5.2, 8.6
");
// a synced multi-line history panel below the bars: every party as a line, drawn
// up to a moving time-cursor (the Flourish bar+line combo)
racepanel(de);
race(de, 16);