Use Voronoi.find() to group data by the Voronoi cells of the top 10% data points.
See also the animated version.
Original work by Philippe Rivière for d3-voronoi (issue 17).
license: gpl-3.0 |
Use Voronoi.find() to group data by the Voronoi cells of the top 10% data points.
See also the animated version.
Original work by Philippe Rivière for d3-voronoi (issue 17).
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
circle { | |
stroke: #444; | |
} | |
</style> | |
<svg width="960" height="500"></svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var svg = d3.select("svg"), | |
width = +svg.attr("width"), | |
height = +svg.attr("height"); | |
var color = d3.scaleOrdinal().range(d3.schemeCategory20); | |
var n = 4000; | |
var data = d3.range(n) | |
.map(function(d,i) { return [Math.random() * width, Math.random() * height, color(i), Math.random()]; }); | |
var voronoi = d3.voronoi() | |
.size([width, height]); | |
var sites = data.sort(function(a,b) { | |
return d3.descending(a[3], b[3]); | |
}) | |
.slice(0,n/10); | |
var diagram = voronoi(sites); | |
diagram.find = find; | |
d3.select('svg') | |
.append('g') | |
.selectAll('circle') | |
.data(data) | |
.enter() | |
.append('circle') | |
.attr('r', function(d) {return 10 * d[3] * d[3];}) | |
.attr('transform', function(d) { return 'translate('+ [ d[0], d[1] ] +')'; }) | |
.attr('fill', function(d) { | |
var found = diagram.find(d[0],d[1]); | |
return sites[found.index][2]; | |
}); | |
function find (x, y, radius){ | |
// optimization: start from most recent result | |
var i, next = diagram.find.found || Math.floor(Math.random() * diagram.cells.length); | |
var cell = diagram.cells[next] || diagram.cells[next=0]; | |
var dx = x - cell.site[0], | |
dy = y - cell.site[1], | |
dist = dx*dx + dy*dy; | |
do { | |
cell = diagram.cells[i=next]; | |
next = null; | |
cell.halfedges.forEach(function(e) { | |
var edge = diagram.edges[e]; | |
var ea = edge.left; | |
if (ea === cell.site || !ea) { | |
ea = edge.right; | |
} | |
if (ea){ | |
var dx = x - ea[0], | |
dy = y - ea[1], | |
ndist = dx*dx + dy*dy; | |
if (ndist < dist){ | |
dist = ndist; | |
next = ea.index; | |
return; | |
} | |
} | |
}); | |
} while (next !== null); | |
diagram.find.found = i; | |
if (!radius || dist < radius * radius) return cell.site; | |
} | |
</script> |
�PNG | |