Menu

Cleveland dot plotEdit

0
500
1000
1500
2000
2500
3000
3500
2016
2017
2018
2019

You could create this kind of plot by reshaping your data into rows of containing name, value and group and plot it like a scatter plot, but here's another way that doesn't require all that data manipulation and takes advantage of Layer Cake's accessor shorthand. In main.js, we simply specify the names of the keys in each row that we want to plot and in the layer component, we call $xGet(row) to map each object into an array of pixel values.

<script>
  import { LayerCake, Html } from 'layercake';
  import { scaleBand, scaleOrdinal } from 'd3-scale';

  import ClevelandDotPlot from './_components/ClevelandDotPlot.percent-range.html.svelte';
  import AxisX from './_components/AxisX.percent-range.html.svelte';
  import AxisY from './_components/AxisY.percent-range.html.svelte';

  // This example loads csv data as json using @rollup/plugin-dsv
  import data from './_data/fruitOrdinal.csv';

  const yKey = 'year';
  const xKey = Object.keys(data[0]).filter(d => d !== yKey);

  const seriesColors = ['#f0c', '#00bbff', '#00e047', '#ff7a33'];

  data.forEach(d => {
    xKey.forEach(name => {
      d[name] = +d[name];
    });
  });
</script>

<div class="chart-container">
  <LayerCake
    ssr
    percentRange
    padding={{ right: 10, bottom: 20, left: 30 }}
    x={xKey}
    y={yKey}
    yScale={scaleBand().paddingInner(0.05).round(true)}
    xDomain={[0, null]}
    xPadding={[2, 0]}
    zScale={scaleOrdinal()}
    zDomain={xKey}
    zRange={seriesColors}
    {data}
  >
    <Html>
      <AxisX />
      <AxisY gridlines={false} />
      <ClevelandDotPlot />
    </Html>
  </LayerCake>
</div>

<style>
  /*
    The wrapper div needs to have an explicit width and height in CSS.
    It can also be a flexbox child or CSS grid element.
    The point being it needs dimensions since the <LayerCake> element will
    expand to fill it.
  */
  .chart-container {
    width: 100%;
    height: 250px;
  }
</style>