Public
Edited
Aug 8, 2023
Insert cell
Insert cell
chart = {
const width = 960;
const height = width;
const tree = d3.quadtree(
[],
(i) => points[i][0],
(i) => points[i][1]
);
tree.cover(
d3.min(points, ([x]) => x),
d3.min(points, ([, y]) => y)
);
tree.cover(
d3.max(points, ([x]) => x),
d3.max(points, ([, y]) => y)
);
const x = d3.scaleLinear([tree._x0, tree._x1], [0.5, width - 0.5]);
const y = d3.scaleLinear([tree._y0, tree._y1], [height - 0.5, 0.5]);

const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;");

const g = svg.append("g").attr("stroke", "currentColor").attr("fill", "none");

g.append("rect")
.attr("x", x(tree._x0))
.attr("y", y(tree._y1))
.attr("width", x(tree._x1) - x(tree._x0))
.attr("height", y(tree._y0) - y(tree._y1));

yield svg.node();

const nodes = new Set();
for (let i = 0; i < points.length; ++i) {
tree.add(i);
let t = svg.transition();

svg
.append("circle")
.attr("fill", "currentColor")
.attr("stroke", "white")
.attr("cx", x(points[i][0]))
.attr("cy", y(points[i][1]))
.attr("r", 0)
.transition(t)
.attr("r", 2.5);

// if the added point is in the boundary, and the capacity is 1.
// Then time to divide the current boundary/node


// First of all, let's check if the current node has been divided or not

// then let's go to each quad of the current node to see where this point can be added
let quads = tree._root
// if divide, all we need is parent node's x,y
// const xm = (x0 + x1) / 2;
// const ym = (y0 + y1) / 2;
// g.append("line")
// .attr("x1", x(xm))
// .attr("y1", y(ym))
// .attr("x2", x(xm))
// .attr("y2", y(ym))
// .transition(t)
// .attr("x1", x(x0));
// g.append("line")
// .attr("x1", x(xm))
// .attr("y1", y(ym))
// .attr("x2", x(xm))
// .attr("y2", y(ym))
// .transition(t)
// .attr("x2", x(x1));
// g.append("line")
// .attr("x1", x(xm))
// .attr("y1", y(ym))
// .attr("x2", x(xm))
// .attr("y2", y(ym))
// .transition(t)
// .attr("y1", y(y0));
// g.append("line")
// .attr("x1", x(xm))
// .attr("y1", y(ym))
// .attr("x2", x(xm))
// .attr("y2", y(ym))
// .transition(t)
// .attr("y2", y(y1));
await t.end();
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function quadtree_visitParent(callback) {
let quads = [],
q,
node = this._root,
parent,
child,
x0,
y0,
x1,
y1,
xm,
ym;
// console.log(this);
if (node)
quads.push({
node,
x0: this._x0,
y0: this._y0,
x1: this._x1,
y1: this._y1
});
while ((q = quads.pop())) {
(node = q.node), (parent = q.parent);

if (parent) callback(parent.x0, parent.y0, parent.x1, parent.y1);
if (!node.length) continue;
(x0 = q.x0),
(y0 = q.y0),
(x1 = q.x1),
(y1 = q.y1),
(xm = (x0 + x1) / 2),
(ym = (y0 + y1) / 2);
if ((child = node[3]))
quads.push({ parent: q, node: child, x0: xm, y0: ym, x1: x1, y1: y1 });
if ((child = node[2]))
quads.push({ parent: q, node: child, x0: x0, y0: ym, x1: xm, y1: y1 });
if ((child = node[1]))
quads.push({ parent: q, node: child, x0: xm, y0: y0, x1: x1, y1: ym });
if ((child = node[0]))
quads.push({ parent: q, node: child, x0: x0, y0: y0, x1: xm, y1: ym });
}
return this;
}
Insert cell
points = ((random) => Array.from({ length: 10 }, () => [random(), random()]))(
d3.randomNormal.source(d3.randomLcg(42))()
)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more