console.clear() d3.select('html').selectAppend('div.tooltip') d3.loadData('https://int.nyt.com/newsgraphics/2017/06/uk-election/results-live.json', function(err, res) { data = res[0].constituencies data.forEach(d => { d.candidates.forEach(c => { if (c.party == 'C'){ d.c2017 = c.votes_pct/100 d.c2015 = (c.votes_pct - c.votes_pct_change)/100 } if (c.party == 'Lab'){ d.l2017 = (c.votes_pct)/100 d.l2015 = (c.votes_pct - c.votes_pct_change)/100 } if (c.party == 'UKIP'){ d.u2017 = (c.votes_pct)/100 d.u2015 = (c.votes_pct - c.votes_pct_change)/100 } }) d.pc2015 = d.c2015/(d.c2015 + d.l2015) d.pc2017 = d.c2017/(d.c2017 + d.l2017) }) d3.select('body').html('') var c = d3.conventions({}) c.x.domain([.2, .8]) c.y.domain([0, .3]) c.xAxis.ticks(5) c.yAxis.ticks(5) c.drawAxis() c.svg.appendMany(data, 'path') .at({ d: d => { return [ 'M', c.x(d.pc2015), c.y(d.u2015), 'L', c.x(d.pc2017), c.y(d.u2017), ].join(' ') }, stroke: '#000', opacity: .4 }) .call(d3.attachTooltip) .attr('marker-end', 'url(#arrow)') c.svg .append('marker') .attr('id', 'arrow') .attr('viewBox', '-10 -10 20 20') .attr('markerWidth', 10) .attr('markerHeight', 10) .attr('orient', 'auto') .append('path') .attr('d', 'M-4,-6 L 10,0 L -4,6') })