tahamajs/IE / Projects /front /src /components /genui /ChartComponent.tsx
tahamajs's picture
download
raw
4.57 kB
// src/components/genui/ChartComponent.tsx
import { useMemo } from "react";
import {
BarChart, Bar, LineChart, Line, PieChart, Pie, AreaChart, Area,
ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, Tooltip,
Legend, ResponsiveContainer, Cell,
} from "recharts";
const COLORS = ["#0d9488", "#2563eb", "#7c3aed", "#db2777", "#ea580c", "#ca8a04", "#16a34a"];
interface ChartComponentProps {
chartType: "bar" | "line" | "pie" | "area" | "scatter";
title: string;
labels: string[];
datasets: { label: string; data: number[]; color?: string }[];
xLabel?: string;
yLabel?: string;
height?: number;
isStreaming?: boolean;
onAction?: (action: string, data: any) => void;
}
export function ChartComponent({ chartType, title, labels, datasets, xLabel, yLabel, height = 300, isStreaming, onAction }: ChartComponentProps) {
const data = useMemo(() =>
labels.map((label, i) => {
const row: Record<string, any> = { name: label };
datasets.forEach(ds => { row[ds.label] = ds.data[i] ?? 0; });
return row;
}),
[labels, datasets]
);
const renderChart = () => {
switch (chartType) {
case "bar":
return (
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
<XAxis dataKey="name" tick={{ fontSize: 11 }} />
<YAxis tick={{ fontSize: 11 }} />
<Tooltip />
<Legend />
{datasets.map((ds, i) => (
<Bar key={ds.label} dataKey={ds.label} fill={ds.color ?? COLORS[i % COLORS.length]} radius={[4, 4, 0, 0]} />
))}
</BarChart>
);
case "line":
return (
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
<XAxis dataKey="name" tick={{ fontSize: 11 }} />
<YAxis tick={{ fontSize: 11 }} />
<Tooltip />
<Legend />
{datasets.map((ds, i) => (
<Line key={ds.label} type="monotone" dataKey={ds.label} stroke={ds.color ?? COLORS[i % COLORS.length]} strokeWidth={2} dot={{ r: 3 }} />
))}
</LineChart>
);
case "pie":
const pieData = labels.map((label, i) => ({
name: label,
value: datasets[0]?.data[i] ?? 0,
}));
return (
<PieChart>
<Pie data={pieData} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80} label>
{pieData.map((_, i) => <Cell key={i} fill={COLORS[i % COLORS.length]} />)}
</Pie>
<Tooltip />
<Legend />
</PieChart>
);
case "area":
return (
<AreaChart data={data}>
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
<XAxis dataKey="name" tick={{ fontSize: 11 }} />
<YAxis tick={{ fontSize: 11 }} />
<Tooltip />
<Legend />
{datasets.map((ds, i) => (
<Area key={ds.label} type="monotone" dataKey={ds.label} fill={ds.color ?? COLORS[i % COLORS.length]} stroke={ds.color ?? COLORS[i % COLORS.length]} fillOpacity={0.3} />
))}
</AreaChart>
);
case "scatter":
return (
<ScatterChart>
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
<XAxis dataKey="x" name={xLabel ?? "X"} tick={{ fontSize: 11 }} />
<YAxis dataKey="y" name={yLabel ?? "Y"} tick={{ fontSize: 11 }} />
<Tooltip cursor={{ strokeDasharray: "3 3" }} />
<Legend />
{datasets.map((ds, i) => (
<Scatter key={ds.label} name={ds.label} data={ds.data.map((v, j) => ({ x: j, y: v }))} fill={ds.color ?? COLORS[i % COLORS.length]} />
))}
</ScatterChart>
);
default:
return <p>Unsupported chart type</p>;
}
};
return (
<div className="space-y-2">
<h3 className="font-semibold text-sm">{title}</h3>
<ResponsiveContainer width="100%" height={height}>
{renderChart()}
</ResponsiveContainer>
<div className="flex gap-2">
{(["bar","line","pie","area"] as const).map(t => (
<button
key={t}
onClick={() => onAction?.("change_chart_type", { chartType: t })}
className={`text-[10px] px-2 py-0.5 rounded-full ${chartType === t ? "bg-primary text-white" : "bg-gray-100 dark:bg-gray-700 text-gray-500"}`}
>
{t}
</button>
))}
</div>
</div>
);
}

Xet Storage Details

Size:
4.57 kB
·
Xet hash:
44021de320e4f2d1df42de0511b0d19d3dd0aca028ffff5785d9eccec59e1372

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.