TanStack
Catalog

Bubble scatterplot

relationship

89 lines · 2 files · 2.4 kB

cases/scatter-bubble/example.tsx65 lines · entry
cases/scatter-bubble/example.tsx
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip as exampleTooltip } from '@tanstack/charts/tooltip'

import { colorLegend, defineChart, dot } from '@tanstack/charts'
import { scaleLinear, scaleSqrt } from 'd3-scale'
import { bubbleRows } from './model'

const groupRange = ['#2563eb', '#f97316', '#10b981']

export const createExampleChart = (input: ChartOptions) => {
  const rows = bubbleRows(input.revision)

  return defineChart(
    {
      marks: [
        dot(rows, {
          key: (row) =>
            `${row.species}:${row.island}:${row.culmen_length_mm}:${row.culmen_depth_mm}:${row.flipper_length_mm}:${row.body_mass_g}:${row.sex}`,
          x: 'culmen_length_mm',
          y: 'culmen_depth_mm',
          color: 'species',
          r: 'body_mass_g',
          rScale: {
            scale: () => scaleSqrt().range([3, 11]),
          },
          fillOpacity: 0.78,
          stroke: 'currentColor',
          strokeOpacity: 0.28,
          strokeWidth: 0.75,
        }),
      ],
      scales: {
        x: {
          scale: scaleLinear,
          grid: true,
          axis: { label: 'Bill length (mm)' },
        },
        y: {
          scale: scaleLinear,
          grid: true,
          axis: { label: 'Bill depth (mm)' },
        },
      },

      color: {
        range: groupRange,
        legend: colorLegend({ label: 'Species' }),
      },
    },
    { keyboard: true, tooltip: exampleTooltip },
  )
}
export interface ChartOptions {
  revision: number
}

export const exampleAriaLabel = 'Bubble scatterplot'

export const chart = createExampleChart({
  revision: 0,
})

export default function Example() {
  return <Chart ariaLabel={exampleAriaLabel} definition={chart} height={480} />
}
cases/scatter-bubble/model.ts24 lines · dependency
cases/scatter-bubble/model.ts
import { penguins } from '@tanstack/charts-data/penguins'
import type { PenguinsRow } from '@tanstack/charts-data/penguins'

export type BubblePenguin = PenguinsRow & {
  culmen_length_mm: number
  culmen_depth_mm: number
  body_mass_g: number
}

const completePenguins = penguins.filter(isBubblePenguin)

export function bubbleRows(revision: number): readonly BubblePenguin[] {
  return completePenguins
    .slice(revision * 8, revision * 8 + 320)
    .sort((left, right) => right.body_mass_g - left.body_mass_g)
}

function isBubblePenguin(row: PenguinsRow): row is BubblePenguin {
  return (
    row.culmen_length_mm !== null &&
    row.culmen_depth_mm !== null &&
    row.body_mass_g !== null
  )
}