chart = (county, state, data, row) => {
const pack = data => d3.pack()
.size([size, size])
.padding(3)(d3.hierarchy(data)
.sum(d => d.population_total_2018)
.sort((a, b) => b.d_2016 < a.d_2016 ? -1 : 1)
);
const root = pack(
{
children: [
{
name: 'same',
children: data.filter(d => d.poll_count_2016 === d.poll_count_2020)
},
{
name: 'loss',
children: data.filter(d => d.poll_count_2016 > d.poll_count_2020)
},
{
name: 'gain',
children: data.filter(d => d.poll_count_2016 < d.poll_count_2020)
}
]
}
);
const svg = d3.create("svg")
.attr('width', size + 20)
.attr('height', size + 20)
.attr("viewBox", [0, 0, size + 20, size + 20])
svg.append('rect').attr('width', size + 20).attr('height', size + 20).style('fill', 'white');
const guts = svg
.append('g')
.attr('transform', `translate(${10},${10})`)
guts.append('text')
.text(county + ' County, ' + state)
.attr('y', 40)
.style('font-family', 'Helvetica')
.style('font-size', 40)
.style('font-weight', 800)
const same = guts.selectAll("g.same")
.data(root.children.find(c => c.data.name === 'same').children)
.enter("g")
.append("g")
.classed('same', true)
.classed('circle-wrapper', true)
.attr("transform", d => `translate(${d.x},${d.y})`);
const samePopulation = numeral(Math.round(
root
.children
.find(c => c.data.name === 'same')
.children
.reduce((a, c) => (a += c.data.population_total_2018), 0)
)).format(',');
guts
.append('text')
.classed('small', true)
.text(`${samePopulation} possible voters live in precincts that stayed the same.`)
.attr('x', 0)
.attr('y', 100)
const loss = guts.selectAll("g.removed")
.data(root.children.find(c => c.data.name === 'loss').children)
.enter("g")
.append("g")
.classed('removed', true)
.classed('circle-wrapper', true)
.attr("transform", d => `translate(${d.x},${d.y})`);
const lossPopulation = numeral(Math.round(
root
.children
.find(c => c.data.name === 'loss')
.children
.reduce((a, c) => (a += c.data.population_total_2018), 0)
)).format(',');
guts
.append('text')
.classed('small', true)
.text(`${lossPopulation} possible voters live`)
.attr('x', size)
.attr('y', 230)
.style('text-anchor', 'end')
guts
.append('text')
.classed('small', true)
.text('in precincts that lost polls.')
.attr('x', size)
.attr('y', 245)
.style("text-anchor", 'end');
const gain = guts.selectAll("g.gain")
.data(root.children.find(c => c.data.name === 'gain').children)
.enter("g")
.append("g")
.classed('removed', true)
.classed('circle-wrapper', true)
.attr("transform", d => `translate(${d.x},${d.y})`);
const gainPopulation = numeral(Math.round(
root
.children
.find(c => c.data.name === 'gain')
.children
.reduce((a, c) => (a += c.data.population_total_2018), 0)
)).format(',');
guts
.append('text')
.classed('small', true)
.text(`${gainPopulation} possible voters live`)
.attr('x', size - 100)
.attr('y', size - 100)
.style('text-anchor', 'end')
guts
.append('text')
.classed('small', true)
.text('in precincts that gained polls.')
.attr('x', size - 100)
.attr('y', size - 100 + 15)
.style("text-anchor", 'end');
guts.selectAll('.small')
.style('font-size', 12.5)
.style('font-family', 'Helvetica')
.style("font-weight", 800)
same.append('circle')
loss.append("circle")
gain.append("circle")
guts.selectAll('circle')
.attr("r", d => d.r)
.style('fill', d => {
return d3.interpolate(
scales.vote((d.data.d_2016 / d.data.t_2016) - (d.data.r_2016 / d.data.t_2016)),
'#ffffff'
)(0.5)
})
.style('stroke', d => {
return scales.vote((d.data.d_2016 / d.data.t_2016) - (d.data.r_2016 / d.data.t_2016))
})
.style('stroke-width', 1);
makeLegend(guts, size, row);
return svg.node();
}