import React, { useEffect, useState } from 'react' import API from '../API' import LeaderboardFilter from './LeaderboardFilter' interface LeaderboardTableProps { file: string } interface Row { metric: string [key: string]: string | number } interface Groups { [group: string]: { [subgroup: string]: string[] } } const LeaderboardTable: React.FC = ({ file }) => { const [tableRows, setTableRows] = useState([]) const [tableHeader, setTableHeader] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [groups, setGroups] = useState({}) const [selectedMetrics, setSelectedMetrics] = useState>(new Set()) const [defaultSelectedMetrics, setDefaultSelectedMetrics] = useState([]) useEffect(() => { API.fetchStaticFile(`data/${file}_benchmark.csv`) .then((response) => { const data = JSON.parse(response) const rows: Row[] = data['rows'] const groups = data['groups'] as { [key: string]: string[] } // Each value of groups is a list of metrics, group them by the first part of the metric before the first _ const groupsData = Object.entries(groups) .sort(([groupA], [groupB]) => { // Make sure "overall" comes first if (groupA === 'Overall') return -1 if (groupB === 'Overall') return 1 // Otherwise sort alphabetically return groupA.localeCompare(groupB) }) .reduce( (acc, [group, metrics]) => { // Sort metrics to ensure consistent subgroup order const sortedMetrics = [...metrics].sort() // Create and sort subgroups acc[group] = sortedMetrics.reduce<{ [key: string]: string[] }>((subAcc, metric) => { const [mainGroup, subGroup] = metric.split('_') if (!subAcc[mainGroup]) { subAcc[mainGroup] = [] } subAcc[mainGroup].push(metric) return subAcc }, {}) // Convert to sorted entries and back to object acc[group] = Object.fromEntries( Object.entries(acc[group]).sort(([subGroupA], [subGroupB]) => subGroupA.localeCompare(subGroupB) ) ) return acc }, {} as { [key: string]: { [key: string]: string[] } } ) const allKeys: string[] = Array.from(new Set(rows.flatMap((row) => Object.keys(row)))) setSelectedMetrics(new Set(data['default_selected_metrics'])) setDefaultSelectedMetrics(data['default_selected_metrics']) setTableHeader(allKeys) setTableRows(rows) setGroups(groupsData) setLoading(false) }) .catch((err) => { setError('Failed to fetch JSON: ' + err.message) setLoading(false) }) }, [file]) const handleSelectDefaults = () => { setSelectedMetrics(new Set(defaultSelectedMetrics)) } return (

{file}

{loading &&
Loading...
} {error &&
{error}
} {!loading && !error && (
{tableHeader.map((col, idx) => ( ))} {tableRows .filter((row) => selectedMetrics.has(row['metric'] as string)) .map((row, i) => ( {Object.keys(row).map((column, j) => { const cell = row[column] return ( ) })} ))}
{col}
{isNaN(Number(cell)) ? cell : Number(Number(cell).toFixed(3))}
)}
) } export default LeaderboardTable