Archived

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

Menu

WebGL Scatter (svg axes, quadtree hover)

A scatter plot drawn with WebGL, with SVG axes and a QuadTree layer that marks the nearest point on hover. The WebGL component uses regl and draws every point in one call, so it suits large datasets.

<script>
  import { LayerCake, Svg, WebGL, Html } from 'layercake';

  import ScatterWebgl from './_components/Scatter.webgl.svelte';
  import AxisX from './_components/AxisX.svelte';
  import AxisY from './_components/AxisY.svelte';
  import QuadTree from './_components/QuadTree.html.svelte';

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

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

  const r = 3;
  const xyPadding = 6;
</script>

<div class="chart-container">
  <LayerCake
    padding={{ top: 5, right: 5, bottom: 20, left: 25 }}
    x={xKey}
    y={yKey}
    xPadding={[xyPadding, xyPadding]}
    yPadding={[xyPadding, xyPadding]}
    {data}
  >
    <Svg>
      <AxisX />
      <AxisY tickMarks={false} ticks={5} />
    </Svg>

    <WebGL>
      <ScatterWebgl {r} />
    </WebGL>

    <Html>
      <QuadTree>
        {#snippet children({ x, y, visible })}
          <div
            class="circle"
            style="top:{y}px;left:{x}px;display: {visible ? 'block' : 'none'};"
          ></div>
        {/snippet}
      </QuadTree>
    </Html>
  </LayerCake>
</div>

<style>
  /* Give the wrapper a width and height. LayerCake fills it. */
  .chart-container {
    width: 100%;
    height: 250px;
  }
  .circle {
    position: absolute;
    border-radius: 50%;
    background-color: rgba(171, 0, 214);
    transform: translate(-50%, -50%);
    pointer-events: none;
    width: 10px;
    height: 10px;
  }
</style>