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