Public
Edited
Mar 22, 2023
1 fork
1 star
Insert cell
Insert cell
viewof config = Inputs.form({
n: Inputs.range([0, 100000], {value: 10000, step: 1, label: "# Points"}),
size: Inputs.range([0.01, 0.5], {value: 0.15, label: "Point Size Factor"})
})
Insert cell
function phyllotaxis(n) {
const initialRadius = 1;
const initialAngle = Math.PI * (3 - Math.sqrt(5)); // Golden Angle
const r = initialRadius * Math.sqrt(n + 0.5);
const theta = n * initialAngle;
return [ r * Math.cos(theta), r * Math.sin(theta)];
}
Insert cell
nodes = {
const nodes = Array
.from(Array(config.n).keys())
.map(phyllotaxis);
return nodes;
}
Insert cell
{
const size = width;
const context = DOM.context2d(size, size);
context.fillStyle = '#222';
context.fillRect(0, 0, size, size);
const range = config.n / 100000
const x = d3.scaleLinear().domain(d3.extent(nodes, n=> n[0] * 1.1)).range([0, size]);
const y = x;
const c = d3.scaleSequential(d3.interpolateSpectral).domain([0, Math.sqrt(config.n)]);
for (let i = 0; i < nodes.length; ++i) {
const [cx, cy] = nodes[i];
context.beginPath()
context.fillStyle = c(Math.sqrt(i)) ;
context.arc(
x(cx),
y(cy),
size / Math.sqrt(nodes.length) * config.size,
0,
2 * Math.PI
)
context.fill()
if (nodes.length < 100) {
context.fillStyle = 'white'
context.textAlign = 'center'
context.textBaseline = 'middle'
context.font = '10px Arial'
context.fillText(i, x(cx), y(cy))
}
}

return context.canvas;
}

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