Last active
August 29, 2015 14:18
-
-
Save ginseng666/08e5776ace8e52ac9c45 to your computer and use it in GitHub Desktop.
Slope Chart: Election Results, Lower Austria, 1995 vs. 2015
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
number | name | eligible_voters_1995 | eligible_voters_2015 | invalid_votes_1995 | invalid_votes_2015 | valid_votes_1995 | valid_votes_2015 | seats_to_fill_1995 | seats_to_fill_2015 | oevp_votes_1995 | oevp_votes_2015 | oevp_seats_1995 | oevp_seats_2015 | spoe_votes_1995 | spoe_votes_2015 | spoe_seats_1995 | spoe_seats_2015 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
30401 | Wiener Neustadt | 31099 | 36431 | 536 | 290 | 20834 | 20619 | 40 | 40 | 4419 | 6998 | 9 | 14 | 10355 | 8310 | 22 | 17 | |
30501 | Allhartsberg | 1325 | 1805 | 40 | 42 | 1132 | 1419 | 19 | 21 | 775 | 1154 | 14 | 17 | 198 | 265 | 3 | 4 | |
30502 | Amstetten | 18538 | 20428 | 436 | 330 | 13360 | 11432 | 41 | 41 | 2938 | 2812 | 9 | 10 | 5944 | 5310 | 19 | 20 | |
30503 | Ardagger | 2379 | 2985 | 54 | 65 | 1957 | 2294 | 23 | 23 | 1332 | 1659 | 16 | 17 | 242 | 279 | 3 | 3 | |
30504 | Aschbach-Markt | 2585 | 3206 | 54 | 31 | 2048 | 2320 | 23 | 23 | 1426 | 1142 | 16 | 12 | 350 | 276 | 4 | 2 | |
30506 | Behamberg | 2219 | 2918 | 65 | 36 | 1821 | 2029 | 21 | 23 | 1194 | 1189 | 14 | 14 | 457 | 564 | 5 | 6 | |
30507 | Biberbach | 1519 | 1979 | 16 | 38 | 1261 | 1490 | 19 | 21 | 911 | 1047 | 14 | 15 | 259 | 199 | 4 | 3 | |
30508 | Ennsdorf | 1755 | 2551 | 22 | 22 | 1368 | 1628 | 21 | 21 | 187 | 438 | 3 | 6 | 890 | 1002 | 14 | 13 | |
30509 | Ernsthofen | 1636 | 1985 | 32 | 18 | 1366 | 1470 | 21 | 21 | 753 | 795 | 12 | 12 | 613 | 613 | 9 | 9 | |
30510 | Ertl | 822 | 1115 | 13 | 19 | 666 | 828 | 19 | 19 | 624 | 737 | 18 | 17 | 42 | 91 | 1 | 2 | |
30511 | Euratsfeld | 1616 | 2197 | 47 | 48 | 1391 | 1820 | 21 | 21 | 1126 | 1341 | 18 | 16 | 155 | 257 | 2 | 3 | |
30512 | Ferschnitz | 1096 | 1541 | 13 | 26 | 979 | 1276 | 19 | 19 | 810 | 958 | 17 | 15 | 122 | 218 | 2 | 3 | |
30514 | Haag | 4102 | 4901 | 90 | 44 | 3073 | 3168 | 29 | 29 | 1374 | 1631 | 14 | 16 | 657 | 665 | 6 | 6 | |
30515 | Haidershofen | 2546 | 3139 | 42 | 47 | 1962 | 2213 | 23 | 23 | 1170 | 1553 | 14 | 17 | 577 | 389 | 7 | 4 | |
30516 | Hollenstein an der Ybbs | 1589 | 1819 | 28 | 54 | 1375 | 1443 | 19 | 19 | 562 | 686 | 8 | 9 | 751 | 757 | 11 | 10 | |
30517 | Kematen an der Ybbs | 2001 | 2278 | 79 | 49 | 1625 | 1620 | 21 | 21 | 823 | 1013 | 11 | 13 | 802 | 607 | 10 | 8 | |
30520 | Neuhofen an der Ybbs | 1797 | 2521 | 34 | 68 | 1541 | 1692 | 21 | 21 | 1126 | 1120 | 16 | 14 | 164 | 265 | 2 | 3 | |
30521 | Neustadtl an der Donau | 1880 | 2027 | 36 | 30 | 1512 | 1603 | 21 | 21 | 1122 | 1205 | 16 | 16 | 390 | 241 | 5 | 3 | |
30522 | Oed-oehling | 1107 | 1612 | 30 | 31 | 852 | 1151 | 19 | 19 | 595 | 896 | 14 | 15 | 201 | 139 | 4 | 2 | |
30524 | Opponitz | 805 | 812 | 20 | 17 | 673 | 657 | 19 | 15 | 225 | 414 | 6 | 10 | 226 | 147 | 7 | 3 | |
30526 | St. Georgen am Reith | 500 | 622 | 13 | 11 | 420 | 579 | 15 | 15 | 165 | 284 | 6 | 7 | 255 | 295 | 9 | 8 | |
30527 | St. Georgen am Ybbsfelde | 1743 | 2439 | 44 | 47 | 1461 | 1715 | 21 | 21 | 892 | 1043 | 13 | 13 | 386 | 426 | 6 | 5 | |
30529 | St. Pantaleon-Erla | 1801 | 2329 | 35 | 60 | 1535 | 1651 | 21 | 21 | 432 | 729 | 6 | 9 | 1018 | 742 | 14 | 10 | |
30530 | St. Peter in der Au | 3561 | 4536 | 61 | 89 | 2890 | 3197 | 25 | 29 | 2110 | 2129 | 19 | 20 | 450 | 688 | 4 | 6 | |
30531 | St. Valentin | 7219 | 8293 | 164 | 139 | 5415 | 4857 | 33 | 33 | 1496 | 1242 | 9 | 8 | 2634 | 2952 | 17 | 21 | |
30532 | Seitenstetten | 2350 | 2875 | 30 | 58 | 1907 | 2095 | 21 | 23 | 1246 | 1301 | 15 | 15 | 237 | 501 | 2 | 5 | |
30533 | Sonntagberg | 3566 | 3644 | 102 | 47 | 2835 | 2752 | 25 | 23 | 793 | 1607 | 7 | 14 | 1661 | 921 | 15 | 8 | |
30534 | Strengberg | 1633 | 1776 | 32 | 48 | 1258 | 1257 | 21 | 21 | 838 | 846 | 15 | 15 | 313 | 277 | 5 | 4 | |
30536 | Viehdorf | 905 | 1195 | 23 | 22 | 775 | 952 | 19 | 19 | 569 | 831 | 15 | 17 | 140 | 121 | 3 | 2 |
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> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Election Results, Lower Austria, 1995 vs. 2015</title> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<style> | |
text | |
{ | |
font-size:10pt; | |
} | |
line | |
{ | |
stroke:black; | |
} | |
.heading | |
{ | |
font-size:14pt; | |
fill:steelblue; | |
} | |
label | |
{ | |
color:steelblue; | |
font-size:14pt; | |
padding:0.2em; | |
} | |
label.checked | |
{ | |
background-color:#efefef; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="switch"></div> | |
<div id="chart"></div> | |
<script type="text/javascript"> | |
var width=800; | |
var height=700; | |
var data, datastore, res95, res15, pos, line; | |
var parties=["oevp","spoe"]; //parties for the radio buttons | |
var check=0; | |
var svg=d3.select("#chart").append("svg").attr("width",width).attr("height",height); | |
d3.csv("data.csv", function(data) | |
{ | |
for (i=0;i<data.length;i++) | |
{ | |
data[i].oevp_95=+(data[i].oevp_votes_1995/data[i].valid_votes_1995*100).toFixed(2); //calculating the percentages | |
data[i].oevp_15=+(data[i].oevp_votes_2015/data[i].valid_votes_2015*100).toFixed(2); | |
data[i].spoe_95=+(data[i].spoe_votes_1995/data[i].valid_votes_1995*100).toFixed(2); | |
data[i].spoe_15=+(data[i].spoe_votes_2015/data[i].valid_votes_2015*100).toFixed(2); | |
data[i].idname=data[i].name.replace(/[\.,\s+]/g, ''); //to avoid spaces and dots in the class of the element for proper selection | |
} | |
d3.select("#switch") | |
.selectAll("input") | |
.data(parties) | |
.enter() | |
.append("label") | |
.attr("id",function(d){return d;}) | |
.classed("checked", function(d,i){return i===check ? true : false;}) | |
.text(function(d){return d.toUpperCase();}) | |
.append("input") | |
.attr("type","radio") | |
.attr("name","party") | |
.attr("value",function(d){return d;}) | |
.attr("onChange",function(d){return "draw('"+d+"')";}) | |
.property("checked", function(d, i) {return (i===check)}); //add the radio buttons, depending on the number of available parties | |
svg | |
.append("text") | |
.attr("x", 200) | |
.attr("y",20) | |
.attr("text-anchor", "end") | |
.attr("class","heading") | |
.text("1995"); | |
svg | |
.append("text") | |
.attr("x", 500) | |
.attr("y",20) | |
.attr("text-anchor", "start") | |
.attr("class","heading") | |
.text("2015"); | |
datastore=data; //somehow the data-variable is undefined in the draw-function below, not sure why | |
pos=(height-30)/datastore.length; //fixed multiplier for the y-positions (might be easier done with d3.axis) | |
datastore.sort(function(a,b){return d3.descending(a.oevp_95,b.oevp_95);}) //make the left side | |
res95=svg.selectAll(".res95").data(datastore).enter().append("text"); | |
res95 | |
.attr("x",200) | |
.attr("y",function(d,i){d.pos95=45+i*pos; return 50+i*pos;}) | |
.attr("text-anchor","end") | |
.text(function(d){return d.name+": "+d.oevp_95;}) | |
.attr("class",function(d){return d.idname;}) | |
.on("mouseover",function(){d3.selectAll("text."+this.className.baseVal) | |
.style("font-weight","bold") | |
.style("fill","red"); | |
d3.selectAll("line."+this.className.baseVal).style("stroke","red");}) | |
.on("mouseout",function(){d3.selectAll("text."+this.className.baseVal) | |
.style("font-weight","normal") | |
.style("fill","black"); | |
d3.selectAll("line."+this.className.baseVal).style("stroke","black");}); //different selection for text and line, because changing the stroke-value would also affect the text | |
datastore.sort(function(a,b){return d3.descending(a.oevp_15,b.oevp_15);}) //make the right side | |
res15=svg.selectAll(".res15").data(datastore).enter().append("text"); | |
res15 | |
.attr("x",500) | |
.attr("y",function(d,i){d.pos15=45+i*pos; return 50+i*pos;}) | |
.attr("text-anchor","start") | |
.text(function(d){return d.name+": "+d.oevp_15;}) | |
.attr("class",function(d){return d.idname;}) | |
.on("mouseover",function(){d3.selectAll("text."+this.className.baseVal) | |
.style("font-weight","bold") | |
.style("fill","red"); | |
d3.selectAll("line."+this.className.baseVal).style("stroke","red");}) | |
.on("mouseout",function(){d3.selectAll("text."+this.className.baseVal) | |
.style("font-weight","normal") | |
.style("fill","black"); | |
d3.selectAll("line."+this.className.baseVal).style("stroke","black");}); | |
line=svg.selectAll("line").data(datastore).enter().append("line"); //draw a line between left and right | |
line | |
.attr("x1",210) | |
.attr("x2",490) | |
.attr("y1",function(d,i){return d.pos95;}) | |
.attr("y2",function(d){return d.pos15;}) | |
.attr("class",function(d){return d.idname;}); | |
}); | |
function draw(choice) | |
{ | |
d3.selectAll("label").classed("checked",false); | |
d3.select("#"+choice).classed("checked",true); | |
party_95=choice+"_95"; //construct the name of the object property based on the radio button | |
party_15=choice+"_15"; //construct the name of the object property based on the radio button | |
datastore.sort(function(a,b){return d3.descending(a[party_95],b[party_95]);}); | |
for (i=0; i<datastore.length;i++) //this part seems necessary to get an updated index for the list - not very elegant, but i have not found a better solution yet | |
{ | |
datastore[i].pos95=i; | |
} | |
datastore.sort(function(a,b){return d3.descending(a[party_15],b[party_15]);}); //the same for the right side | |
for (i=0; i<datastore.length;i++) | |
{ | |
datastore[i].pos15=i; | |
} | |
res95 | |
.transition() | |
.duration(500) | |
.attr("y",function(d){return (50+d.pos95*pos);}) | |
.text(function(d){return d.name+": "+d[party_95];}); | |
res15 | |
.transition() | |
.duration(500) | |
.attr("y",function(d){return (50+d.pos15*pos);}) | |
.text(function(d){return d.name+": "+d[party_15];}); | |
line | |
.transition() | |
.duration(500) | |
.attr("y1",function(d){return 45+d.pos95*pos;}) | |
.attr("y2",function(d){return 45+d.pos15*pos;}); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment