Skip to content
CodeAtlas UI

Charts

ScatterChart

Correlation plots, bubble charts and clustered scatter by group.

<script>
  import { ScatterChart } from "@codeatlasdev/ui/charts";
</script>

<ScatterChart series={[{ name: "Accounts", data: [[1200, 3.4], [4800, 5.1]] }]} yName="Conversion %" />

Points are [x, y] or [x, y, size]. When any point has a third value the chart switches to bubble mode automatically and scales the symbols by size.

Basic scatter

Visits against conversion rate.

Code
svelte
<script lang="ts">
  import { GlassCard } from '@codeatlasdev/ui';
  import { ScatterChart } from '@codeatlasdev/ui/charts';

  const data = Array.from({ length: 80 }, (_, i): [number, number] => [
    Math.round(500 + 14500 * (0.5 + 0.5 * Math.sin(i * 0.31 + 1.2)) * (0.7 + 0.3 * Math.cos(i * 0.17))),
    parseFloat((0.5 + 13.5 * (0.5 + 0.5 * Math.cos(i * 0.23 + 0.8)) * (0.6 + 0.4 * Math.sin(i * 0.41))).toFixed(2)),
  ]);
</script>

<GlassCard full>
  <ScatterChart series={[{ name: 'Data points', data }]} yName="Conversion %" yFormatter={(v) => `${v.toFixed(1)}%`} height="320px" />
</GlassCard>

Bubble chart

The third value of each point sets the bubble size.

Code
svelte
<script lang="ts">
  import { GlassCard } from '@codeatlasdev/ui';
  import { ScatterChart } from '@codeatlasdev/ui/charts';

  // The third value of each point is the bubble size.
  const data = Array.from({ length: 50 }, (_, i): [number, number, number] => [
    Math.round(1000 + 13000 * (0.5 + 0.5 * Math.sin(i * 0.43 + 0.6)) * (0.65 + 0.35 * Math.cos(i * 0.19))),
    parseFloat((1 + 12 * (0.5 + 0.5 * Math.cos(i * 0.37 + 1.1)) * (0.7 + 0.3 * Math.sin(i * 0.53))).toFixed(2)),
    Math.round(1000 + 49000 * Math.abs(Math.sin(i * 0.29 + 0.4)) * Math.abs(Math.cos(i * 0.11))),
  ]);
</script>

<GlassCard full>
  <ScatterChart series={[{ name: 'Accounts', data }]} yName="Conversion %" yFormatter={(v) => `${v.toFixed(1)}%`} height="340px" />
</GlassCard>

Clustered by tier

One series per group, each with its own palette color.

Code
svelte
<script lang="ts">
  import { GlassCard } from '@codeatlasdev/ui';
  import { ScatterChart, type ScatterSeries } from '@codeatlasdev/ui/charts';

  const cluster = (n: number, x0: number, xr: number, y0: number, yr: number, a: number, b: number, c: number, d: number) =>
    Array.from({ length: n }, (_, i): [number, number] => [
      Math.round(x0 + xr * (0.5 + 0.5 * Math.sin(i * a + b))),
      parseFloat((y0 + yr * (0.5 + 0.5 * Math.cos(i * c + d))).toFixed(2)),
    ]);

  // `color` is optional: omit it and the palette assigns one per series.
  const series: ScatterSeries[] = [
    { name: 'Premium', data: cluster(30, 9000, 5500, 8, 5.5, 0.53, 0.7, 0.47, 0.3) },
    { name: 'Standard', data: cluster(30, 4500, 4000, 3.5, 4, 0.61, 1.4, 0.39, 0.9) },
    { name: 'Free', data: cluster(30, 500, 3500, 0.5, 2.5, 0.71, 2.1, 0.59, 1.7) },
  ];
</script>

<GlassCard full>
  <ScatterChart {series} yName="Conversion %" yFormatter={(v) => `${v.toFixed(1)}%`} height="340px" />
</GlassCard>

Props

PropTypeDefaultDescription
seriesScatterSeries[]–Named series as { name, data: [x, y] | [x, y, size][], color? }.
xNamestring–Label of the x axis.
yNamestring–Label of the y axis.
xFormatter(v: number) => string–Formats x ticks and tooltip. Overrides valueFormatter for x.
yFormatter(v: number) => string–Formats y ticks and tooltip. Overrides valueFormatter for y.
valueFormatter(v: number) => string–Fallback formatter used for both axes.
heightstring'320px'CSS height of the chart.
classstring''Extra class names.