Public
Edited
Aug 1, 2023
60 forks
68 stars
Insert cell
Insert cell
chart = {
let currentTransform = [width / 2, height / 2, height];

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])

const g = svg.append("g");

g.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", ([x]) => x)
.attr("cy", ([, y]) => y)
.attr("r", radius)
.attr("fill", (d, i) => d3.interpolateRainbow(i / 360))

function transition() {
const d = data[Math.floor(Math.random() * data.length)];
const i = d3.interpolateZoom(currentTransform, [...d, radius * 2 + 1]);

g.transition()
.delay(250)
.duration(i.duration)
.attrTween("transform", () => t => transform(currentTransform = i(t)))
.on("end", transition);
}

function transform([x, y, r]) {
return `
translate(${width / 2}, ${height / 2})
scale(${height / r})
translate(${-x}, ${-y})
`;
}

return svg.call(transition).node();
}
Insert cell
height = 500 // Observable provides a responsive *width*
Insert cell
radius = 6
Insert cell
step = radius * 2
Insert cell
data = Array.from({length: 2000}, (_, i) => {
const r = step * Math.sqrt(i += 0.5), a = theta * i;
return [
width / 2 + r * Math.cos(a),
height / 2 + r * Math.sin(a)
];
})
Insert cell
theta = Math.PI * (3 - Math.sqrt(5))
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