function linkForce(links, {
min = 50, max = 200, strength = .5, id = d => d.id
} = {}) {
const clamp = (a, b, v) => v <= a ? a : v >= b ? b : v;
const update = (alpha) => {
const s = .5 * alpha * strength;
for(const {source: a, target: b} of links) {
const dx = a.x + a.vx - b.x - b.vy;
const dy = a.y + a.vy - b.y - b.vy;
const dn = Math.hypot(dx, dy);
const dc = clamp(min, max, dn);
if(dn === dc) continue;
const f = (dc - dn) / dn * .5 * alpha * strength;
a.vx += dx * f;
a.vy += dy * f;
b.vx -= dx * f;
b.vy -= dy * f;
}
};
const initialize = nodes => {
const map = new Map(nodes.map(d => [id(d), d]));
for(const link of links) {
link.source = map.get(link.source);
link.target = map.get(link.target);
}
};
return Object.assign(update, {initialize});
}