Skip to content

Instantly share code, notes, and snippets.

@bmershon
Forked from mbostock/.block
Last active January 24, 2017 23:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmershon/10ff92f5e84a8a87626fec6a782ca769 to your computer and use it in GitHub Desktop.
Save bmershon/10ff92f5e84a8a87626fec6a782ca769 to your computer and use it in GitHub Desktop.
Debug Quadtree
license: gpl-3.0
height: 960

While studying how d3-quadtree was built, I wanted to be able to interactively modify a quadtree.

This is a remix of Mike Bostock's example.

In diving through d3-quadtree, one finds "fun" bits of code like this one.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
cursor: crosshair;
position: absolute;
}
circle {
fill: rgba(240,0,0,1);
}
rect {
fill: none;
stroke-dasharray: 5, 5;
stroke: rgba(0,0,0,1);
stroke-width: 1px;
}
rect.leaf {
stroke-dasharray: none;
fill: rgba(0,0,0,0.1);
}
rect.leaf:hover {
fill: rgba(0,0,240,0.3);
}
text {
font-family: Helvetica;
font-size: 24px;
font-weight: bold;
text-anchor: middle;
}
</style>
<svg id="quadtree" width="960" height="960"></svg>
<script src="https://d3js.org/d3.v4.js"></script>
<script>
var svg = d3.select("#quadtree");
var width = 960,
height = 960,
radius = 1.5;
var text = svg.append("text")
.text("Click to add a point.")
.attr("x", width / 2)
.attr("y", height / 2);
svg.on("click", click);
let points = [],
quads = [],
extent = [[1, 1],[width - 1, height - 1]];
var quadtree = d3.quadtree()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
function click() {
if (text) {
text.remove();
text = undefined;
}
var mouse = d3.mouse(this),
newPoint = {x: mouse[0], y: mouse[1]};
points.push(newPoint);
quadtree.add(newPoint);
quads = [];
// Pre-order traversal of the quadtree.
quadtree.visit(function(node, x0, y0, x1, y1) {
if (node.data) { // Leaf node to be rendered.
quads.push({
"data": node.data,
"x0": x0,
"y0": y0,
"x1": x1,
"y1": y1
});
}
});
extent = quadtree.extent();
quads.push({
"x0": extent[0][0],
"y0": extent[0][1],
"x1": extent[1][0],
"y1": extent[1][1]
});
update();
}
function update() {
var circle, rectangle;
circle = svg.selectAll("circle")
.data(points);
circle.exit().remove();
circle.enter().append("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", radius)
.merge(circle);
// Rather than attempt to "key" quads, simply redraw them all.
rectangle = svg.selectAll("rect").remove();
rectangle = svg.selectAll("rect")
.data(quads);
rectangle.exit().remove();
rectangle.enter().append("rect")
.attr("x", function(d) { return d.x0; })
.attr("y", function(d) { return d.y0; })
.attr("width", function(d) { return d.x1 - d.x0; })
.attr("height", function(d) { return d.y1 - d.y0; })
.classed("leaf", function(d) { return d.data; })
.merge(circle);
}
</script>
@bmershon
Copy link
Author

TODO

Right click on square to delete a point from the quadtree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment