import React, { Suspense } from 'react'; import { Box, Typography } from '@mui/material'; import { LazyLineChart, Line, XAxis, YAxis, Tooltip as RechartsTooltip, ResponsiveContainer, ChartLoadingFallback } from '../../utils/lazyRecharts'; interface MiniSparklineProps { data: Array<{ date: string; value: number }>; color: string; height?: number; showArea?: boolean; formatValue?: (value: number) => string; label?: string; } /** * MiniSparkline - Enhanced trend line chart for metric cards with axes and tooltips * * Usage: * `$${v.toFixed(2)}`} * label="Cost" * /> */ export const MiniSparkline: React.FC = ({ data, color, height = 60, showArea = false, formatValue = (v) => v.toLocaleString(), label = 'Value' }) => { // Ensure we have data if (!data || data.length === 0) { return ( No data available ); } // If only one data point, duplicate it for visual consistency const chartData = data.length === 1 ? [data[0], { ...data[0], value: data[0].value }] : data; // Calculate min/max for Y-axis domain const values = chartData.map(d => d.value); const minValue = Math.min(...values); const maxValue = Math.max(...values); const padding = (maxValue - minValue) * 0.1 || 0.1; // Format date for X-axis const formatDate = (dateStr: string) => { try { const date = new Date(dateStr); if (isNaN(date.getTime())) return dateStr; // Show day of month for daily data return date.getDate().toString(); } catch { return dateStr; } }; // Custom tooltip const CustomTooltip = ({ active, payload }: any) => { if (active && payload && payload.length) { const data = payload[0].payload; return ( {new Date(data.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} {label}: {formatValue(data.value)} ); } return null; }; return ( }> { if (value >= 1000) return `${(value / 1000).toFixed(1)}k`; if (value >= 1) return value.toFixed(0); return value.toFixed(2); }} stroke="rgba(255,255,255,0.5)" tick={{ fill: 'rgba(255,255,255,0.5)', fontSize: 10 }} width={40} /> } /> ); }; export default MiniSparkline;