chart = {
const context = DOM.context2d(width, height);
const nodes = data.map(Object.create);
let bp = 10
let forceY = d3.forceY(height / 2 + bp).strength(yStrength)
let myForceY = function(y) {
function force(alpha) {
forceY(alpha)
for (var i = 0, n = nodes.length; i < n; ++i) {
let node = nodes[i];
if (node.y + node.r > height / 2 - bp) {
node.vy = -node.vy
node.y = height / 2 - node.r / 2 - bp
}
}
}
force.initialize = forceY.initialize
force.strength = forceY.strength
force.y = forceY.y
return force;
}
const simulation = d3.forceSimulation(nodes)
.alphaTarget(0.3)
.velocityDecay(0.1)
.force("x", d3.forceX(d => d.x0).strength(xStrength))
.force("y", myForceY())
.force("collide", d3.forceCollide().radius(d => d.r + 1).iterations(10))
.on("tick", ticked);
d3.select(context.canvas);
invalidation.then(() => simulation.stop());
function ticked() {
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
for (const d of nodes) {
context.beginPath();
context.moveTo(d.x + d.r, d.y);
context.arc(d.x, d.y, d.r, 0, 2 * Math.PI);
context.fillStyle = markColor;
context.fill();
}
context.restore();
}
return context.canvas;
}