Menu

Multiline (html labels + quadtree tooltip)

A fancy example with a quadtree tooltip lines that change their z-position based on whichever has the highest value at that hover position.

import LayerCake from 'layercake';
import fruit from './data/fruit.js';
import MultiLine from './components/MultiLine.html';
import AxisX from './components/AxisX.html';
import AxisY from './components/AxisY.html';
import LineLabels from './components/LineLabels.html';
import Tooltip from './components/Tooltip.html';

const fruitLong = Object.keys(fruit[0]).map(key => {
  if (key === 'month') return null;
  return {
    key,
    values: fruit.map(d => {
      return { key, month: d.month, value: d[key] };
    })
  };
}).filter(d => d);

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 d / 1000 + 'k';
  }
  return d;
}

// Make a flat array of the `values` of our nested series
// we can pluck the `value` field from each item in the array to measure extents
const flatten = data => data.reduce((store, group) => store.concat(group.values), []);

const myCake = new LayerCake({
  padding: { top: 7, right: 10, bottom: 20, left: 25 },
  x: 'month',
  y: 'value',
  flatData: flatten(fruitLong),
  yDomain: [0, null],
  data: fruitLong,
  target: document.getElementById('my-chart'),
  fruit_: fruit
})
  .svgLayers([
    { component: AxisX, opts: { gridlines: false, tickNumber: 3, formatTick: formatXTick } },
    { component: AxisY, opts: { formatTick: formatYTick } },
    { component: MultiLine, opts: {} }
  ])
  .htmlLayers([
    { component: LineLabels, opts: {} },
    { component: Tooltip, opts: {} }
  ]);

myCake.render();