|
<!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> |