Menu

Stacked area

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.

import { default as LayerCake, flatten } from 'layercake';
import { stack } from 'd3-shape';
import fruit from './data/fruit.js';
import AreaStacked from './components/AreaStacked.html';
import AxisX from './components/AxisX.html';
import AxisY from './components/AxisY.html';

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

/* --------------------------------------------
 * 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 formatXTick (d) {
  const date = new Date(d);
  return `${monthNames[date.getMonth()]} ${date.getDate()}`;
}

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

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

const myCake = new LayerCake({
  padding: { top: 0, right: 0, bottom: 20, left: 17 },
  x: d => d.data.month,
  y: [0, 1],
  // Because our stacked data is an array of arrays and we need a flat area to measure extents, pass a flat version to the extents calculator
  flatData: flatten(series),
  data: series,
  target: document.getElementById('my-chart'),
  seriesNames_: seriesNames
})
  .svgLayers([
    { component: AxisX, opts: { formatTick: formatXTick, tickNumber: 3 } },
    { component: AxisY, opts: { formatTick: formatYTick } },
    { component: AreaStacked, opts: { colors } }
  ]);

myCake.render();