{"id":13481107,"url":"https://github.com/Kcnarf/d3-beeswarm","last_synced_at":"2025-03-27T11:31:51.414Z","repository":{"id":50382686,"uuid":"60592725","full_name":"Kcnarf/d3-beeswarm","owner":"Kcnarf","description":"D3 plugin which computes a 'beeswarm' arrangement","archived":false,"fork":false,"pushed_at":"2022-08-16T09:47:45.000Z","size":70,"stargazers_count":52,"open_issues_count":2,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-11T11:14:55.755Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kcnarf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-07T07:41:29.000Z","updated_at":"2024-06-17T18:28:01.000Z","dependencies_parsed_at":"2022-07-31T02:18:12.485Z","dependency_job_id":null,"html_url":"https://github.com/Kcnarf/d3-beeswarm","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kcnarf%2Fd3-beeswarm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kcnarf%2Fd3-beeswarm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kcnarf%2Fd3-beeswarm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kcnarf%2Fd3-beeswarm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kcnarf","download_url":"https://codeload.github.com/Kcnarf/d3-beeswarm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245836242,"owners_count":20680339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:00:48.753Z","updated_at":"2025-03-27T11:31:51.127Z","avatar_url":"https://github.com/Kcnarf.png","language":"JavaScript","funding_links":[],"categories":["Charts"],"sub_categories":[],"readme":"# d3-beeswarm\n\nThis d3 plugin produces a _beeswarm_ arrangement, thanks to a dedicated algorithm and without the use a the d3.force layout.\n\nAvailable only for **d3 v3.x** and **d3 v4**.\n\n## Context\n\nBeeswarm 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\n\nSome beeswarm-like plot implementation uses force layout, but the force layout simulation has some drawbacks:\n\n- 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\n- it requires several iterations to reach its equilibrium\n\nThis _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.\n\n## Examples\n\n- [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?\n- [White House Salaries - Obama '16 VS Trump '17](https://bl.ocks.org/Kcnarf/4608704a70fc24e2c06ca0116830de47).\n- This [post](http://poly-graph.co/vocabulary.html) uses a beeswarm plot (but not this plugin).\n- This [block](http://bl.ocks.org/Kcnarf/5c989173d0e0c74ab4b62161b33bb0a8) allows to play with the options of this **d3-beeswarm** plugin.\n\n## Installing\n\nIf 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:\n\n```html\n\u003cscript src=\"https://d3js.org/d3.v3.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://rawgit.com/Kcnarf/d3-beeswarm/master/build/d3-beeswarm.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  var swarm = d3.beeswarm();\n\u003c/script\u003e\n```\n\n## TL;DR;\n\nIn your javascript, in order to define the arrangement:\n\n```javascript\nvar swarm = d3\n  .beeswarm()\n  .data(data) // set the data to arrange\n  .distributeOn(function(d) {\n    // set the value accessor to distribute on\n    return xScale(d.foo); // evaluated once on each element of data\n  }) // when starting the arrangement\n  .radius(4) // set the radius for overlapping detection\n  .orientation('horizontal') // set the orientation of the arrangement\n  // could also be 'vertical'\n  .side('symetric') // set the side(s) available for accumulation\n  // could also be 'positive' or 'negative'\n  .arrange(); // launch arrangement computation;\n// return an array of {datum: , x: , y: }\n// where datum refers to an element of data\n// each element of data remains unchanged\n```\n\nThen, later in your javascript, in order to draw the swarm:\n\n```javascript\nd3.selectAll('circle')\n  .data(swarm)\n  .enter()\n  .append('circle')\n  .attr('cx', function(bee) {\n    return bee.x;\n  })\n  .attr('cy', function(bee) {\n    return bee.y;\n  })\n  .attr('r', 4)\n  .style('fill', function(bee) {\n    return fillScale(bee.datum.bar);\n  });\n```\n\nIn the last line, `bee.datum` refers to the original datum.\n\n## Reference\n\n- R package: [http://www.cbs.dtu.dk/~eklund/beeswarm](http://www.cbs.dtu.dk/~eklund/beeswarm/)\n\n## API\n\n\u003ca name=\"beeswarm\" href=\"#beeswarm\"\u003e#\u003c/a\u003e d3.\u003cb\u003ebeeswarm\u003c/b\u003e()\n\nCreates a new beeswarm with the default settings:\n\n```javascript\ndistributeOn = function(d) {\n  return d.x;\n};\nradius = 4;\norientation = 'horizontal';\nside = 'symetric';\n```\n\n\u003ca name=\"beeswarm_data\" href=\"#beeswarm_data\"\u003e#\u003c/a\u003e \u003ci\u003ebeeswarm.\u003c/i\u003e\u003cb\u003edata\u003c/b\u003edata\u003c/b\u003e([data])\n\nIf _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.\n\n\u003ca name=\"beeswarm_distributeOn\" href=\"#beeswarm_distributeOn\"\u003e#\u003c/a\u003e \u003ci\u003ebeeswarm.\u003c/i\u003e\u003cb\u003edistributeOn\u003c/b\u003e([callback])\n\nIf _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; }`.\n\nThe 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:\n\n```javascript\nd3.beeswarm()\n  .data(data)\n  .distributeOn(function(d) {\n    return xScale(d.foo);\n  });\n```\n\n\u003ca name=\"beeswarm_radius\" href=\"#beeswarm_radius\"\u003e#\u003c/a\u003e \u003ci\u003ebeeswarm.\u003c/i\u003e\u003cb\u003eradius\u003c/b\u003e([radius])\n\nWithout any argument, returns the current radius of the layout.\nIf _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.\n\nThe 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:\n\n- a lower rendering radius will add some padding between data\n- 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)\n\n\u003ca name=\"beeswarm_orientation\" href=\"#beeswarm_orientation\"\u003e#\u003c/a\u003e \u003ci\u003ebeeswarm.\u003c/i\u003e\u003cb\u003eorientation\u003c/b\u003e([orientation])\n\nIf _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'`.\n\nA `'horizontal'` orientation will arrange data along the x-axis. A `'vertical'` arrangement will arrange data along the y-axis.\n\n\u003ca name=\"beeswarm_side\" href=\"#beeswarm_side\"\u003e#\u003c/a\u003e \u003ci\u003ebeeswarm.\u003c/i\u003e\u003cb\u003eside\u003c/b\u003e([side])\n\nIf _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'`.\n\nA `'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.\n\n\u003ca name=\"beeswarm_arrange\" href=\"#beeswarm_arrange\"\u003e#\u003c/a\u003e \u003ci\u003ebeeswarm.\u003c/i\u003e\u003cb\u003earrange\u003c/b\u003e()\n\nLaunches 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.\n\n## How To\n\n- 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).\n- 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).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKcnarf%2Fd3-beeswarm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKcnarf%2Fd3-beeswarm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKcnarf%2Fd3-beeswarm/lists"}