104 lines · 2 files · 2.9 kB
cases/107-polar-scatter/example.tsx85 lines · entry
cases/107-polar-scatter/example.tsx
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip as exampleTooltip } from '@tanstack/charts/tooltip'
import { defineChart } from '@tanstack/charts'
import { angleGrid, polar, radialDot, radialGrid } from '@tanstack/charts/polar'
import { scaleLinear } from 'd3-scale'
import { windDirection, windLatitudeBand, windSpeed } from './transform'
const angleDomain = [0, 360] as const
const radiusDomain = [0, 13] as const
const angleGridValues = [0, 45, 90, 135, 180, 225, 270, 315] as const
const radiusGridValues = [3, 6, 9, 12] as const
const dotColor = '#e11d48'
const gridColor = '#94a3b8'
export const createExampleChart = (input: ChartOptions) => {
const rows = windLatitudeBand(input.revision)
return defineChart(
{
marks: [
polar({
radiusRatio: 0.72,
scales: {
angle: { scale: scaleLinear().domain(angleDomain) },
radius: { scale: scaleLinear().domain(radiusDomain) },
},
guides: [
radialGrid({
values: radiusGridValues,
labels: false,
stroke: gridColor,
strokeOpacity: 0.35,
}),
angleGrid({
values: angleGridValues,
labels: false,
stroke: gridColor,
strokeOpacity: 0.35,
}),
],
marks: [
radialDot(rows, {
angle: windDirection,
radius: windSpeed,
r: 4.5,
fill: dotColor,
stroke: '#ffffff',
strokeWidth: 1,
}),
],
}),
],
scales: {
x: null,
y: null,
},
margin: 0,
},
{
keyboard: true,
tooltip: {
use: exampleTooltip,
...{
format: ({ datum }) =>
`${datum.latitude}°N, ${datum.longitude}°E · ${windSpeed(datum).toFixed(1)} m/s`,
},
},
},
)
}
export interface ChartOptions {
revision: number
}
export const exampleAriaLabel = 'Surface wind polar scatter'
export const chart = createExampleChart({
revision: 0,
})
export default function Example() {
return <Chart ariaLabel={exampleAriaLabel} definition={chart} height={480} />
}cases/107-polar-scatter/transform.ts19 lines · dependency
cases/107-polar-scatter/transform.ts
import { wind } from '@tanstack/charts-data/wind'
import type { WindRow } from '@tanstack/charts-data/wind'
const selectableLatitudeBands = [48.125, 55.125] as const
export function windLatitudeBand(revision = 0): readonly WindRow[] {
const latitude =
selectableLatitudeBands[revision % selectableLatitudeBands.length] ??
selectableLatitudeBands[0]
return wind.filter((row) => row.latitude === latitude)
}
export function windDirection(row: WindRow): number {
return (Math.atan2(row.v, row.u) * (180 / Math.PI) + 360) % 360
}
export function windSpeed(row: WindRow): number {
return Math.hypot(row.u, row.v)
}