{
const main = svg`<svg viewBox="0 0 ${width} 550">
<style>.base { fill-opacity: 0.75; stroke-opacity: 0.5; }`;
yield main;
const color = d3.scaleOrdinal(d3.schemeCategory10);
const randomPoints = Array.from({ length: 500 }, () => ({
value: Math.random(),
color: d3.color(color(Math.random()))
}));
const networkCenter = d3.forceCenter().x(250).y(250);
const forceX = d3.forceX(() => 100).strength(0.1);
const forceY = d3.forceY((d) => d.value * 500).strength(1);
const collide = d3
.bboxCollide((d) => [
[-d.value * 10, -d.value * 5],
[d.value * 10, d.value * 5]
])
.strength(1)
.iterations(2);
const force = d3
.forceSimulation(randomPoints)
.velocityDecay(0.6)
.force("center", networkCenter)
.force("x", forceX)
.force("y", forceY)
.force("collide", collide)
.on("tick", updateNetwork);
const nodeEnter = d3
.select(main)
.append("g")
.selectAll("g.node")
.data(randomPoints)
.enter()
.append("g")
.attr("class", "node");
nodeEnter
.append("rect")
.attr("class", "base")
.style("stroke", (d) => d.color.darker(2))
.style("fill", (d) => d.color.brighter(2))
.attr("width", (d) => d.value * 20)
.attr("height", (d) => d.value * 10)
.attr("x", (d) => -d.value * 10)
.attr("y", (d) => -d.value * 5);
function updateNetwork() {
d3.select(main)
.selectAll("g.node")
.attr("transform", (d) => `translate(${d.x}, ${d.y})`);
}
}