Archived

Documentation for Layer Cake v10, before Svelte 5 runes. Current docs at layercake.graphics

Menu

Synced brush

1980
1990
2000
2010
0
5
1980
1990
2000
2010
0
10
1980
1990
2000
2010
0
10
1980
1990
2000
2010
0
10

Four charts sharing one brush. Each SyncedBrushWrapper.percent-range.svelte holds a chart and a brush and exposes min and max as bindable props. Binding all four to the same values keeps them in step, so dragging any brush zooms every chart.

This is the server-side rendered version. ssr and percentRange on <LayerCake> put the scales in percentages, so the chart renders before the browser measures it. The axes are HTML components and the marks sit in a <ScaledSvg> that stretches to fit its box.

<script>
  import SyncedBrushWrapper from './_components/SyncedBrushWrapper.percent-range.svelte';

  // The CSV rows are parsed, and their numbers typed, by @rollup/plugin-dsv. See vite.config.js
  import pointsOne from './_data/points.csv';
  import pointsTwo from './_data/pointsTwo.csv';
  import pointsThree from './_data/pointsThree.csv';
  import pointsFour from './_data/pointsFour.csv';

  // One brush range shared by every chart
  /** @type {[number|null, number|null]} */
  let brushExtents = $state([null, null]);

  const xKey = 'myX';
  const yKey = 'myY';

  const datasets = [pointsOne, pointsTwo, pointsThree, pointsFour];

  const colors = ['#00e047', '#00bbff', '#ff00cc', '#ffcc00'];
</script>

<div class="chart-container">
  {#each datasets as dataset, i}
    <SyncedBrushWrapper
      data={dataset}
      {xKey}
      {yKey}
      bind:min={brushExtents[0]}
      bind:max={brushExtents[1]}
      stroke={colors[i]}
    />
  {/each}
</div>

<style>
  /* Give the wrapper a width and height. LayerCake fills it. */
  .chart-container {
    width: 100%;
    height: 250px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-content: space-between;
  }
</style>