import { ChartData } from '@/types/chat'; import { Table } from '@mui/joy'; import { useMemo } from 'react'; interface TableChartProps { chart: ChartData; columnNameMap?: Record; renderCell?: (value: any, row: any, col: string) => React.ReactNode; } export default function TableChart({ chart, columnNameMap, renderCell }: TableChartProps) { // Process table data const { columns, dataSource } = useMemo(() => { if (!chart.values || chart.values.length === 0) { return { columns: [], dataSource: [] }; } const firstRow = chart.values[0]; // Handle type-value structure if ('type' in firstRow && 'value' in firstRow && 'name' in firstRow) { // Group by name and transform type-value pairs into columns const mergedData = new Map(); chart.values.forEach(item => { if (!mergedData.has(item.name)) { mergedData.set(item.name, { name: item.name }); } const row = mergedData.get(item.name); row[item.type] = item.value; }); // Get all unique types as columns const types = [...new Set(chart.values.map(item => item.type))]; return { columns: ['name', ...types], dataSource: Array.from(mergedData.values()), }; } // Use data as is for other formats return { columns: Object.keys(chart.values[0]), dataSource: chart.values, }; }, [chart]); // Smart column name formatting const formatCol = (col: string) => columnNameMap?.[col] || col .replace(/_/g, ' ') .replace(/([a-z])([A-Z])/g, '$1 $2') .replace(/\b\w/g, l => l.toUpperCase()); // Cell value formatting const formatCellValue = (value: any) => { if (value === null || value === undefined) return '-'; if (typeof value === 'number') { // Handle percentage and score values (0-100 range) if (value >= 0 && value <= 100) { return value.toFixed(2); // Keep two decimal places for scores/percentages } // For large numbers, use thousand separators if (value >= 1000) { return value.toLocaleString(); } // For other numbers, limit to 2 decimal places if needed return Number.isInteger(value) ? value.toString() : value.toFixed(2); } return String(value); }; return (
{chart.chart_name}
{chart.chart_desc}
{columns.map(col => ( ))} {dataSource.map((row, i) => ( {columns.map(col => ( ))} ))}
{formatCol(col)}
{renderCell ? renderCell(row[col as keyof typeof row], row, col) : formatCellValue(row[col as keyof typeof row])}
); }