Menu

Multiline (html labels + quadtree tooltip)Edit

Jan. 1
Feb. 1
Mar. 1
Apr. 1
0
1k
2k
3k
Apples
Bananas
Cherries
Dates

A multiline example with a quadtree tooltip.

<script>
  import { LayerCake, ScaledSvg, Html } from 'layercake';
  import { scaleOrdinal } from 'd3-scale';
  import { timeParse, timeFormat } from 'd3-time-format';
  import { format, precisionFixed } from 'd3-format';

  import MultiLine from './components/MultiLine.svelte';
  import AxisX from './components/AxisX.html.svelte';
  import AxisY from './components/AxisY.html.svelte';
  import Labels from './components/Labels.svelte';
  import SharedTooltip from './components/SharedTooltip.percent-range.svelte';

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

  /* --------------------------------------------
   * Set what is our x key to separate it from the other series
   */
  const xKey = 'month';
  const yKey = 'value';
  const zKey = 'key';

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

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

  const dataLong = seriesNames.map(key => {
    return {
      key,
      values: data.map(d => {
        d[xKey] = typeof d[xKey] === 'string' ? parseDate(d[xKey]) : d[xKey]; // Conditional required for sapper
        return {
          key,
          [yKey]: +d[key],
          [xKey]: d[xKey]
        };
      })
    };
  });

  // 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((memo, group) => {
    return memo.concat(group.values);
  }, []);

  const formatTickX = timeFormat('%b. %e');
  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: 7, right: 10, bottom: 20, left: 25 }}
    x={xKey}
    y={yKey}
    z={zKey}
    zScale={scaleOrdinal()}
    zDomain={seriesNames}
    zRange={seriesColors}
    flatData={flatten(dataLong)}
    yDomain={[0, null]}
    data={dataLong}
  >
    <Html>
      <AxisX
        gridlines={false}
        ticks={data.map(d => d[xKey]).sort((a, b) => a - b)}
        formatTick={formatTickX}
        snapTicks={true}
      />
      <AxisY
        baseline={true}
        formatTick={formatTickY}
      />
    </Html>

    <ScaledSvg>
      <MultiLine/>
    </ScaledSvg>

    <Html>
      <Labels/>
      <SharedTooltip
        formatTitle={formatTickX}
        dataset={data}
      />
    </Html>
  </LayerCake>
</div>