Files
Neon-Desk/components/charts/renderers/line-chart-view.tsx

101 lines
2.5 KiB
TypeScript

import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer
} from 'recharts';
import type { ChartDataPoint } from '@/lib/types';
import { getChartColors } from '../utils/chart-colors';
import { ChartTooltip } from '../primitives/chart-tooltip';
import { isPriceData, isOHLCVData } from '../utils/chart-data-transformers';
type LineChartViewProps = {
data: ChartDataPoint[];
formatters?: {
price?: (value: number) => string;
date?: (value: string) => string;
volume?: (value: number) => string;
};
};
export function LineChartView({
data,
formatters
}: LineChartViewProps) {
const colors = getChartColors();
const chartData = data.map(point => {
if (isOHLCVData(point)) {
return {
date: point.date,
price: point.close,
open: point.open,
high: point.high,
low: point.low,
close: point.close,
volume: point.volume
};
} else if (isPriceData(point)) {
return {
date: point.date,
price: point.price
};
}
return point;
});
return (
<ResponsiveContainer width="100%" height="100%">
<LineChart data={chartData} margin={{ top: 5, right: 5, left: 5, bottom: 5 }}>
<CartesianGrid
strokeDasharray="3 3"
stroke={colors.grid}
vertical={false}
/>
<XAxis
dataKey="date"
stroke={colors.muted}
fontSize={11}
tickFormatter={formatters?.date}
minTickGap={50}
axisLine={{ stroke: colors.grid }}
tickLine={false}
/>
<YAxis
stroke={colors.muted}
fontSize={11}
tickFormatter={formatters?.price}
width={65}
domain={['auto', 'auto']}
axisLine={false}
tickLine={false}
orientation="right"
/>
<Tooltip
content={(tooltipProps) => <ChartTooltip {...tooltipProps} formatters={formatters} />}
cursor={{ stroke: colors.muted, strokeWidth: 1, strokeDasharray: '5 5' }}
isAnimationActive={false}
/>
<Line
type="linear"
dataKey="price"
stroke={colors.primary}
strokeWidth={2}
dot={false}
activeDot={{
r: 4,
stroke: colors.primary,
strokeWidth: 2,
fill: colors.tooltipBg
}}
isAnimationActive={false}
connectNulls={true}
/>
</LineChart>
</ResponsiveContainer>
);
}