D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
ddramone
Full window
Github gist
voronoi knn
Built with
blockbuilder.org
<!DOCTYPE html> <meta charset="utf-8"> <style> .links { stroke: #000; stroke-opacity: 0.2; } .polygons { fill: none; stroke: #000; } </style> <svg width="960" height="500"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> console.clear(); var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); /** DUMB DATA **/ var sites = d3.range(200) .map(function(d) { var x = Math.random() * (width - 80) + 40; var y = Math.random() * (height-80) + 40; return { x: x, y: y, id: 'luminiare'+Math.random() }; }).filter((point)=>{ var x = point.x; var y = point.y; xInRange = x>200 && x<600; yInRange = y<400; return !(xInRange && yInRange); }); var voronoi = d3.voronoi() .x((d)=>d.x) .y((d)=>d.y) .extent([[0, 0], [width, height]]); var diagram = voronoi(sites); var links = diagram.links(); var averageDistance = getAverageDistance(); var radius = svg.append("g") .attr("class", "spread"); var polygon = svg.append("g") .attr("class", "polygons") .selectAll("path") .data(voronoi.polygons(sites)) .enter().append("path") .attr('stroke','cyan') .call(redrawPolygon); var circles = svg.append("g") .attr("class", "circles") .selectAll('circle') .data(sites) .enter().append('circle') .attr('r', 10) .attr('fill',function(d){ return 'red'; }) .attr("cy", (d)=> d.y) .attr("cx", (d)=> d.x) .on("click", findNeighbours) .on("mouseenter", showRadius) function showRadius(){ var cell = findCell(d3.mouse(this)); radius.selectAll('circle').remove(); radius .append('circle') .attr('r', averageDistance) .attr("cy", cell.data.y) .attr("cx", cell.data.x) .attr('stroke','blue') .attr('fill','#fffbea'); } var highlighted = []; function findCell(m) { return diagram.find(m[0],m[1]) } function findNeighbours() { var cell = findCell(d3.mouse(this)); var cellData = diagram.cells[cell.index]; cell.data.status = 'localized'; for(var edgeIndex of cellData.halfedges) { var edge = diagram.edges[edgeIndex]; var neighbour = edge.left == cell ? edge.right : edge.left; if(!neighbour) continue; if(neighbour.data.status == 'localized') continue; var tP = neighbour.data; // target Point var sP = cell.data; // source Point var distance = Math.sqrt( (Math.pow(tP.x-sP.x,2))+ (Math.pow(tP.y-sP.y,2))) if(distance < averageDistance){ neighbour.data.status = 'highlighted'; } // break; } redraw(); } function redraw() { circles.data(sites) .attr('fill',function(d){ return { localized: 'blue', highlighted: 'green' }[d.status] || 'red' }) } function redrawPolygon(polygon) { polygon .attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; }); } function getAverageDistance() { var distances = links.map(function(d) { return Math.sqrt( Math.pow(d.target.x - d.source.x,2) + Math.pow(d.target.y - d.source.y,2) ); }); var max = d3.max(distances); var min = d3.min(distances); var mean = d3.mean(distances); return max-(max-mean)/2; return (max+mean)/2; } </script>
https://d3js.org/d3.v4.min.js