dodge = (data) => {
const circles = data.map(d => ({x: x(d.value), r: r(d.population), data: d})).sort((a, b) => b.r - a.r);
const epsilon = 1e-3;
let head = null, tail = null, queue = null;
function intersects(x, y, r) {
let a = head;
while (a) {
const radius2 = (a.r + r + padding) ** 2;
if (radius2 - epsilon > (a.x - x) ** 2 + (a.y - y) ** 2) {
return true;
}
a = a.next;
}
return false;
}
for (const b of circles) {
if (intersects(b.x, b.y = b.r, b.r)) {
let a = head;
b.y = Infinity;
do {
let y = a.y + Math.sqrt((a.r + b.r + padding) ** 2 - (a.x - b.x) ** 2);
if (y < b.y && !intersects(b.x, y, b.r)) b.y = y;
a = a.next;
} while (a);
}
b.next = null;
if (head === null) {
head = tail = b;
queue = head;
} else tail = tail.next = b;
}
return circles;
}