import React from 'react'
import ReactApexChart from 'react-apexcharts'
import ApexCharts from 'apexcharts'
import './styles.css'
// 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 +
'%)'
)
}
const ApexChart = () => {
const [state, setState] = React.useState({
series: [338, 602],
options: {
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,
},
},
},
})
React.useEffect(() => {
// Reach the live instance by its chart.id, then wire the slider.
// (countsForAge and readoutText live in the shared head script.)
let chart
const timer = window.setInterval(() => {
chart = ApexCharts.getChartByID('popChart')
if (!chart) return
window.clearInterval(timer)
const ageInput = document.querySelector('#age')
const readout = document.querySelector('#readout')
ageInput.addEventListener('input', () => {
const minAge = parseInt(ageInput.value, 10)
readout.textContent = readoutText(minAge)
const c = countsForAge(minAge)
chart.updateSeries([c.female, c.male])
})
}, 50)
return () => window.clearInterval(timer)
}, [])
return (
<div>
<div className="wrap">
<h1>Population explorer</h1>
<p>
One dot per person, coloured by gender, the minority packed into the
centre.
</p>
<div className="chart-wrap">
<div id="chart">
<ReactApexChart
options={state.options}
series={state.series}
type="unit"
height={460}
/>
</div>
</div>
<div className="controls">
Minimum age:{' '}
<span className="readout" id="readout">
45+
</span>
<input type="range" id="age" min="45" max="90" step="1" value="45" />
</div>
</div>
</div>
)
}
export default ApexChart