// Small-multiple waffles: ONE mini-waffle per country, each a 10x10 grid where
// every square is 1% of that country's population living in a city. Reading
// down the trellis you compare the fill height across countries at a glance;
// toggling the year fills each tile cell-by-cell IN PLACE, so you watch the
// whole world urbanise between 1980 and 2020.
//
// This is the unit chart's `grid` layout in `split` mode: `grid.split: true`
// draws one tile per category, `grid.total: 100` gives each tile 100 cells and
// `grid.max: 100` maps the value straight to filled cells (a value of 92 fills
// 92 of 100), so each tile reads as a true percentage. The empty cells show as
// a faint `trackColor` backdrop. Figures are World-Bank-style illustrative
// urban-population shares. Shared by the vanilla-js/React/Vue builds.
var COUNTRIES = [
'Japan',
'United States',
'Germany',
'Brazil',
'South Korea',
'China',
'Nigeria',
'India',
'Kenya',
]
// One accent for every filled cell: the metric is the same everywhere, so the
// eye compares fill height, not colour. The per-tile label carries the country.
var ACCENT = '#0EA5E9'
var COLORS = COUNTRIES.map(function () {
return ACCENT
})
var YEARS = {
2020: {
label: '2020',
caption:
'By 2020 most of the world lives in a city. The tiles that were nearly empty in 1980, China and Nigeria among them, have filled in fast.',
// urban population, % of total (illustrative, ~2020)
values: [92, 83, 77, 87, 81, 61, 52, 35, 28],
},
1980: {
label: '1980',
caption:
'In 1980 cities were still the exception across much of Asia and Africa: barely a fifth of China lived in one. Each square is one percent of the population.',
// urban population, % of total (illustrative, ~1980)
values: [76, 74, 73, 66, 57, 19, 22, 23, 16],
},
}
var options = {
series: YEARS['2020'].values,
chart: {
id: 'urbanWaffle',
type: 'waffle',
height: 560,
animations: {
enabled: true,
speed: 650,
},
},
labels: COUNTRIES,
colors: COLORS,
legend: {
show: false,
},
plotOptions: {
unit: {
grid: {
split: true,
columns: 10,
total: 100,
max: 100,
trackColor: '#E8EDF2',
},
spacing: 1.2,
clusterLabels: {
show: true,
position: 'bottom',
fontSize: '12px',
fontWeight: 600,
color: '#334155',
formatter: function (name, o) {
return name + ' · ' + Math.round(o.value) + '%'
},
},
},
},
}
var chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()
// Button-driven year switch: each year is a chart.updateSeries payload; every
// tile keeps its cells in place and only the fill boundary moves. (COUNTRIES,
// COLORS and YEARS live in the shared head script.)
var buttons = document.querySelectorAll('#year-nav button')
var caption = document.getElementById('caption')
function showYear(key) {
buttons.forEach(function (b) {
b.classList.toggle('active', b.getAttribute('data-year') === key)
})
caption.textContent = YEARS[key].caption
chart.updateSeries(YEARS[key].values)
}
buttons.forEach(function (btn) {
btn.addEventListener('click', function () {
showYear(btn.getAttribute('data-year'))
})
})
caption.textContent = YEARS['2020'].caption