block by fil 3faaaf1b5f34b03a7a2235bf22e20b73

delaunay.findAll()

Full Screen

A potential method to find all sites within a given distance of a point.

forked from Andrew-Reid‘s block: Voronoi - voronoi.findAll()

index.html

<html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/d3-delaunay@5"></script>
<body>
<script>   
var width = 960;
var height = 500;

var data = d3.range(200).map(function(d) {
  var y = d3.randomNormal(height / 2,80)();
  var  x = d3.randomNormal(width / 2, 150)();
  if(x > width)  x = width - 0.001; else if (x < 0) x = 0.001;
  if(y > height) y = height - 0.001; else if (y < 0) y = 0.001;
  return [x,y]
});

var delaunay = d3.Delaunay.from(data);
  
delaunay.findAll = function(x, y, radius) {
  const points = delaunay.points,
        results = [],
        seen = [],
        queue = [delaunay.find(x, y)];

  while (queue.length) {
    const q = queue.pop();
    if (seen[q]) continue;
    seen[q] = true;
    if (Math.hypot(x - points[2*q], y - points[2*q+1]) < radius) {
      results.push(q);
      for (const p of delaunay.neighbors(q)) queue.push(p);
    }
  }
  
  return results;
}



var svg = d3.select("body")
  .append("svg")
  .attr("width",width)
  .attr("height",height);

var circles = svg.selectAll("circle")
  .data(data).join("circle")
  .attr("cx", d => d[0])
  .attr("cy", d => d[1])
  .attr("r", 3);
  
var results = delaunay.findAll(width/2,height/2, 25);
circles.attr("fill", (_,i) => results.indexOf(i) > -1 ? "orange" : "green");
  
var circle = svg.append("circle")
  .attr("cx",width/2)
  .attr("cy",height/2)
  .attr("r",25)
  .attr("fill","none")
  .attr("stroke","black")
  .attr("stroke-width",1);
  
circle.transition()
  .attrTween("r", function() {
    var node = this;
      return function(t) { 
        var r = d3.interpolate(25,200)(t);
        var results = delaunay.findAll(width/2, height/2, r);
  console.log(results)
        circles.attr("fill", (_,i) => results.indexOf(i) > -1 ? "orange" : "green");
        return r;
      }
    })
    .duration(2000)
    .delay(750);

</script>