import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from 'recharts';
import type { TimeseriesItem } from '@family-budget/shared';
import { useMediaQuery } from '../hooks/useMediaQuery';
interface Props {
data: TimeseriesItem[];
}
const rubFormatter = new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
maximumFractionDigits: 0,
});
export function TimeseriesChart({ data }: Props) {
const isMobile = useMediaQuery('(max-width: 600px)');
const chartHeight = isMobile ? 250 : 300;
if (data.length === 0) {
return
Нет данных за период
;
}
const chartData = data.map((item) => ({
period: item.periodStart,
Расходы: Math.abs(item.expenseAmount) / 100,
Доходы: item.incomeAmount / 100,
Инвестиции: Math.abs(item.investmentOutflow) / 100,
}));
return (
{
const d = new Date(v);
return `${d.getDate()}.${String(d.getMonth() + 1).padStart(2, '0')}`;
}}
fontSize={12}
stroke="var(--color-text-secondary)"
tickLine={false}
axisLine={false}
/>
v >= 1000 ? `${(v / 1000).toFixed(0)}к` : String(v)
}
fontSize={12}
stroke="var(--color-text-secondary)"
tickLine={false}
axisLine={false}
/>
rubFormatter.format(value)}
cursor={{ fill: 'var(--color-chart-cursor)' }}
contentStyle={{
border: '1px solid var(--color-border)',
borderRadius: 8,
boxShadow: 'var(--shadow-lg)',
}}
/>
);
}