// Shared by the vanilla-js, React and Vue builds. A synthetic population model:
// as the minimum age rises, the crowd shrinks and the female share dips. Each
// dot is one person; colour is gender; the female minority nests in the centre
// of the packed blob. Dragging the slider re-buckets the data and the dots
// redistribute in place, they do not rebuild from scratch.
function countsForAge(minAge) {
var frac = (90 - minAge) / 45 // 1 at age 45, 0 at age 90
var total = Math.round(180 + 760 * frac)
var femaleShare = 0.2 + 0.16 * frac
var female = Math.round(total * femaleShare)
return { female: female, male: total - female, total: total }
}
function readoutText(minAge) {
var c = countsForAge(minAge)
var pct = ((c.female / c.total) * 100).toFixed(1)
return (
c.total.toLocaleString() +
' people aged ' +
minAge +
'+, ' +
c.female.toLocaleString() +
' female (' +
pct +
'%)'
)
}
var options = {
series: [338, 602],
chart: {
id: 'popChart',
type: 'unit',
height: 460,
animations: {
enabled: true,
speed: 700,
},
},
labels: ['Female', 'Male'],
colors: ['#EE5A8F', '#1AA5A0'],
legend: {
position: 'bottom',
},
plotOptions: {
unit: {
layout: 'packed',
sortByGroup: true,
spacing: 1.1,
},
},
}
var chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()
// countsForAge and readoutText live in the shared head script.
var ageInput = document.querySelector('#age')
var readout = document.querySelector('#readout')
ageInput.addEventListener('input', function () {
var minAge = parseInt(ageInput.value, 10)
readout.textContent = readoutText(minAge)
var c = countsForAge(minAge)
chart.updateSeries([c.female, c.male])
})