89 lines · 2 files · 2.5 kB
cases/28-candlestick/example.tsx81 lines · entry
cases/28-candlestick/example.tsx
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip as exampleTooltip } from '@tanstack/charts/tooltip'
import { defineChart, link } from '@tanstack/charts'
import { aapl } from '@tanstack/charts-data/aapl'
import { scaleLinear, scaleUtc } from 'd3-scale'
import { selectCandleData } from './selection'
const candleDate = new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
timeZone: 'UTC',
})
const price = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})
export const createExampleChart = (input: ChartOptions) => {
const rows = selectCandleData(aapl, input.revision)
const gains = rows.filter((row) => row.Close >= row.Open)
const losses = rows.filter((row) => row.Close < row.Open)
return defineChart(
{
marks: [
link(rows, {
x1: 'Date',
y1: 'Low',
x2: 'Date',
y2: 'High',
stroke: '#64748b',
strokeWidth: 1,
}),
link(gains, {
x1: 'Date',
y1: 'Open',
x2: 'Date',
y2: 'Close',
stroke: '#10b981',
strokeWidth: 5,
}),
link(losses, {
x1: 'Date',
y1: 'Open',
x2: 'Date',
y2: 'Close',
stroke: '#ef4444',
strokeWidth: 5,
}),
],
scales: {
x: { scale: scaleUtc },
y: { scale: scaleLinear, grid: true, axis: { label: 'Price' } },
},
},
{
keyboard: true,
tooltip: {
use: exampleTooltip,
...{
format: (point) =>
`${candleDate.format(point.datum.Date)} · Open: ${price.format(point.datum.Open)} · High: ${price.format(point.datum.High)} · Low: ${price.format(point.datum.Low)} · Close: ${price.format(point.datum.Close)}`,
},
},
},
)
}
export interface ChartOptions {
revision: number
}
export const exampleAriaLabel = 'Apple daily candlestick chart'
export const chart = createExampleChart({
revision: 0,
})
export default function Example() {
return <Chart ariaLabel={exampleAriaLabel} definition={chart} height={480} />
}cases/28-candlestick/selection.ts8 lines · dependency
cases/28-candlestick/selection.ts
import type { AaplRow } from '@tanstack/charts-data/aapl'
const sessionsPerView = 30
export function selectCandleData(rows: readonly AaplRow[], revision = 0) {
const start = Math.abs(revision % 2) * sessionsPerView
return rows.slice(start, start + sessionsPerView)
}