type Dataset = { name: string; values: number[]; color?: string };
interface Props {
type: 'Bar' | 'Pie' | 'Line' | string;
labels: string[];
datasets: Dataset[];
height?: number;
}
const clamp = (n: number) => (Number.isFinite(n) ? Math.max(0, n) : 0);
export default function SimpleChart({ type, labels, datasets, height = 220 }: Props) {
if (!labels?.length || !datasets?.length) {
return
No data
;
}
if (type.toLowerCase() === 'pie') {
const values = datasets[0].values.map(clamp);
const total = values.reduce((a, b) => a + b, 0) || 1;
const radius = Math.min(100, height / 2 - 10);
const cx = radius + 10;
const cy = radius + 10;
let cumulative = 0;
const colors = datasets[0].values.map((_, i) => datasets[0].color || defaultColor(i));
return (
);
}
// Bar chart (stack if multiple datasets)
const series = datasets;
const max = Math.max(...series.flatMap(s => s.values.map(clamp)), 1);
const width = Math.max(labels.length * 60, 300);
const chartHeight = height - 40;
const barWidth = Math.max(20, (width - 40) / labels.length - 10);
return (
);
}
function defaultColor(i: number): string {
const palette = ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#6366F1', '#22C55E', '#E11D48'];
return palette[i % palette.length];
}
function truncate(s: string, n: number) {
return s.length > n ? s.slice(0, n - 1) + '…' : s;
}