Created by Christopher Manning
- Drag the nodes to interact with the diagram
- Use the mousewheel to adjust the charge on the nodes (zoom in/out)
Created by Christopher Manning
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.min.js"></script> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.min.js"></script> | |
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.min.js"></script> | |
<link rel="stylesheet" href="http://mbostock.github.com/d3/ex/colorbrewer.css"> | |
<style type="text/css"> | |
circle { | |
stroke: #EFEDF5; | |
fill: #EFEDF5; | |
} | |
line { | |
stroke: #EFEDF5; | |
pointer-events: none | |
} | |
path{ | |
stroke: black | |
} | |
</style> | |
</head> | |
<body> | |
<div id="chart"> | |
</div> | |
<script type="text/javascript"> | |
var w = 960, | |
h = 500, | |
links = [], | |
voronoiVertices = [], | |
color = d3.scale.quantize().domain([7000, 10000]).range(d3.range(2, 9)); | |
var vertices = d3.range(100).map(function(d) { return {x: d.x, y: d.y}; }) | |
var zoomChargeScale = d3.scale.quantize().domain([0, 100]).range(d3.range(-10000, 1).reverse()) | |
var zoom = d3.behavior.zoom() | |
.on("zoom", function(d,i) { force.charge(zoomChargeScale(d3.event.scale)).start() }); | |
var svg = d3.select("#chart") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h) | |
.attr("class", "Purples") | |
.call(zoom) | |
var force = self.force = d3.layout.force() | |
.charge(-300) | |
.size([w, h]) | |
.on("tick", update); | |
force.nodes(vertices).start(); | |
svg.selectAll("path") | |
.data(d3.geom.voronoi(vertices.map(function(o){return [o.x, o.y]}))) | |
.enter().append("path") | |
.attr("class", function(d, i) { return "q"+color(d3.geom.polygon(d).area())+"-9"; }) | |
.attr("d", function(d) { return "M" + d.join("L") + "Z"; }) | |
svg.selectAll("circle") | |
.data(vertices) | |
.enter().append("circle") | |
.call(force.drag) | |
.attr("r", 5) | |
var link = svg.selectAll("line") | |
function update(e) { | |
voronoiVertices = vertices.map(function(o){return [o.x, o.y, o]}) | |
svg.selectAll("circle") | |
.attr("cx", function(d) { return d.x; }) | |
.attr("cy", function(d) { return d.y; }); | |
svg.selectAll("path") | |
.data(d3.geom.voronoi(voronoiVertices)) | |
.attr("class", function(d, i) { return "q"+color(d3.geom.polygon(d).area())+"-9"; }) | |
.attr("d", function(d) { return "M" + d.join("L") + "Z"; }) | |
links = [] | |
d3.geom.delaunay(voronoiVertices).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 = link.data(links) | |
link.enter().append("line") | |
link.attr("x1", function(d) { return d.source[2].x; }) | |
.attr("y1", function(d) { return d.source[2].y; }) | |
.attr("x2", function(d) { return d.target[2].x; }) | |
.attr("y2", function(d) { return d.target[2].y; }) | |
link.exit().remove() | |
} | |
function edge(a, b) { | |
return { | |
source: a, | |
target: b | |
}; | |
} | |
</script> | |
</body> | |
</html> |