Instantly share code, notes, and snippets.

What would you like to do?
Voronoi Diagram with Force Directed Nodes and Delaunay Links
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<script src=""></script>
<style type="text/css">
.Purples .q0-3{fill:rgb(239,237,245)}
.Purples .q1-3{fill:rgb(188,189,220)}
.Purples .q2-3{fill:rgb(117,107,177)}
.Purples .q0-4{fill:rgb(242,240,247)}
.Purples .q1-4{fill:rgb(203,201,226)}
.Purples .q2-4{fill:rgb(158,154,200)}
.Purples .q3-4{fill:rgb(106,81,163)}
.Purples .q0-5{fill:rgb(242,240,247)}
.Purples .q1-5{fill:rgb(203,201,226)}
.Purples .q2-5{fill:rgb(158,154,200)}
.Purples .q3-5{fill:rgb(117,107,177)}
.Purples .q4-5{fill:rgb(84,39,143)}
.Purples .q0-6{fill:rgb(242,240,247)}
.Purples .q1-6{fill:rgb(218,218,235)}
.Purples .q2-6{fill:rgb(188,189,220)}
.Purples .q3-6{fill:rgb(158,154,200)}
.Purples .q4-6{fill:rgb(117,107,177)}
.Purples .q5-6{fill:rgb(84,39,143)}
.Purples .q0-7{fill:rgb(242,240,247)}
.Purples .q1-7{fill:rgb(218,218,235)}
.Purples .q2-7{fill:rgb(188,189,220)}
.Purples .q3-7{fill:rgb(158,154,200)}
.Purples .q4-7{fill:rgb(128,125,186)}
.Purples .q5-7{fill:rgb(106,81,163)}
.Purples .q6-7{fill:rgb(74,20,134)}
.Purples .q0-8{fill:rgb(252,251,253)}
.Purples .q1-8{fill:rgb(239,237,245)}
.Purples .q2-8{fill:rgb(218,218,235)}
.Purples .q3-8{fill:rgb(188,189,220)}
.Purples .q4-8{fill:rgb(158,154,200)}
.Purples .q5-8{fill:rgb(128,125,186)}
.Purples .q6-8{fill:rgb(106,81,163)}
.Purples .q7-8{fill:rgb(74,20,134)}
.Purples .q0-9{fill:rgb(252,251,253)}
.Purples .q1-9{fill:rgb(239,237,245)}
.Purples .q2-9{fill:rgb(218,218,235)}
.Purples .q3-9{fill:rgb(188,189,220)}
.Purples .q4-9{fill:rgb(158,154,200)}
.Purples .q5-9{fill:rgb(128,125,186)}
.Purples .q6-9{fill:rgb(106,81,163)}
.Purples .q7-9{fill:rgb(84,39,143)}
.Purples .q8-9{fill:rgb(63,0,125)}
circle {
stroke: #EFEDF5;
fill: #EFEDF5;
line {
stroke: #EFEDF5;
pointer-events: none
stroke: black
<div id="chart">
<script type="text/javascript">
var w = 960,
h = 500,
links = [],
voronoiVertices = [],
color = d3.scale.quantize().domain([7000, 10000]).range(d3.range(2, 9));
var numVertices = 150;
var vertices = d3.range(numVertices).map(function(d) { return {x: d.x, y: d.y}; })
var prevEventScale = 1;
var zoom = d3.behavior.zoom().on("zoom", function(d,i) {
if (d3.event.scale > prevEventScale) {
vertices.push(function(d) { return {x: d.x, y: d.y}; })
} else if (vertices.length > 2) {
prevEventScale = d3.event.scale;
var svg ="#chart")
.attr("width", w)
.attr("height", h)
.attr("class", "Purples")
var force = self.force = d3.layout.force()
.size([w, h])
.on("tick", update);
var circle = svg.selectAll("circle");
var path = svg.selectAll("path");
var link = svg.selectAll("line");
function update(e) {
voronoiVertices ={return [o.x, o.y, o]})
path =
path.enter().insert("path", "path") //group all the path elements first so they have the lowest z-order
.attr("class", function(d, i) { return "q"+color(d3.geom.polygon(d).area())+"-9"; })
.attr("d", function(d) { return "M" + d.join("L") + "Z"; });
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"; });
circle =
.attr("r", 0)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.transition().duration(1000).attr("r", 5);
circle.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
circle.exit().transition().attr("r", 0).remove();
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.attr("x1", function(d) { return d.source[2].x; })
.attr("y1", function(d) { return d.source[2].y; })
.attr("x2", function(d) { return[2].x; })
.attr("y2", function(d) { return[2].y; })
function edge(a, b) {
return {
source: a,
target: b

This comment has been minimized.

davefaliskie commented Jun 13, 2015

Is there a way to make each individual box a clickable link? Could you use JSON data to bind to each box? If so how?


This comment has been minimized.

davefaliskie commented Oct 12, 2016

I did get the Voronoi to work with JSON data. I posted it at this link I used Ruby on Rails, however the modified code from christophermanning can be found in assets -> javascripts -> d3_scripts.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment