TanStack
Catalog

Two-dimensional vector field

spatial

55 lines · 2 files · 1.8 kB

cases/42-vector-field/example.tsx37 lines · entry
cases/42-vector-field/example.tsx
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip as exampleTooltip } from '@tanstack/charts/tooltip'

import { defineChart, vector } from '@tanstack/charts'
import { wind } from '@tanstack/charts-data/wind'
import { scaleLinear, scaleSqrt } from 'd3-scale'
import { sampleWind } from './selection'

const speed = scaleSqrt().domain([0, 14]).range([0, 22])
const sampledWind = sampleWind(wind)

export const createExampleChart = () =>
  defineChart(
    {
      marks: [
        vector(sampledWind, {
          id: 'wind-vectors',
          x: 'longitude',
          y: 'latitude',
          length: (row) => speed(Math.hypot(row.u, row.v)),
          rotate: (row) => (Math.atan2(row.u, row.v) * 180) / Math.PI,
          stroke: '#2563eb',
        }),
      ],
      x: { scale: scaleLinear, grid: true, axis: { label: 'Longitude' } },
      y: { scale: scaleLinear, grid: true, axis: { label: 'Latitude' } },
    },
    { keyboard: true, tooltip: exampleTooltip },
  )

export const exampleAriaLabel = 'Two-dimensional vector field'

export const chart = createExampleChart()

export default function Example() {
  return <Chart ariaLabel={exampleAriaLabel} definition={chart} height={480} />
}
cases/42-vector-field/selection.ts18 lines · dependency
cases/42-vector-field/selection.ts
import type { WindRow } from '@tanstack/charts-data/wind'

export function sampleWind(rows: readonly WindRow[]) {
  const longitudes = [...new Set(rows.map((row) => row.longitude))]
  const latitudes = [...new Set(rows.map((row) => row.latitude))]
  const selectedLongitudes = new Set(
    [0, 16, 32, 48, 64, 79].map((index) => longitudes[index]),
  )
  const selectedLatitudes = new Set(
    [0, 15, 30, 45, 59].map((index) => latitudes[index]),
  )

  return rows.filter(
    (row) =>
      selectedLongitudes.has(row.longitude) &&
      selectedLatitudes.has(row.latitude),
  )
}