position = (data) => {
var iters = 600;
var thresh = 0.001;
const rCollide = 10;
data.forEach(d => { d.y = d._y + d.value/2 + lineHeight /2});
const max = d3.max(data, d=>d.value);
function boxForce(alpha) {
data.forEach(d => {
let nextY = d.y + d.vy;
if (nextY < bbox.y) { d.vy = 0, d.y = bbox.y }
if (nextY > bbox.y + bbox.height) { d.vy = 0, d.y = bbox.y + bbox.height }
});
}
const simulation = d3.forceSimulation(data)
.force('charge', d3.forceCollide().strength(0.7).radius(rCollide))
.force('bounded', boxForce)
.force('y', d3.forceY().strength(d=>(d.value/max)**2).y(d => d._y + d.value/2 + lineHeight/2))
.stop();
for (var i = iters; i > 0; --i) {
simulation.tick();
if(simulation.alpha() < thresh) {
break;
}
}
return data;
}