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 (
);
})}
);
}