Created
October 26, 2016 02:53
-
-
Save sugi2000/4f7432a55f24f83db9d406c624341540 to your computer and use it in GitHub Desktop.
2015-01-11 Saga Gubernatorial Election
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://d3js.org/topojson.v1.min.js"></script> | |
<script src="http://d3js.org/queue.v1.min.js"></script> | |
<!-- | |
<script src="crossfilter.min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/dc/1.7.0/dc.min.js"></script> | |
<style src="http://cdnjs.cloudflare.com/ajax/libs/dc/1.7.0/dc.css" /> | |
--> | |
<style type="text/css"> | |
.label { | |
fill: #333; | |
font-size: 9px; | |
font-weight: bold; | |
text-anchor: middle; | |
} | |
svg text.legend, text.area-desc { | |
font-size: 11px; | |
font-weight: bold; | |
} | |
svg text.result { | |
font-size: 11px; | |
fill: #666; | |
} | |
svg path.map-path { | |
stroke: #fff; | |
} | |
svg text::selection { background: none; } | |
</style> | |
<body> | |
<script> | |
var width = 960, | |
height = 960; | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
//.append("g"); | |
var g = svg.append("g"); | |
//var mapfilepath = '/sugi2000/raw/f5cb73861573aab98187/japan0001.json'; | |
//var kencsvpath = '/sugi2000/raw/f5cb73861573aab98187/ken.csv'; | |
var mapfilepath = 'saga.topojson'; | |
var csvpath = 'saga.csv'; | |
var saga; | |
var votes = []; | |
var candidates = ['山口 祥義','樋渡 啓祐','島谷 幸宏','飯盛 良隆']; | |
var results = [182795, 143720, 32844, 6951]; | |
var resultSizes = []; | |
for (var i = 0; i < results.length; i++) { | |
resultSizes.push(Math.sqrt(results[i]) * 0.2); | |
} | |
/* | |
var shareColor = function(d, candidate) { | |
var total = | |
} | |
*/ | |
/* | |
var zoom = d3.behavior.zoom() | |
.scaleExtent([1, 8]) | |
.on("zoom", zoomed); | |
svg.call(zoom) | |
.call(zoom.event); | |
*/ | |
//var color = d3.scale.linear().range(["#ff4400", "#00cc66"]); | |
var color = d3.scale.linear().domain([0, 0.25, 0.5, 0.75, 1]).range(["#0000ee", "#00ee00", "#eeeeee", "#eeee00", "#ee0000"]); | |
var kenColor = function(d) { | |
if (d.properties.JCODE) { | |
return color(+d.properties.JCODE.substr(0, 2) / 47); | |
} else { | |
return d3.hsl(0, 0, 0) | |
} | |
}; | |
var color = d3.scale.ordinal() | |
.range(['hsla(0, 70%, 50%, 1.0)', 'hsla(210, 70%, 50%, 1.0)', 'hsla(60, 70%, 50%, 1.0)', 'hsla(90, 0%, 50%, 1.0)']); | |
g.selectAll('circle.legend') | |
.data(candidates) | |
.enter() | |
.append('circle') | |
.attr('class', 'legend') | |
.attr('cx', 100) | |
.attr('cy', function(d,i) { | |
var margin = 100; | |
for (var j = 0; j < i; j++) { | |
margin += resultSizes[j]; | |
} | |
return margin; | |
}) | |
.attr('r', 0) | |
// .attr('r', function(d,i) { return resultSizes[i] / 2; }) | |
.style('fill', function(d) { return color(d); }); | |
g.selectAll('circle.legend') | |
.transition() | |
.duration(2500) | |
.ease('elastic') | |
.delay(function(d,i){return i * 100;}) | |
.attr('r', function(d,i) { return resultSizes[i] / 2; }); | |
g.selectAll('text.legend') | |
.data(candidates) | |
.enter() | |
.append('text') | |
.attr('class', 'legend') | |
.attr('x', 150) | |
.attr('y', function(d,i) { | |
var margin = 100; | |
for (var j = 0; j < i; j++) { | |
margin += resultSizes[j]; | |
} | |
return margin; | |
}) | |
.text(function(d){ return d;}); | |
g.selectAll('text.result') | |
.data(results) | |
.enter() | |
.append('text') | |
.attr('class', 'result') | |
.attr('x', 150) | |
.attr('y', function(d,i) { | |
var margin = 100; | |
for (var j = 0; j < i; j++) { | |
margin += resultSizes[j]; | |
} | |
return margin + 12; | |
}) | |
.text(function(d){ return d.toLocaleString() + '票';}); | |
var areaColors = ['hsla(0, 70%, 90%, 1.0)', 'hsla(210, 70%, 90%, 1.0)']; | |
g.selectAll('rect.legend') | |
.data([0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,1,1,1,1]) | |
.enter() | |
.append('rect') | |
.attr('class', 'legend') | |
.attr('x', function(d, i) { return 50 + (i % 5) * 25; }) | |
.attr('y', function(d, i) { return 400 + Math.floor(i / 5) * 25; }) | |
.attr('width', 0) | |
.attr('height', 0) | |
// .attr('width', 25) | |
// .attr('height', 25) | |
.style('stroke', '#fff') | |
.style('fill', 'hsla(0, 0%, 50%, 1.0)'); | |
// .style('fill', function(d) { return areaColors[d]; }); | |
g.selectAll('rect.legend') | |
.transition() | |
.duration(500) | |
.delay(function(d,i){return i*50;}) | |
.attr({ | |
width: 25, | |
height: 25, | |
}) | |
.style('fill', function(d) { return areaColors[d]; }); | |
g.append('text') | |
.attr('class', 'area-desc') | |
.attr('x', 50) | |
.attr('y', 395) | |
.style('fill', color(0)) | |
.text('山口候補が最多得票の市町'); | |
g.append('text') | |
.attr('class', 'area-desc') | |
.attr('x', 50) | |
.attr('y', 515) | |
.style('fill', color(1)) | |
.text('樋渡候補が最多得票の市町'); | |
queue(1) | |
.defer(d3.json, mapfilepath) | |
.defer(d3.csv, csvpath) | |
.await(ready); | |
function ready(error, map, rows) { | |
if (error) { | |
return console.warn(error); | |
} | |
renderMap(map); | |
renderRows(rows); | |
updateMap(candidates[0]); | |
} | |
function renderMap(map) { | |
// setup map | |
saga = topojson.feature(map, map.objects.saga).features; | |
//console.log(saga); | |
updateMap(saga); | |
} | |
function updateMap(candidate) { | |
console.log(candidate); | |
var projection = d3.geo.mercator() | |
//.scale(1500) | |
.center([130,33.2]) | |
.scale(50000) | |
//.center(d3.geo.centroid(saga)) | |
.translate([width / 2, height / 2]); | |
var path = d3.geo.path().projection(projection); | |
var update = g.selectAll('path').data(saga) | |
var enter = update.enter(); | |
for (var i = 0; i < candidates.length; i++) { | |
update.attr('candidate-' + (i+1), function(d){ | |
return d.properties[candidates[i]]; | |
}); | |
} | |
enter | |
.append('path') | |
.attr('class', 'map-path') | |
.attr('d', path) | |
.attr('JCODE', function(d) {return d.properties.JCODE;}) | |
.attr('KENCODE', function(d) { | |
if (d.properties.JCODE) { | |
return d.properties.JCODE.substr(0, 2); | |
} else { | |
return 'null'; | |
} | |
}) | |
.attr('shikuchoson', function(d) { | |
return d.properties.SIKUCHOSON; | |
}) | |
.style('fill', '#eee') | |
.style('cursor', 'pointer') | |
/*.on('mouseover', function(){ | |
var self = d3.select(this); | |
self.style('fill', 'red'); | |
}) | |
.on('mouseout', function(){ | |
var self = d3.select(this); | |
self.transition() | |
.duration(300) | |
.style('fill', kenColor); | |
})*/ | |
; | |
update | |
.transition() | |
.duration(300) | |
.style('fill', function(d) { | |
if (+d.properties[candidates[0]] > +d.properties[candidates[1]]) { | |
return areaColors[0]; | |
} else { | |
return areaColors[1]; | |
} | |
color = d3.scale.linear().domain([0, 100000]).range(['#f8f8f8', '#ff0000']); | |
console.log(d.properties[candidate]); | |
return color(+d.properties[candidate]); | |
}); | |
var centroids = []; | |
for (var i = 0; i < saga.length; i++) { | |
centroids.push(path.centroid(saga[i])); | |
if (saga[i].properties.SIKUCHOSON === 'みやき町') { | |
centroids[centroids.length - 1][1] -= 20; // offset y | |
} | |
} | |
console.log(centroids); | |
g.selectAll('text.label') | |
.data(saga) | |
.enter() | |
.append('text') | |
.attr('class', function(d) { return 'label ' + d.properties.JCODE; }) | |
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; }) | |
.attr('dy', function(d) { | |
if (d.properties.SIKUCHOSON === 'みやき町') { | |
return '-2em'; | |
} else { | |
return '.35em'; | |
} | |
}) | |
.attr('pointer-events', 'none') | |
.text(function(d) { return d.properties.SIKUCHOSON; }); | |
for (var i = 0; i < votes.length; i++) { | |
var color = d3.scale.ordinal() | |
.range(['hsla(0, 70%, 50%, 0.75)', 'hsla(210, 70%, 50%, 0.75)', 'hsla(60, 70%, 50%, 0.75)', 'hsla(90, 0%, 50%, 0.75)']); | |
var entries = d3.entries(votes[i]); | |
entries.shift(); // remove first town-name | |
console.log(entries); | |
var totalVotes = 0; | |
for (var j = 0; j < entries.length; j++) { | |
totalVotes += +entries[j].value; | |
} | |
var radius = Math.sqrt(totalVotes) * 0.25; | |
var arc = d3.svg.arc() | |
.outerRadius(radius) | |
.innerRadius(radius * 0.5); | |
var pie = d3.layout.pie() | |
.sort(null) | |
.value(function(d) { return +d.value; }); | |
var garc = g.selectAll('g.arc-' + i) | |
.data(pie(entries)) | |
.enter() | |
.append('g') | |
.attr('class', function(d) { return "arc arc-" + i; }) | |
.attr("transform", 'translate(' + centroids[i] + ')'); | |
garc.append('path') | |
.attr('d', arc) | |
.style('fill', function(d) { return color(+d.value); }); | |
} | |
} | |
function renderRows(rows) { | |
votes = rows; | |
console.log(votes); | |
// add properties | |
for (var i = 0; i < rows.length; i++) { | |
//console.log(rows[i].市町, saga[i].properties.SIKUCHOSON); | |
if (rows[i]['市町'] === saga[i].properties.SIKUCHOSON) { | |
for (var j = 0; j < candidates.length; j++) { | |
saga[i].properties[candidates[j]] = rows[i][candidates[j]]; | |
} | |
} | |
} | |
} | |
function zoomed() { | |
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); | |
} | |
d3.select(self.frameElement).style("height", height + "px"); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
市町 | 山口 祥義 | 樋渡 啓祐 | 島谷 幸宏 | 飯盛 良隆 | |
---|---|---|---|---|---|
佐賀市 | 55085 | 33807 | 10543 | 1824 | |
唐津市 | 20108 | 23193 | 6216 | 1096 | |
鳥栖市 | 8790 | 9554 | 3490 | 778 | |
多久市 | 4991 | 4245 | 581 | 146 | |
伊万里市 | 11888 | 10180 | 1798 | 360 | |
武雄市 | 10415 | 15934 | 1196 | 220 | |
鹿島市 | 8767 | 4221 | 724 | 153 | |
小城市 | 11480 | 6180 | 1342 | 719 | |
嬉野市 | 6245 | 5573 | 651 | 154 | |
神埼市 | 8187 | 5004 | 1588 | 345 | |
吉野ヶ里町 | 3194 | 2553 | 656 | 209 | |
基山町 | 2374 | 3276 | 1102 | 174 | |
上峰町 | 1986 | 1420 | 295 | 92 | |
みやき町 | 4166 | 5079 | 1042 | 279 | |
玄海町 | 1707 | 902 | 113 | 44 | |
有田町 | 3784 | 5480 | 627 | 154 | |
大町町 | 1737 | 1592 | 220 | 37 | |
江北町 | 3629 | 1251 | 179 | 41 | |
白石町 | 11848 | 2225 | 316 | 67 | |
太良町 | 2414 | 2051 | 165 | 59 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment