Menu

BeeswarmForce.svelte component

Generates an SVG Beeswarm chart using a d3-force simulation.

Param Default Required Description
r Number 4
no
The circle radius size in pixels.
strokeWidth Number 1
no
The circle's stroke width in pixels.
stroke String '#fff'
no
The circle's stroke color.
xStrength Number 0.95
no
The value passed into the .strength method on forceX. See the documentation.
yStrength Number 0.075
no
The value passed into the .strength method on forceY. See the documentation.
getTitle Function None
no
An accessor function to get the field on the data element to display as a hover label using a <title> tag.

Used in these examples:

<!--
  @component
  Generates an SVG Beeswarm chart using a [d3-force simulation](https://github.com/d3/d3-force).
 -->
<script>
  import { getContext } from 'svelte';
  import { forceSimulation, forceX, forceY, forceCollide } from 'd3-force';

  const { data, xGet, height, zGet } = getContext('LayerCake');

  const nodes = $data.map((d) => ({ ...d }));

  /** @type {Number} [r=4] - The circle radius size in pixels. */
  export let r = 4;

  /** @type {Number} [strokeWidth=1] - The circle's stroke width in pixels. */
  export let strokeWidth = 1;

  /** @type {String} [stroke='#fff'] - The circle's stroke color. */
  export let stroke = '#fff';

  /** @type {Number} [xStrength=0.95] - The value passed into the `.strength` method on `forceX`. See [the documentation](https://github.com/d3/d3-force#x_strength). */
  export let xStrength = 0.95;

  /** @type {Number} [yStrength=0.075] - The value passed into the `.strength` method on `forceY`. See [the documentation](https://github.com/d3/d3-force#y_strength). */
  export let yStrength = 0.075;

  /** @type {Function} [getTitle] — An accessor function to get the field on the data element to display as a hover label using a `<title>` tag. */
  export let getTitle = undefined;

  $: simulation = forceSimulation(nodes)
    .force('x', forceX().x(d => $xGet(d)).strength(xStrength))
    .force('y', forceY().y($height / 2).strength(yStrength))
    .force('collide', forceCollide(r))
    .stop();

  $: {
    for ( let i = 0,
      n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay()));
      i < n;
      ++i ) {
      simulation.tick();
    }
  }
</script>

<g class='bee-group'>
  {#each simulation.nodes() as node}
    <circle
      fill='{$zGet(node)}'
      stroke='{stroke}'
      stroke-width='{strokeWidth}'
      cx='{node.x}'
      cy='{node.y}'
      r='{r}'
    >
      {#if getTitle}
        <title>{getTitle(node)}</title>
      {/if}
    </circle>
  {/each}
</g>