Public
Edited
Mar 30
Insert cell
Insert cell
Insert cell
{
const size = 640;
const circles = [];
const random = d3.randomUniform(-25, 25);
let [dx0, dy0, dx1, dy1, i0, i1] = [0, 0, 0, 0, 0, 0];

drawCircle(size / 2, size / 2, 150);

const extent = d3.extent(circles.map((d) => d.r)).reverse();
const scale = (i) => {
if (i === 0) return () => "black";
else return d3.scaleSequential(extent, d3[`interpolate${names[i]}`]);
};

function drawCircle(x, y, r) {
if (r < 4) return;
circles.push({ x, y, r });
drawCircle(x, y, r - 15);
}

function draw({ frameCount }) {
if (frameCount !== 0) {
[dx0, dy0] = [dx1, dy1];
[dx1, dy1] = [random(), random()];
[i0, i1] = [i1, d3.randomInt(1, names.length)()];
}

const [c0, c1] = [scale(i0), scale(i1)];

return cm.svg("g", circles, {
transform: (_, i) => `translate(${i * dx0},${i * dy0})`,
transition: (d, i) => [
{
transform: `translate(${i * dx1},${i * dy1})`,
duration: 1000,
delay: i * 20,
ease: d3.easeElastic
}
],
children: (d, i) => [
cm.svg("text", {
transform: `translate(${d.x},${d.y})`,
textAnchor: "middle",
dominantBaseline: "middle",
textContent: text,
fontSize: (d.r * 2) / Math.sqrt(text.length),
stroke: "#000",
fill: c0(d.r),
strokeWidth: 0.5,
fontWeight: "bold",
transition: [{ fill: c1(d.r), duration: 1000, delay: i * 20 }]
})
]
});
}

const app = cm.app({
width: size,
height: size,
draw,
loop: true,
frameRate: 0.5,
use: { transition: cm.transition }
});

invalidation.then(() => app.dispose());

return app.render();
}
Insert cell
Insert cell
Insert cell
Insert cell
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