Menu

Cleveland dot plotEdit

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, Svg } from 'layercake';
  import { scaleBand, scaleOrdinal } from 'd3-scale';

  import ClevelandDotPlot from './_components/ClevelandDotPlot.svelte';
  import AxisX from './_components/AxisX.svelte';
  import AxisY from './_components/AxisY.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>

<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>

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