All examples By author By category About

Kcnarf

d3-beeswarm plugin

This block uses the d3-beeswarm plugin I made (see the Github project). This plugin produces a beeswarm arrangement, thanks to a dedicated algorithm and without the use a the d3.force layout.

Beeswarm is a one-dimensional scatter plot with closely-packed, non-overlapping points. The beeswarm plot is a useful technique when we wish to see not only the measured values of interest for each data point, but also the distribution of these values

Some beeswarm-like plot implementation uses force layout, but the force layout simulation has some drawbacks:

This beeswarm plugin uses a dedicated one pass algorithm. By default, the plugin arranges data in an horizontal way. In this case, the final arrangement is contraint in x and free in y. This means that data are arranged along the x-axis, and that the position of each data reflects its precise x value. y position doesn't reflect any data-related value, and only serves the non-overlapping constraint. This plugin can also arrange data in a vertical way.

Even if this block works fine, the plugin is an on-going work. See the Github project's issues for possible enhancements.

Usages

var swarm = d3.beeswarm()
  .data(data)                                 // set the data to arrange
  .distributeOn(function(d){                  // set the value accessor to distribute on
       return xScale(d.trend);                  // evaluated once on each element of data
   })                                           // when starting the arrangement
  .radius(4)                                  // set the radius for overlapping detection
  .orientation("horizontal")                  // set the orientation of the arrangement
                                                // could also be 'vertical'
  .side("symetric")                           // set side(s) available for accumulation;
                                                // could also be 'positive' or 'negative'
  .arrange();                                 // launch arrangement computation;
                                                // return an array of {datum: , x: , y: }
                                                // where datum refers to an element of data
                                                // each element of data remains unchanged

Then, later in your code, in order to draw the swarm:

d3.selectAll("circle")
  .data(swarm)
  .enter()
    .append("circle")
      .attr("cx", function(bee) { return bee.x; })
      .attr("cy", function(bee) { return bee.y; })
      .attr("r", 4)
      .style("fill", function(bee) { return fill(bee.datum.rank); })

In the last line, bee.datum refers to the original datum.

Acknowledgments to: