chart = {
const svg = d3.create('svg')
.attr('width', width)
.attr('height', height)
data.forEach(d => d.r = rScale(d.electoralVotes))
const simulation = d3.forceSimulation( data )
.force('x', d3.forceX().strength(0.2).x(d => xScale(d.dem/d.total)) )
.force('y', d3.forceY().strength(0.05).y(margin.top + height / 2) )
.force('collide', d3.forceCollide().radius(d => d.r + 1 ).strength(1) )
const g = svg.selectAll('g.node')
.data( simulation.nodes() )
.join('g')
.attr('class', 'node')
.call( g => g
.append('circle')
.attr('r', d => d.r)
.style('fill', d => color(Math.round(d.dem/d.total)))
.style('opacity', 0.9)
)
.call( g => g
.append('title')
.text(d => `${d.state}\nDem: ${d.dem.toLocaleString()}\nRep: ${d.rep.toLocaleString()}\nTotal: ${ d.total.toLocaleString() }\nElectoral votes: ${d.electoralVotes}\n`)
)
svg.append('g')
.attr('class', 'x-axis')
.attr('transform', `translate(0,${ height/2 })`)
.call(xAxis)
simulation.on("tick", () => g.attr('transform', d => `translate(${ d.x },${ d.y })`) )
return svg.node()
}