Skip to content

Instantly share code, notes, and snippets.

@milkbread
Forked from mbostock/.block
Last active August 29, 2015 13:58
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 milkbread/10129030 to your computer and use it in GitHub Desktop.
Save milkbread/10129030 to your computer and use it in GitHub Desktop.
German states in a forced layout

Click and drag to move states around.

This is an adapted version of the impressive example of Force-Directed States of America presented by Mike Bostock!

This example shows, how to make the same cool stuff with german state polygons.

I simply changed:

  • data input - de.json

  • projection - d3.geo.mercator()

    • scale: 2000
    • translate: [width / 2, height / 2]
    • center: [10.5, 51.35]
  • 'linkDistance' - multiply with 1.1

  • display link above the polygons

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.
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" href="styles.css" />
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
</head>
<body>
<div id="container"></div>
<div class="brws_info"></div>
<script>
// if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1) {
// d3.select(".brws_info")
// .text("I appreciate for the bad performance in Firefox...it's nice but not the best browser for playing with SVG!");
// }
var width = 400,
height = 500;
var path = d3.geo.path(),
force = d3.layout.force().size([width, height]),
projection = d3.geo.mercator()
.center([10.5, 51.35])
.scale(2000)
.translate([width / 2, height / 2]);
path.projection(projection);
var div = d3.select("#container")
.style("opacity", 0);
var svg = div.append("svg")
.attr("width", width)
.attr("height", height);
d3.json("de.json", function(error, de) {
var states = topojson.feature(de, de.objects.subunits),
nodes = [],
links = [];
states.features.forEach(function(d, i) {
var centroid = path.centroid(d);
if (centroid.some(isNaN)) return;
centroid.x = centroid[0];
centroid.y = centroid[1];
centroid.feature = d;
nodes.push(centroid);
});
d3.geom.voronoi().links(nodes).forEach(function(link) {
var dx = link.source.x - link.target.x,
dy = link.source.y - link.target.y;
link.distance = Math.sqrt(dx * dx + dy * dy);
links.push(link);
});
force
.gravity(0)
.nodes(nodes)
.links(links)
.linkDistance(function(d) { return d.distance * 1.1; })
.start();
// **Attributes**
var opacityCache,
duration = 600;
var drag = force.drag();
var node = svg.selectAll("g")
.data(nodes)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + -d.x + "," + -d.y + ")"; })
.call(drag)
.append("path")
.attr("class", "polygon")
.attr("id", function(d) {return d.feature.properties.name;})
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.attr("d", function(d) { return path(d.feature.geometry); })
.on("mousedown", function(){
opacityCache = d3.select(this).style("fill-opacity");
d3.select(this)
.classed("draged", true)
.transition().duration(duration).style("fill-opacity", 1);
})
drag.on("dragend", function(){
d3.select('.draged')
.classed("draged", false)
.transition().duration(duration).style("fill-opacity", opacityCache);
});
var link = svg.selectAll("line")
.data(links)
.enter().append("line")
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
force.on("tick", function(e) {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
div.transition().duration(2000).style("opacity", 1);
});
</script>
</body>
</html>
svg {
/*Trick to have the svg-container centered*/
margin-left: auto;
margin-right: auto;
display: block;
border-radius:25px;
/* background-color: #eee;
border: dashed 1px rgba(0, 0, 0, .1);
box-shadow: 10px 10px 5px #888;
*/}
.polygon {
fill: #40744C;
fill-opacity: .5;
stroke: #aaa;
stroke-width: 1px;
stroke-opacity: .7;
cursor: pointer;
}
line {
stroke: #fff;
stroke-dasharray: 5,5;
}
/*.brws_info {
text-align: center;
color: #f00;
}
*/
#Nordrhein-Westfalen { fill: #a6cee3; }
#Baden-Württemberg { fill: #1f78b4; }
#Hessen { fill: #b2df8a; }
#Bremen { fill: #33a02c; }
#Niedersachsen { fill: #fb9a99; }
#Thüringen { fill: #e31a1c; }
#Hamburg { fill: #fdbf6f; }
#Schleswig-Holstein { fill: #ff7f00; }
#Rheinland-Pfalz { fill: #cab2d6; }
#Saarland { fill: #b15928; }
#Bayern { fill: #ffff99; }
#Berlin { fill: #6a3d9a; }
#Sachsen-Anhalt { fill: #d9d9d9; }
#Sachsen { fill: #ccebc5; }
#Brandenburg { fill: #fdb462; }
#Mecklenburg-Vorpommern { fill: #bebada; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment