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, ScaledSvg, Html, flatten } from 'layercake';
  import { stack } from 'd3-shape';
  import { scaleOrdinal } from 'd3-scale';
  import { format, precisionFixed } from 'd3-format';
  import { timeParse, timeFormat } from 'd3-time-format';

  import AxisX from './components/AxisX.html.svelte';
  import AxisY from './components/AxisY.html.svelte';
  import AreaStacked from './components/AreaStacked.svelte';

  import data from './data/fruit.csv';

  const xKey = 'month';
  const yKey = [0, 1];
  const zKey = 'key';

  const parseDate = timeParse('%Y-%m-%d');

  const seriesNames = Object.keys(data[0]).filter(d => d !== xKey);
  const seriesColors = ['#ff00cc', '#ff7ac7', '#ffb3c0', '#ffe4b8'];

  data.forEach(d => {
    d[xKey] = typeof d[xKey] === 'string' ? parseDate(d[xKey]) : d[xKey];
    seriesNames.forEach(name => {
      d[name] = +d[name];
    });
  });

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

  const series = stackData(data);

  const formatTickX = timeFormat('%b. %-d')
  const formatTickY = d => format(`.${precisionFixed(d)}s`)(d);
</script>

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

<div class="chart-container">
  <LayerCake
    ssr={true}
    percentRange={true}
    padding={{ top: 0, right: 0, bottom: 20, left: 17 }}
    x={d => d.data[xKey]}
    y={yKey}
    z={zKey}
    zScale={scaleOrdinal()}
    zDomain={seriesNames}
    zRange={seriesColors}
    flatData={flatten(series)}
    data={series}
  >
    <Html>
      <AxisX
        formatTick={formatTickX}
      />
      <AxisY
        baseline={true}
        formatTick={formatTickY}
      />
    </Html>
    <ScaledSvg>
      <AreaStacked/>
    </ScaledSvg>
  </LayerCake>
</div>