Skip to content

Instantly share code, notes, and snippets.

@toja
Last active September 19, 2017 21:33
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 toja/df3a73c597304c58f728ce9d7f70a876 to your computer and use it in GitHub Desktop.
Save toja/df3a73c597304c58f728ce9d7f70a876 to your computer and use it in GitHub Desktop.
Leipzig OT - BTW2013
license: gpl-3.0
height: 640
border: no

Results of the parliamentary elections (for the Bundestag) 2013 in Leipzig.

Source: Stadt Leipzig

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.land {
fill: #ddd;
}
.border {
fill: none;
stroke-linejoin: round;
stroke-linecap: round;
}
.ortsteil {
stroke: #666;
stroke-width: 0.5px;
stroke-dasharray: 1 3;
}
.bezirk {
stroke: #fff;
stroke-width: 2px;
}
.wk {
stroke: #999;
stroke-width: 2px;
}
.bubble {
fill: brown;
opacity: .8;
stroke: #333;
stroke-width: .5px;
}
.bubble :hover {
stroke: #aaa;
}
.legend circle {
fill: none;
stroke: #ccc;
}
.legend text {
fill: #777;
font: 10px sans-serif;
text-anchor: middle;
}
</style>
<body>
<div id="option">
<select onchange="update(this.value)">
<option value="CDU" selected="selected">CDU</option>
<option value="SPD">SPD</option>
<option value="LIN">Die Linke</option>
<option value="GRU">Gruene</option>
<option value="AFD">AfD</option>
<option value="FDP">FDP</option>
<option value="NPD">NPD</option>
</select>
</div>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v2.min.js"></script>
<script>
var radius = d3.scale.sqrt()
.domain([0, 25000])
.range([0, 28]);
var color = d3.scale.linear()
.domain([0, 40])
.range(["#fff", "#00ff00"]);
var colors = {CDU: "#333", SPD: "#FF0000", LIN: "#E3000F", GRU: '#64A12D', AFD: '#009ee0', FDP: '#ffed00', NPD: '#8b4513'};
var maximum = {CDU: 40.66, SPD: 26.17, LIN: 30.43, GRU: 27.06, AFD: 13.17, FDP: 6.16, NPD: 6.22};
var formatNumber = d3.format(",.0f");
var width = 600,
height = 600,
padding = 0;
var path = d3.geo.path()
.projection(null);
var force = d3.layout.force()
.charge(0)
.gravity(0)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var legend = svg.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + (width - 50) + "," + (height - 20) + ")")
.selectAll("g")
.data([25000, 10000, 3000])
.enter().append("g");
legend.append("circle")
.attr("cy", function(d) { return -radius(d); })
.attr("r", radius);
legend.append("text")
.attr("y", function(d) { return -2 * radius(d); })
.attr("dy", "1.2em")
.text(d3.format("2s"));
d3.json("ortsteile.json", function(error, le) {
if (error)
return console.error(error);
var ot = topojson.feature(le, le.objects.ot).features;
var nodes = ot.map (function(d) {
var point = path.centroid(d);
return {
x: point[0], y: point[1],
x0: point[0], y0: point[1],
r: radius(d.properties.POP),
n: d.properties.NAME,
p: {
LIN: d.properties.LIN,
SPD: d.properties.SPD,
CDU: d.properties.CDU,
GRU: d.properties.GRU,
FDP: d.properties.FDP,
AFD: d.properties.AFD,
NPD: d.properties.NPD
}
}
});
svg.append("g")
.attr("class", "ot")
.selectAll(".ortsteile")
.data(ot)
.enter().append("path")
.attr("d", path)
.attr("fill", "#f6f4f2");
svg.append("path")
.datum(topojson.mesh(le, le.objects.ot, function(a, b) { return a !== b; }))
.attr("class", "border ortsteil")
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(le, le.objects.bz, function(a, b) { return a !== b; }))
.attr("class", "border bezirk")
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(le, le.objects.wk, function(a, b) { return a !== b; }))
.attr("class", "border wk")
.attr("d", path);
force
.nodes(nodes)
.on("tick", tick)
.start()
var bubbles = svg.append("g")
.attr("class", "bubble");
var node = bubbles.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", function(d) { return d.r; });
node.append("title")
.text(function(d) { return d.n + "\nCDU: " + d.p.CDU; });
update('CDU');
function tick(e) {
node.each(gravity(e.alpha * .1))
.each(collide(.5))
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
function gravity(k) {
return function(d) {
d.x += (d.x0 - d.x) * k;
d.y += (d.y0 - d.y) * k;
};
}
function collide(k) {
var q = d3.geom.quadtree(nodes);
return function(node) {
var nr = node.r + padding,
nx1 = node.x - nr,
nx2 = node.x + nr,
ny1 = node.y - nr,
ny2 = node.y + nr;
q.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = x * x + y * y,
r = nr + quad.point.r;
if (l < r * r) {
l = ((l = Math.sqrt(l)) - r) / l * k;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
});
var setColor = function (partei) {
color
.domain([0, maximum[partei]])
.range(["#fff", colors[partei]]);
}
var update = function (partei) {
setColor(partei);
// achte auf korrekte Auswahl!
svg.select(".bubble")
.selectAll("circle")
.transition()
.duration(1000)
.attr("fill", function (d) { return color(d.p[partei]); })
.selectAll("title")
.text (function(d){ return d.n + " - " + d.p[partei] + "%"; });
}
</script>
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