Published
Edited
Jul 29, 2022
15 forks
Importers
10 stars
Insert cell
Insert cell
beeswarm = beeswarmForce()
.x(d => x(d.value))
.y(chartheight / 2)
.r(d => 1 + r(d.size))
Insert cell
{
const svg = d3.create("svg")
.attr("width", chartwidth + margin.left + margin.right)
.attr("height", chartheight + margin.top + margin.bottom);
const g = svg.append("g")
.attr("transform", `translate(${[margin.left, margin.top]})`);
g.append("g")
.call(d3.axisBottom(x).tickSizeOuter(0))
.attr("transform", `translate(0, ${chartheight / 1.25})`);
g.selectAll("circle")
.data(beeswarm(data))
.join("circle")
.attr("stroke", "black")
.attr("fill-opacity", 0.8)
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", d => r(d.data.size));
return svg.node();
}
Insert cell
x = d3.scaleLinear(
d3.extent(data, d => d.value),
[0, chartwidth]
);
Insert cell
r = d3.scaleSqrt(
[100, 1000],
[1, Math.sqrt(width * height) / 30]
);
Insert cell
margin = ({ left: 2 * r.range()[1], right: 2 * r.range()[1], top: 1, bottom: 1 });
Insert cell
chartwidth = width - margin.left - margin.right;
Insert cell
height = 200;
Insert cell
chartheight = height - margin.top - margin.bottom;
Insert cell
// Make some random data
data = {
const random = d3.randomNormal();
return Array
.from({ length: 100 })
.map(d => ({ value: random(), size: d3.randomUniform(...r.domain())() }));
}
Insert cell
beeswarmForce = function(){
let x = d => d[0];
let y = d => d[1];
let r = d => d[2];
let ticks = 300;
function beeswarm(data){
const entries = data.map(d => {
return {
x0: typeof x === "function" ? x(d) : x,
y0: typeof y === "function" ? y(d) : y,
r: typeof r === "function" ? r(d) : r,
data: d
}
});
const simulation = d3.forceSimulation(entries)
.force("x", d3.forceX(d => d.x0))
.force("y", d3.forceY(d => d.y0))
.force("collide", d3.forceCollide(d => d.r));
for (let i = 0; i < ticks; i++) simulation.tick();
return entries;
}
beeswarm.x = f => f ? (x = f, beeswarm) : x;
beeswarm.y = f => f ? (y = f, beeswarm) : y;
beeswarm.r = f => f ? (r = f, beeswarm) : r;
beeswarm.ticks = n => n ? (ticks = n, beeswarm) : ticks;
return beeswarm;
}
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