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
99 lines
2.8 KiB
TypeScript
99 lines
2.8 KiB
TypeScript
/**
|
|
* Bar Chart Component
|
|
* Displays categorical data as bars
|
|
*/
|
|
|
|
import {
|
|
BarChart as RechartsBarChart,
|
|
Bar,
|
|
XAxis,
|
|
YAxis,
|
|
CartesianGrid,
|
|
Tooltip,
|
|
Legend,
|
|
ResponsiveContainer,
|
|
Cell,
|
|
} from 'recharts';
|
|
|
|
interface BarChartProps {
|
|
data: any[];
|
|
xKey: string;
|
|
yKey: string | string[];
|
|
title?: string;
|
|
colors?: string[];
|
|
height?: number;
|
|
showGrid?: boolean;
|
|
showLegend?: boolean;
|
|
stacked?: boolean;
|
|
horizontal?: boolean;
|
|
formatter?: (value: number) => string;
|
|
}
|
|
|
|
const DEFAULT_COLORS = ['#10b981', '#3b82f6', '#8b5cf6', '#f59e0b', '#ef4444', '#06b6d4'];
|
|
|
|
export default function BarChart({
|
|
data,
|
|
xKey,
|
|
yKey,
|
|
title,
|
|
colors = DEFAULT_COLORS,
|
|
height = 300,
|
|
showGrid = true,
|
|
showLegend = true,
|
|
stacked = false,
|
|
horizontal = false,
|
|
formatter = (value) => value.toLocaleString(),
|
|
}: BarChartProps) {
|
|
const yKeys = Array.isArray(yKey) ? yKey : [yKey];
|
|
const layout = horizontal ? 'vertical' : 'horizontal';
|
|
|
|
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}>
|
|
<RechartsBarChart
|
|
data={data}
|
|
layout={layout}
|
|
margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
|
|
>
|
|
{showGrid && <CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />}
|
|
{horizontal ? (
|
|
<>
|
|
<XAxis type="number" tick={{ fill: '#6b7280', fontSize: 12 }} tickFormatter={formatter} />
|
|
<YAxis dataKey={xKey} type="category" tick={{ fill: '#6b7280', fontSize: 12 }} width={100} />
|
|
</>
|
|
) : (
|
|
<>
|
|
<XAxis dataKey={xKey} tick={{ fill: '#6b7280', fontSize: 12 }} />
|
|
<YAxis tick={{ fill: '#6b7280', fontSize: 12 }} 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 && yKeys.length > 1 && <Legend />}
|
|
{yKeys.map((key, index) => (
|
|
<Bar
|
|
key={key}
|
|
dataKey={key}
|
|
fill={colors[index % colors.length]}
|
|
stackId={stacked ? 'stack' : undefined}
|
|
radius={[4, 4, 0, 0]}
|
|
>
|
|
{yKeys.length === 1 &&
|
|
data.map((entry, i) => (
|
|
<Cell key={`cell-${i}`} fill={colors[i % colors.length]} />
|
|
))}
|
|
</Bar>
|
|
))}
|
|
</RechartsBarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
);
|
|
}
|