Published
Edited
Jun 20, 2021
9 stars
Insert cell
Insert cell
{
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})`);
}
}
Insert cell
d3 = require("d3@7", "d3-bboxCollide@1.0.4")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more