localgreenchain/components/analytics/charts/AreaChart.tsx
Claude 816c3b3f2e
Implement Agent 7: Advanced Analytics Dashboard
Add comprehensive analytics system with:
- Analytics data layer (aggregator, metrics, trends, cache)
- 6 API endpoints (overview, plants, transport, farms, sustainability, export)
- 6 chart components (LineChart, BarChart, PieChart, AreaChart, Gauge, Heatmap)
- 5 dashboard widgets (KPICard, TrendIndicator, DataTable, DateRangePicker, FilterPanel)
- 5 dashboard pages (overview, plants, transport, farms, sustainability)
- Export functionality (CSV, JSON)

Dependencies added: recharts, d3, date-fns

Also includes minor fixes:
- Fix EnvironmentalForm spread type error
- Fix AgentOrchestrator Map iteration issues
- Fix next.config.js image domains undefined error
- Add downlevelIteration to tsconfig
2025-11-23 04:02:07 +00:00

98 lines
2.8 KiB
TypeScript

/**
* Area Chart Component
* Displays time series data as a filled area chart
*/
import {
AreaChart as RechartsAreaChart,
Area,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from 'recharts';
interface AreaChartProps {
data: any[];
xKey: string;
yKey: string | string[];
title?: string;
colors?: string[];
height?: number;
showGrid?: boolean;
showLegend?: boolean;
stacked?: boolean;
gradient?: boolean;
formatter?: (value: number) => string;
}
const DEFAULT_COLORS = ['#10b981', '#3b82f6', '#8b5cf6', '#f59e0b', '#ef4444'];
export default function AreaChart({
data,
xKey,
yKey,
title,
colors = DEFAULT_COLORS,
height = 300,
showGrid = true,
showLegend = true,
stacked = false,
gradient = true,
formatter = (value) => value.toLocaleString(),
}: AreaChartProps) {
const yKeys = Array.isArray(yKey) ? yKey : [yKey];
return (
<div className="bg-white rounded-lg shadow-lg p-6">
{title && <h3 className="text-lg font-bold text-gray-900 mb-4">{title}</h3>}
<ResponsiveContainer width="100%" height={height}>
<RechartsAreaChart data={data} margin={{ top: 10, right: 30, left: 0, bottom: 0 }}>
<defs>
{yKeys.map((key, index) => (
<linearGradient key={key} id={`color${key}`} x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={colors[index % colors.length]} stopOpacity={0.8} />
<stop offset="95%" stopColor={colors[index % colors.length]} stopOpacity={0.1} />
</linearGradient>
))}
</defs>
{showGrid && <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />}
<XAxis
dataKey={xKey}
tick={{ fill: '#6b7280', fontSize: 12 }}
tickLine={{ stroke: '#e5e7eb' }}
/>
<YAxis
tick={{ fill: '#6b7280', fontSize: 12 }}
tickLine={{ stroke: '#e5e7eb' }}
tickFormatter={formatter}
/>
<Tooltip
contentStyle={{
backgroundColor: '#fff',
border: '1px solid #e5e7eb',
borderRadius: '8px',
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
}}
formatter={(value: number) => [formatter(value), '']}
/>
{showLegend && <Legend />}
{yKeys.map((key, index) => (
<Area
key={key}
type="monotone"
dataKey={key}
stackId={stacked ? 'stack' : undefined}
stroke={colors[index % colors.length]}
strokeWidth={2}
fill={gradient ? `url(#color${key})` : colors[index % colors.length]}
fillOpacity={gradient ? 1 : 0.6}
/>
))}
</RechartsAreaChart>
</ResponsiveContainer>
</div>
);
}