|
<html> |
|
<meta charset="utf-8"> |
|
<style> |
|
body { |
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; |
|
} |
|
path.areas { |
|
stroke: grey; |
|
stroke-opacity: 0.5; |
|
cursor: pointer; |
|
} |
|
div.tooltip { |
|
font-size: 12px; |
|
position: absolute; |
|
height: auto; |
|
padding: 10px; |
|
color: #ffffff; |
|
background-color: #000000; |
|
-webkit-border-radius: 5px; |
|
-moz-border-radius: 5px; |
|
border-radius: 5px; |
|
pointer-events: none; |
|
word-wrap: break-word; |
|
white-space: pre; |
|
} |
|
</style> |
|
<body> |
|
<h1>Northern Ireland Assembly Election 2017</h1> |
|
<h2>Turnout: <span id="total_turnout"></span></h2> |
|
<svg width="100%" height="500"></svg> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<script type="text/javascript" src="http://d3js.org/queue.v1.min.js"></script> |
|
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> |
|
<script src="https://npmcdn.com/@turf/turf/turf.min.js"></script> |
|
<script src="https://rawgit.com/BobHarper1/d3.geo2rect/master/build/geo2rect.min.js"></script> |
|
<script> |
|
var svg = d3.select('svg'); |
|
var div = d3.select("body").append("div") |
|
.attr("class", "tooltip") |
|
.style("opacity", 0); |
|
var config = { |
|
width : parseInt(svg.style('width'), 10), |
|
height : parseInt(svg.style('height'), 10), |
|
padding : 40, |
|
projection : d3.geoMercator(), |
|
duration : 700, |
|
key:function(d){return d.properties.ABBREV; }, |
|
grid : { |
|
FE:{x:0,y:1}, |
|
WT:{x:0,y:2}, |
|
FT:{x:0,y:3}, |
|
EL:{x:1,y:1}, |
|
MU:{x:1,y:2}, |
|
UB:{x:1,y:3}, |
|
AN:{x:1,y:4}, |
|
NA:{x:2,y:1}, |
|
SA:{x:2,y:2}, |
|
LV:{x:2,y:3}, |
|
SD:{x:2,y:4}, |
|
EA:{x:3,y:1}, |
|
BN:{x:3,y:2}, |
|
BW:{x:3,y:3}, |
|
BE:{x:4,y:2}, |
|
BS:{x:4,y:3}, |
|
ST:{x:4,y:4}, |
|
ND:{x:5,y:3}, |
|
} |
|
}; |
|
var x = d3.scaleLinear() |
|
.domain([58, 74]) |
|
.rangeRound([50, 50 + (29 * 8)]); |
|
var color = d3.scaleThreshold() |
|
.domain([58, 60,62,64, 66, 68, 70, 72]) |
|
.range(d3.schemePurples[9]); |
|
var g = svg.append("g") |
|
.attr("class", "key") |
|
.attr("transform", "translate(0,40)"); |
|
g.selectAll("rect") |
|
.data(color.range().map(function(d) { |
|
d = color.invertExtent(d); |
|
if (d[0] == null) d[0] = x.domain()[0]; |
|
if (d[1] == null) d[1] = x.domain()[1]; |
|
return d; |
|
})) |
|
.enter().append("rect") |
|
.attr("height", 8) |
|
.attr("x", function(d) { return x(d[0]); }) |
|
.attr("width", function(d) { return 29; }) |
|
.attr("fill", function(d) { return color(d[0]); }); |
|
g.append("text") |
|
.attr("class", "caption") |
|
.attr("x", x.range()[0]) |
|
.attr("y", -6) |
|
.attr("fill", "#000") |
|
.attr("text-anchor", "start") |
|
.attr("font-weight", "bold") |
|
.text("Turnout rate"); |
|
g.call(d3.axisBottom(x) |
|
.tickSize(13) |
|
.tickFormat(function(x, i) { return i ? x : x + "%"; }) |
|
.tickValues(color.domain())) |
|
.select(".domain") |
|
.remove(); |
|
queue() |
|
.defer(d3.csv, 'data.csv') |
|
.await(ready); |
|
function ready(error, data) { |
|
var turnout = {}; |
|
var voters = {}; |
|
var electorate = {}; |
|
var name = {}; |
|
var number = {}; |
|
data.forEach(function(d) { |
|
turnout[d.Constituency_Number] = d.Turnout2017; |
|
voters[d.Constituency_Number] = d.Voters; |
|
electorate[d.Constituency_Number] = d.Electorate; |
|
name[d.Constituency_Number] = d.Constituency_Name; |
|
number[d.Constituency_Number] = d.Constituency_Number; |
|
}); |
|
|
|
console.log(name, number, turnout); |
|
document.getElementById('total_turnout').innerHTML = turnout['NA'] + ': ' + numberWithCommas(voters['NA']) + ' voted'; |
|
|
|
var g2r = new geo2rect.draw(); |
|
d3.json('ni.geojson', function(err, data){ |
|
var geojson = geo2rect.compute(data); |
|
g2r.config = config; |
|
g2r.data = geojson; |
|
g2r.svg = svg.append('g'); |
|
g2r.draw(); |
|
g2r.svg.selectAll('path') |
|
.attr("fill", function(d) { return color(turnout[d.properties.PC_NUM]); }) |
|
.attr("class", "areas") |
|
.on("mouseover", function(d) { |
|
div.transition().duration(500) |
|
.style("opacity", 0.75); |
|
div.text(name[d.properties.PC_NUM] + "\n\r 2017 Turnout: " + turnout[d.properties.PC_NUM] + "\n\rVoters: " + numberWithCommas(voters[d.properties.PC_NUM]) + "\n\rElectorate: " + numberWithCommas(electorate[d.properties.PC_NUM])) |
|
.style("left", (d3.event.pageX) + "px") |
|
.style("top", (d3.event.pageY -30) + "px"); |
|
}) |
|
.on("mouseout", function() { |
|
div.transition().duration(200) |
|
.style("opacity", 0); |
|
}); |
|
}); |
|
d3.select('body').append('button').text('Toggle squares').style('cursor', 'pointer').on('click', function(){ |
|
g2r.toggle(); |
|
g2r.draw(); |
|
console.log(g2r.mode); |
|
}); |
|
} |
|
|
|
function numberWithCommas(x) { |
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); |
|
} |
|
</script> |
|
</body> |
|
</html> |