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> |