72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
import {
|
|
ComposedChart,
|
|
XAxis,
|
|
YAxis,
|
|
CartesianGrid,
|
|
Tooltip,
|
|
ResponsiveContainer,
|
|
Scatter
|
|
} from 'recharts';
|
|
import type { ChartDataPoint } from '@/lib/types';
|
|
import { getChartColors } from '../utils/chart-colors';
|
|
import { ChartTooltip } from '../primitives/chart-tooltip';
|
|
import { CandlestickShape } from '../utils/candlestick-shapes';
|
|
import { isOHLCVData } from '../utils/chart-data-transformers';
|
|
|
|
type CandlestickChartViewProps = {
|
|
data: ChartDataPoint[];
|
|
formatters?: {
|
|
price?: (value: number) => string;
|
|
date?: (value: string) => string;
|
|
volume?: (value: number) => string;
|
|
};
|
|
};
|
|
|
|
export function CandlestickChartView({
|
|
data,
|
|
formatters
|
|
}: CandlestickChartViewProps) {
|
|
const colors = getChartColors();
|
|
|
|
const ohlcvData = data.filter(isOHLCVData);
|
|
|
|
if (ohlcvData.length === 0) {
|
|
return (
|
|
<div className="flex h-full items-center justify-center text-sm text-[color:var(--terminal-muted)]">
|
|
Candlestick chart requires OHLCV data
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<ComposedChart data={ohlcvData}>
|
|
<CartesianGrid strokeDasharray="2 2" stroke={colors.grid} />
|
|
<XAxis
|
|
dataKey="date"
|
|
stroke={colors.muted}
|
|
fontSize={11}
|
|
tickFormatter={formatters?.date}
|
|
minTickGap={32}
|
|
/>
|
|
<YAxis
|
|
stroke={colors.muted}
|
|
fontSize={11}
|
|
tickFormatter={formatters?.price}
|
|
width={60}
|
|
domain={['auto', 'auto']}
|
|
/>
|
|
<Tooltip
|
|
content={(tooltipProps) => <ChartTooltip {...tooltipProps} formatters={formatters} />}
|
|
cursor={{ stroke: colors.muted, strokeDasharray: '3 3' }}
|
|
/>
|
|
<Scatter
|
|
dataKey="close"
|
|
shape={<CandlestickShape />}
|
|
isAnimationActive={false}
|
|
/>
|
|
</ComposedChart>
|
|
</ResponsiveContainer>
|
|
);
|
|
}
|