A static beeswarm plot implemented using d3-force’s collision constraint. A Voronoi overlay improves hover interaction.
forked from mbostock's block: Beeswarm
license: mit |
id,value | |
a,23 | |
b,12 | |
c,11 | |
d,14 | |
e,10 | |
f,10 | |
g,16 | |
h,11, | |
i, 2 | |
j, 22 |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
svg {border: 1px solid} | |
circle { | |
/* fill: none; | |
stroke: black; */ | |
} | |
</style> | |
<svg width="500" height="400"></svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var svg = d3.select("svg"), | |
width = svg.attr("width"), | |
height = svg.attr("height"); | |
var x = d3.scaleLinear().rangeRound([0, width]); | |
var g = svg.append("g"); | |
const smallRadius = 5; | |
const innerPadding = 1; | |
d3.csv("flare.csv", type, function(error, data) { | |
if (error) throw error; | |
var simulation = d3.forceSimulation(data) | |
.force("x", d3.forceX(function(d) { return width / 2 })) | |
.force("y", d3.forceY(height / 2)) | |
.force("collide", d3.forceCollide(smallRadius + innerPadding)) | |
.stop(); | |
for (var i = 0; i < 100; ++i) simulation.tick(); | |
var cell = g.selectAll("circle") | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("r", smallRadius) | |
.attr("cx", function(d) { return d.x; }) | |
.attr("cy", function(d) { return d.y; }); | |
g.append("circle") | |
.attr("r", getOuterRadius(data.length)) | |
.attr("cx", function(d) { return width/2 }) | |
.attr("cy", function(d) { return height/2 }) | |
.attr("fill", "none") | |
.attr("stroke", "blue"); | |
}); | |
function type(d) { | |
if (!d.value) return; | |
d.value = +d.value; | |
return d; | |
} | |
function getOuterRadius(nodes) { | |
return 6 * smallRadius; | |
} | |
</script> |