第47回衆議院議員総選挙 比例代表 北海道ブロックの結果です。
投票日:2014年12月14日
定数:8
データソース
xxxxxxxxxx
<meta charset="utf-8">
<style>
body, .axis text{
font: 14px sans-serif;
font-weight: bold;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path, .x.axis line {
display: none;
}
.y.axis text {
font-size: 10px;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
</style>
<body>
<form>
<label><input type="radio" name="mode" value="parties" checked>党派別得票数</label>
<label><input type="radio" name="mode" value="winners">当選人数</label>
</form>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
<script src="https://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 60};
var width = 900;
var height = 550;
var svg = d3.select('body')
.append('svg')
.attrs({
"width": width + margin.left + margin.right,
"height": height + margin.top + margin.bottom,
})
.append('g')
.attr('transform', 'translate('+margin.left+','+margin.top+')');
var x = d3.scaleBand()
.rangeRound([0, width])
.padding(.1);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var color = d3.scaleOrdinal(d3.schemeCategory10);
var partyColor = d3.scaleOrdinal(d3.schemeCategory10);
var quotient = function(d) { return d.votes / d.denominator; };
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var partyVotes;
var winners;
var pickTimer;
var seats = 8; // 定数
var simulateSeats = 20; // シミュレート定数
var partyKey = '政党';
var votesKey = '得票数';
d3.csv('result.csv', function(error, data){
if (error) { throw error; }
data.forEach(function(d){
d.party = d[partyKey];
d.votes = +d[votesKey],
d.denominator = 1;
d.winners = [];
});
data.sort(function(a,b){ return b[votesKey] - a[votesKey]; });
x.domain(data.map(function(d) { return d[partyKey]; }));
y.domain([0, d3.max(data.map(function(d){return d[votesKey];}))]);
console.log(data);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
// .call(d3.axisLeft(y).ticks(10).tickFormat(d3.formatPrefix('.1', 1e6)))
.append("text")
// .attr("transform", "rotate(-90)")
.attr("x", "-2em")
.attr("y", y(y.ticks(10).shift()))
.attr("dy", "2em")
.attr("text-anchor", "end")
.attr("fill", "#000")
.text(votesKey);
var g = svg.selectAll('.party')
.data(data)
.enter()
.append('g')
.attrs({
class: function(d){ return 'party ' + d.party; },
transform: function(d,i) { return 'translate('+ x(d.party) +', 0)' },
});
var partyVotesBg = g.selectAll('.party-votes-bg')
.data(function(d){return [d];})
.enter()
.append('rect')
.attrs({
class: 'party-votes-bg',
x: 0,
y: function(d){ return y(d.votes); },
width: x.bandwidth(),
height: function(d){ return y(0) - y(d.votes); },
fill: function(d){ return d3.hsl(partyColor(d.party)).brighter(); },
// fill: '#f0f0f0',
});
partyVotes = g.selectAll('.party-votes')
.data(function(d){return [d];})
.enter()
.append('rect')
.attrs({
class: 'party-votes',
x: 0,
y: function(d){ return y(d.votes); },
width: x.bandwidth(),
height: function(d){ return y(0) - y(d.votes); },
fill: function(d){ return partyColor(d.party); },
});
});
function getFirstPartyVotes() {
var maxVotes = 0;
var firstParty;
partyVotes.nodes().forEach(function(d){
var party = d3.select(d);
if (quotient(party.data()[0]) > maxVotes) {
firstParty = party;
maxVotes = quotient(party.data()[0]);
}
});
// console.log(firstParty, maxVotes);
return firstParty;
}
function pickWinner() {
var numWinner = d3.selectAll('.winners').nodes().length;
if (numWinner >= simulateSeats) {
return;
}
var firstPartyVotes = getFirstPartyVotes();
var party = d3.select(firstPartyVotes.node().parentNode);
var data = party.data()[0];
data.winners.push({
party: data.party,
votes: quotient(data),
order: numWinner+1,
});
var padding = 4;
var size = x.bandwidth() / 2 - padding * 2;
var winners = party.selectAll('.winners')
.data(function(d) {return d.winners; })
.enter()
.append('circle')
.attrs({
class: 'winners',
cx: function(d, i) { return padding + ((i % 2) + .5) * (size + padding); },
cy: function(d, i) { return padding + (Math.floor(i / 2) + .5) * (size + padding); },
r: 0,
stroke: '#fff',
'stroke-width': 2,
fill: function(d) {
if (numWinner < seats) {
return partyColor(d.party);
} else {
return 'rgba(0, 0, 0, 0.5)';
}
},
});
var timer = setTimeout(function(){
party.selectAll('.winners-order')
.data(function(d) {return d.winners; })
.enter()
.append('text')
.attrs({
class: 'winners-order',
x: function(d, i) { return padding + ((i % 2)+.5) * (size + padding); },
y: function(d, i) { return padding + (Math.floor(i / 2)+.6) * (size + padding); },
'text-anchor': 'middle',
'font-weight': 'bold',
fill: '#fff',
})
.text(function(d,i){return d.order;});
}, 250);
data.denominator++;
partyVotes
.data(function(d){ return [d]; })
.transition()
.duration(250)
.attrs({
y: function(d){ return y(quotient(d)); },
height: function(d){ return y(0) - y(quotient(d)); },
});
winners
.transition()
.duration(250)
.attrs({
r: size / 2,
});
pickTimer = setTimeout(function(){
pickWinner();
}, 400);
}
d3.selectAll("input").on("change", change);
function change() {
removeWinners();
switch(this.value) {
case 'parties':
transitionParties();
break;
case 'winners':
transitionParties();
setTimeout(function(){
pickWinner();
}, 1000);
break;
}
}
function removeWinners() {
clearTimeout(pickTimer);
d3.selectAll('.party').data().forEach(function(d){
d.denominator = 1;
});
svg.selectAll('.party').data().forEach(function(d){
d.winners = [];
});
var winners = svg.selectAll('.winners, .winners-order')
.data([]);
winners.exit().remove();
}
function transitionParties(callback) {
svg.selectAll('.votes')
.transition()
.duration(1000)
.attrs({
fill: '#f0f0f0',
});
partyVotes
.data(function(d){ return [d]; })
.transition()
.duration(1000)
.attrs({
width: x.bandwidth(),
y: function(d){ return y(quotient(d)); },
height: function(d){ return y(0) - y(quotient(d)); },
});
// .call(endall, callback);
}
function endall(transition, callback) {
if (!callback) callback = function(){};
if (transition.size() === 0) { callback() }
var n = 0;
transition
.each(function() { ++n; })
.each("end", function() { if (!--n) callback.apply(this, arguments); });
}
d3.select(self.frameElement).style("height", height + margin.top + margin.bottom + "px");
</script>
</body>
</html>
Modified http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js to a secure url
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-selection-multi.v0.4.min.js
https://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js