|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<title>California fractured by congressional district</title> |
|
<style> |
|
path.district { |
|
stroke: #fff; |
|
stroke-width: 1px; |
|
stroke-opacity: 0.3; |
|
} |
|
text { |
|
font-size: 24px; |
|
} |
|
</style> |
|
<svg width="960" height="500"></svg> |
|
<script src="http://d3js.org/d3.v2.js"></script> |
|
<script> |
|
var selected_district = "CA"; |
|
|
|
var svg = d3.select("svg"); |
|
|
|
var color = d3.scale.linear() |
|
.domain([0,0.5,1]) |
|
.range(["#d7191c", "#ddd", "#2c7bb6"]) |
|
.interpolate(d3.interpolateLab); |
|
|
|
var projection = d3.geo.azimuthal() |
|
.mode("equidistant") |
|
.origin([-118, 37]) |
|
.scale(2400) |
|
.translate([480, 260]); |
|
|
|
var force = d3.layout.force() |
|
.size([960, 500]); |
|
|
|
var nodes = [], |
|
links = []; |
|
|
|
var path = d3.geo.path() |
|
.projection(projection); |
|
|
|
d3.json("113-ca.json", function(collection) { |
|
// visible districts |
|
var selected = collection.features |
|
.filter(function(district) { |
|
return district.properties.UID.indexOf(selected_district) > -1; |
|
}) |
|
|
|
selected |
|
.forEach(function(d) { |
|
centroid = path.centroid(d); |
|
centroid.x = centroid[0]; |
|
centroid.y = centroid[1]; |
|
centroid.feature = d; |
|
centroid.tract_data = Math.random(); |
|
nodes.push(centroid); |
|
}); |
|
|
|
d3.geom.delaunay(nodes).forEach(function(d) { |
|
links.push(edge(d[0], d[1])); |
|
links.push(edge(d[1], d[2])); |
|
links.push(edge(d[2], d[0])); |
|
}); |
|
|
|
/* |
|
link = svg.selectAll("line") |
|
.data(links) |
|
.enter().append("svg: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; }) |
|
.attr("stroke", "#777") |
|
.attr("stroke-opacity", "0.3") |
|
.attr("stroke-width", "1") |
|
*/ |
|
|
|
node = svg.selectAll("g") |
|
.data(nodes) |
|
.enter().append("svg:g") |
|
.attr("transform", function(d) { return "translate(" + (-d.x) + "," + (-d.y) + ")"}) |
|
.append("path") |
|
.attr("class", "district") |
|
.attr("fill", function(d) { return color(d.tract_data); }) |
|
.attr("transform", function(d) { return "translate(" + (d.x) + "," + (d.y) + ")"}) |
|
.attr("d", function(d) { return path(d.feature) }) |
|
|
|
svg.append("text") |
|
.attr({ |
|
"id": "district", |
|
"x": 220, |
|
"y": 420, |
|
}); |
|
|
|
var tick_count = 0; |
|
|
|
force |
|
.gravity(0.0) |
|
.nodes(nodes) |
|
.links(links) |
|
.linkDistance( function(d) { return d.distance }) |
|
.charge(-0.6) |
|
.friction(0.4) |
|
.theta(0.9) |
|
|
|
force.on("tick", function() { |
|
/* |
|
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 + ")"}); |
|
}); |
|
|
|
setTimeout(force.start, 1500) ; |
|
}); |
|
|
|
function edge(a,b) { |
|
var dx = a.x - b.x, |
|
dy = a.y - b.y, |
|
diff = 22 * Math.abs(a.tract_data - b.tract_data); |
|
|
|
var distance = Math.sqrt(dx * dx + dy * dy) + diff; |
|
return { |
|
source: a, |
|
target: b, |
|
distance: distance |
|
} |
|
}; |
|
</script> |