Built with blockbuilder.org
forked from anonymous's block: Finding adjacent voronoi cells
license: mit |
Built with blockbuilder.org
forked from anonymous's block: Finding adjacent voronoi cells
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.links { | |
stroke: #000; | |
stroke-opacity: 0.2; | |
} | |
.polygons { | |
fill: none; | |
stroke: #000; | |
} | |
.sites { | |
fill: #000; | |
stroke: #fff; | |
} | |
</style> | |
<svg width="960" height="500"></svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var svg = d3.select("svg").on("touchmove mousemove", moved), | |
width = +svg.attr("width"), | |
height = +svg.attr("height"); | |
var sites = d3.range(30) | |
.map(function(d) { return [Math.random() * width, Math.random() * height]; }); | |
var voronoi = d3.voronoi() | |
.extent([[-1, -1], [width + 1, height + 1]]); | |
var polygon = svg.append("g") | |
.attr("class", "polygons") | |
.selectAll("path") | |
.data(voronoi.polygons(sites)) | |
.enter().append("path") | |
.call(redrawPolygon); | |
var link = svg.append("g") | |
.attr("class", "links") | |
.selectAll("line") | |
.data(voronoi.links(sites)) | |
.enter().append("line") | |
.call(redrawLink); | |
var site = svg.append("g") | |
.attr("class", "sites") | |
.selectAll("circle") | |
.data(sites) | |
.enter().append("circle") | |
.attr("r", 2.5) | |
.call(redrawSite); | |
function moved() { | |
sites[0] = d3.mouse(this); | |
redraw(); | |
} | |
function redraw() { | |
//Aim is to find all cells which are adjacent to the current one | |
//Then we can select them | |
var diagram = voronoi(sites); | |
var links = diagram.links() | |
var polygons = diagram.polygons() | |
polygons.forEach(function(p) { | |
p.adjacent = false | |
}) | |
var this_site = sites[0] //array[2] | |
var this_polygon = polygons[0] //set of coordinates and data attribute | |
var counter = 1 | |
links.forEach(function(l) { | |
if (l.source == this_site || l.target == this_site) { | |
//get corresponding polygons | |
polygons.forEach(function(p) { | |
if (p.data == l.target || p.data == l.source) { | |
p["adjacent"] = true | |
} | |
}) | |
} | |
}) | |
//this site corresponds to polygon[0] | |
// | |
polygon = polygon.data(polygons).call(redrawPolygon); | |
link = link.data(links), link.exit().remove(); | |
link = link.enter().append("line").merge(link).call(redrawLink); | |
site = site.data(sites).call(redrawSite); | |
} | |
function redrawPolygon(polygon) { | |
polygon | |
.attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; }) | |
.style("fill", function(d){ | |
if (d.adjacent == 1) { | |
return "#F1F" | |
} else { | |
return "#FF1" | |
} | |
}) | |
} | |
function redrawLink(link) { | |
link | |
.attr("x1", function(d) { return d.source[0]; }) | |
.attr("y1", function(d) { return d.source[1]; }) | |
.attr("x2", function(d) { return d.target[0]; }) | |
.attr("y2", function(d) { return d.target[1]; }); | |
} | |
function redrawSite(site) { | |
site | |
.attr("cx", function(d) { return d[0]; }) | |
.attr("cy", function(d) { return d[1]; }); | |
} | |
</script> |