Menu

Stacked areaEdit

Jan. 11 Jan. 23 Feb. 3 Feb. 15 Feb. 26 Mar. 10 Mar. 22 0 2k 4k 6k

Stack area charts using D3's stack function. Because this will create a nested data structure, we use LayerCake's flatten function and the flatData option from which we measure the extents.

<script>
  import { LayerCake, Svg, flatten } from 'layercake';
  import { stack } from 'd3-shape';
  import fruit from './data/fruit.csv';
  import AxisX from './components/AxisX.svelte';
  import AxisY from './components/AxisY.svelte';
  import AreaStacked from './components/AreaStacked.svelte';

  const seriesNames = Object.keys(fruit[0]).filter(d => d !== 'month');

  fruit.forEach(row => {
    row.month = new Date(row.month);
    seriesNames.forEach(name => {
      row[name] = +row[name];
    });
  });

  const seriesColors = ['#ff00cc', '#ff7ac7', '#ffb3c0', '#ffe4b8'];

  /* --------------------------------------------
   * Create a stacked data structure
   */
  const stackData = stack()
    .keys(seriesNames);

  const series = stackData(fruit);

  const monthNames = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'June', 'July', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'];

  function formatTickX (d) {
    const date = new Date(d);
    return `${monthNames[date.getMonth()]} ${date.getDate()}`;
  }

  function formatTickY (d) {
    if (d > 999) {
      return Math.round(d / 1000) + 'k';
    }
    return d;
  }
</script>

<style>
  .chart-container {
    width: 100%;
    height: 100%;
  }
</style>

<div class="chart-container">
  <LayerCake
    padding={{ top: 0, right: 0, bottom: 20, left: 17 }}
    x={d => d.data.month}
    y={[0, 1]}
    flatData={flatten(series)}
    data={series}
  >
    <Svg>
      <AxisX
        formatTick={formatTickX}
      />
      <AxisY
        formatTick={formatTickY}
      />
      <AreaStacked
        {seriesColors}
        {seriesNames}
      />
    </Svg>
  </LayerCake>
</div>