Published
Edited
Jul 14, 2022
Insert cell
Insert cell
Insert cell
chart = {
replay;

const newCircle = circleGenerator(maxRadius);

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

for (let i = 0; i < N; ++i) {
const circle = newCircle(Math.min(100, Math.pow(1.01, i)));
if (circle === null) continue;

svg.append("circle")
.attr("cx", circle[0])
.attr("cy", circle[1])
.attr("r", 0)
.attr("fill", color(circle))
.transition()
.attr("r", circle[2]);

yield svg.node();
}
}
Insert cell
function circleGenerator(maxRadius) {
const quadtree = d3.quadtree().extent([[0, 0], [width, height]]);
return k => {
let bestX, bestY, bestDistance = 0;

for (var i = 0; i < k; ++i) {
const x = Math.random() * width;
const y = Math.random() * height;
const rx1 = x - maxRadius * 2;
const rx2 = x + maxRadius * 2;
const ry1 = y - maxRadius * 2;
const ry2 = y + maxRadius * 2;
let distance = maxRadius;

quadtree.visit((node, x1, y1, x2, y2) => {
if (!node.length) {
do {
const [px, py, pr] = node.data;
const dx = x - px;
const dy = y - py;
const d2 = dx * dx + dy * dy;
const r2 = pr * pr;
if (d2 < r2) return distance = 0, true; // within a circle
const d = Math.sqrt(d2) - pr;
if (d < distance) distance = d;
} while (node = node.next);
}
return !distance || x1 > rx2 || x2 < rx1 || y1 > ry2 || y2 < ry1; // or outside search radius
});

if (distance > bestDistance) bestX = x, bestY = y, bestDistance = distance;
}

if (bestDistance <= padding) return null;
const best = [bestX, bestY, bestDistance - padding];
quadtree.add(best);
return best;
};
}
Insert cell
N = 2500 // number of circles
Insert cell
maxRadius = 32 // maximum radius of circle
Insert cell
padding = 1 // padding between circles; also minimum radius
Insert cell
height = 500
Insert cell
color = () => d3.interpolateGreys(Math.random() * 0.6 + 0.2)
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