Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Kcnarf/d3-beeswarm
D3 plugin which computes a 'beeswarm' arrangement
https://github.com/Kcnarf/d3-beeswarm
Last synced: 2 months ago
JSON representation
D3 plugin which computes a 'beeswarm' arrangement
- Host: GitHub
- URL: https://github.com/Kcnarf/d3-beeswarm
- Owner: Kcnarf
- License: other
- Created: 2016-06-07T07:41:29.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2022-08-16T09:47:45.000Z (over 2 years ago)
- Last Synced: 2024-10-11T11:14:55.755Z (3 months ago)
- Language: JavaScript
- Homepage:
- Size: 68.4 KB
- Stars: 52
- Watchers: 4
- Forks: 9
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-d3 - d3-beeswarm - Plugin which computes a beeswarm arrangement (Charts)
- awesome-d3 - d3-beeswarm - Plugin which computes a beeswarm arrangement (Charts)
- awesome-d3 - d3-beeswarm - Plugin which computes a beeswarm arrangement (Charts)
README
# d3-beeswarm
This d3 plugin produces a _beeswarm_ arrangement, thanks to a dedicated algorithm and without the use a the d3.force layout.
Available only for **d3 v3.x** and **d3 v4**.
## Context
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:
- it naturally tries to reach its equilibrium by rearranging data points in the 2D space, which can be disruptive to the ordering of the data
- it requires several iterations to reach its equilibriumThis _beeswarm_ plugin uses a dedicated one pass algorithm. By default, this plugin arranges data in an horizontal way, ie. along the x-axis. In this case, the final arrangement is constraint in _x_ and free in _y_. This means that the position of each data reflects its precise _x_ value, while _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.
## Examples
- [Universities of Berlin and Germany](https://lab.technologiestiftung-berlin.de/projects/unis/index_en.html): Where do people study most? How does the academic landscape look like?
- [White House Salaries - Obama '16 VS Trump '17](https://bl.ocks.org/Kcnarf/4608704a70fc24e2c06ca0116830de47).
- This [post](http://poly-graph.co/vocabulary.html) uses a beeswarm plot (but not this plugin).
- This [block](http://bl.ocks.org/Kcnarf/5c989173d0e0c74ab4b62161b33bb0a8) allows to play with the options of this **d3-beeswarm** plugin.## Installing
If you use NPM, `npm install d3-beeswarm`. Otherwise, load `https://rawgit.com/Kcnarf/d3-beeswarm/master/build/d3-beeswarm.js` to make it available in AMD, CommonJS, or vanilla environments. In vanilla, a d3 global is exported:
```html
var swarm = d3.beeswarm();
```
## TL;DR;
In your javascript, in order to define the arrangement:
```javascript
var swarm = d3
.beeswarm()
.data(data) // set the data to arrange
.distributeOn(function(d) {
// set the value accessor to distribute on
return xScale(d.foo); // 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 the 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 javascript, in order to draw the swarm:
```javascript
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 fillScale(bee.datum.bar);
});
```In the last line, `bee.datum` refers to the original datum.
## Reference
- R package: [http://www.cbs.dtu.dk/~eklund/beeswarm](http://www.cbs.dtu.dk/~eklund/beeswarm/)
## API
# d3.beeswarm()
Creates a new beeswarm with the default settings:
```javascript
distributeOn = function(d) {
return d.x;
};
radius = 4;
orientation = 'horizontal';
side = 'symetric';
```# beeswarm.datadata([data])
If _data_ is specified, set the array of data to arrange and returns this beeswarm. If _data_ is not specified, returns the current array of data to arrange.
# beeswarm.distributeOn([callback])
If _callback_ is specified, set the callback that evaluates the value to distribute on and returns this beeswarm. If _callback_ is not specified, return the current callback, which defaults to `function(d) { return d.x; }`.
The callback is evaluated once, on each element to arrange, at the beginning of the arrangement computation. The callback must return the final x-coordinate for an horizontal arrangement (or the final y-coordinate for a vertical arrangement). So if you use a d3.scale, your code should look like:
```javascript
d3.beeswarm()
.data(data)
.distributeOn(function(d) {
return xScale(d.foo);
});
```# beeswarm.radius([radius])
Without any argument, returns the current radius of the layout.
If _radius_ is specified, sets the radius of each datum to the specified number. If _radius_ is not specified, returns the current radius, which defaults to 4.The arrangement uses this _radius_ as a constraint, and arranges each datum so that there is no overlapping. However, when its time to draw each datum, you can use another rendering radius:
- a lower rendering radius will add some padding between data
- a higher rendering radius will add some overlapping between data (making the final viz more compacted as if there wasn't any overlapping, but with the drawback to not meet the non-overlapping constraint of beeswarm arrangement)# beeswarm.orientation([orientation])
If _orientation_ is specified, set the orientation to the specified value (within `'horizontal'` or `'vertical'`) and returns this beeswarm. If _orientation_ is not specified, returns the current orientation, which defaults to `'horizontal'`.
A `'horizontal'` orientation will arrange data along the x-axis. A `'vertical'` arrangement will arrange data along the y-axis.
# beeswarm.side([side])
If _side_ is specified, set the side to the specified value (within `'symetric'`, `'positive'` or `'negative'`) and returns this beeswarm. If _side_ is not specified, returns the current side, which defaults to `'symetric'`.
A `'symetric'` side arranges data around the main axis, placing data above and below the axis. A `'positive'`side arranges data only above the main axis. A `'negative'`side arranges data only below the main axis.
# beeswarm.arrange()
Launches the arrangement computation. Return an array of `{x: , y: , datum: }`, where `x` and `y` are the computed coordinates, and `datum` refers to the original element of data.
## How To
- issue [option to arrange from minToMax, maxToMin, extremeToCenter, shuffled](https://github.com/Kcnarf/d3-beeswarm/issues/7) explains how to arrange in a particular order. It can be tested in [this block](http://bl.ocks.org/Kcnarf/5c989173d0e0c74ab4b62161b33bb0a8).
- issue [add a maximum size, and provide strategies if exceeded](https://github.com/Kcnarf/d3-beeswarm/issues/2) explains how to handle too large viz due to extreme accumulations. It can be tested in [this block](http://bl.ocks.org/Kcnarf/5c989173d0e0c74ab4b62161b33bb0a8).