chart = {
const svg = d3.create('svg')
.attr('viewBox', [0, 0, width, height]);
svg.append('g').call(xAxis);
svg.selectAll('.line-decade')
.data(x.ticks())
.join('line')
.attr('class', 'line-decade')
.attr('x1', d => x(d))
.attr('x2', d => x(d))
.attr('y1', 10)
.attr('y2', height - margin.top)
.attr('stroke-width', 1)
.attr('stroke', 'lightgray');
svg.selectAll('.label-region')
.data(region)
.join('text')
.attr('class', 'label-region')
.attr('x', 0)
.attr('y', d => y(d))
.attr('text-align', 'right')
.attr('alignment-baseline', 'right')
.text(d => d);
const simulation = d3.forceSimulation(data)
.force('x', d3.forceX((d) => x(d.always)).strength(5))
.force('y', d3.forceY((d) => y(d.region)))
.force('collide', d3.forceCollide(radius + padding))
.stop();
svg.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', (d) => x(d.always))
.attr('cy', (d) => y(d.region))
.attr('r', (d) => size(d.population))
.attr('fill', (d) => color(d.region))
.attr('opacity', .7);
svg.selectAll("circle")
.on("mouseover", function(d) {
d3.select(this)
.attr('stroke-width', '2')
.attr("stroke", "black");
tooltip
.style("visibility", "visible")
.html(`<b>County:</b> ${d.county}, ${d.state}<br><b>'Always' wears mask:</b> ${d.always}%<br><b>Population:</b> ${d3.format(".2s")(d.population)}`)
})
.on("mousemove", function() {
tooltip
.style("top", d3.event.pageY - 10 + "px")
.style("left", d3.event.pageX + 10 + "px");
})
.on("mouseout", function() {
d3.select(this).attr('stroke-width', '0');
tooltip.style("visibility", "hidden");
});
for(let i = 0; i < 100; i++) {
simulation.tick();
svg.selectAll('circle')
.data(data)
.attr('cx', (d) => d.x)
.attr('cy', (d) => d.y);
yield svg.node();
}
}