import { ComposedChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts'; import type { DataSeries } from '@/lib/types'; import { getChartColors } from '../utils/chart-colors'; import { ChartTooltip } from '../primitives/chart-tooltip'; import { mergeDataSeries } from '../utils/chart-data-transformers'; type CombinationChartViewProps = { dataSeries: DataSeries[]; formatters?: { price?: (value: number) => string; date?: (value: string) => string; volume?: (value: number) => string; }; }; export function CombinationChartView({ dataSeries, formatters }: CombinationChartViewProps) { const colors = getChartColors(); if (!dataSeries || dataSeries.length === 0) { return (
No data series provided
); } const mergedData = mergeDataSeries(dataSeries); const visibleSeries = dataSeries.filter(series => series.visible !== false); const baseValues = Object.fromEntries(visibleSeries.map((series) => { const initialPoint = mergedData.find((entry) => typeof entry[series.id] === 'number'); const baseValue = typeof initialPoint?.[series.id] === 'number' ? Number(initialPoint[series.id]) : null; return [series.id, baseValue]; })); const normalizedData = mergedData.map((point) => { const normalizedPoint: Record = { date: point.date }; visibleSeries.forEach((series) => { const baseValue = baseValues[series.id]; const currentValue = typeof point[series.id] === 'number' ? Number(point[series.id]) : null; normalizedPoint[series.id] = baseValue && currentValue ? ((currentValue / baseValue) - 1) * 100 : null; }); return normalizedPoint; }); return ( `${Number(value).toFixed(0)}%`} width={60} domain={['auto', 'auto']} /> ( `${value.toFixed(2)}%` }} /> )} cursor={{ stroke: colors.muted, strokeDasharray: '3 3' }} /> {visibleSeries.map(series => { const seriesColor = series.color || colors.primary; return ( ); })} ); }