Skip to content

Instantly share code, notes, and snippets.

@sugi2000
Created October 26, 2016 02:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sugi2000/4f7432a55f24f83db9d406c624341540 to your computer and use it in GitHub Desktop.
Save sugi2000/4f7432a55f24f83db9d406c624341540 to your computer and use it in GitHub Desktop.
2015-01-11 Saga Gubernatorial Election
<!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>
市町 山口 祥義 樋渡 啓祐 島谷 幸宏 飯盛 良隆
佐賀市 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
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment