Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| 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<LeaderboardTableProps> = ({ file }) => { | |
| const [tableRows, setTableRows] = useState<Row[]>([]) | |
| const [tableHeader, setTableHeader] = useState<string[]>([]) | |
| const [loading, setLoading] = useState(true) | |
| const [error, setError] = useState<string | null>(null) | |
| const [groups, setGroups] = useState<Groups>({}) | |
| const [selectedMetrics, setSelectedMetrics] = useState<Set<string>>(new Set()) | |
| const [defaultSelectedMetrics, setDefaultSelectedMetrics] = useState<string[]>([]) | |
| 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 ( | |
| <div className="rounded shadow overflow-auto"> | |
| <h3 className="font-bold mb-2">{file}</h3> | |
| {loading && <div>Loading...</div>} | |
| {error && <div className="text-red-500">{error}</div>} | |
| {!loading && !error && ( | |
| <div className="overflow-x-auto"> | |
| <LeaderboardFilter | |
| groups={groups} | |
| selectedMetrics={selectedMetrics} | |
| setSelectedMetrics={setSelectedMetrics} | |
| defaultSelectedMetrics={defaultSelectedMetrics} | |
| /> | |
| <table className="table"> | |
| <thead> | |
| <tr> | |
| {tableHeader.map((col, idx) => ( | |
| <th key={idx}>{col}</th> | |
| ))} | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {tableRows | |
| .filter((row) => selectedMetrics.has(row['metric'] as string)) | |
| .map((row, i) => ( | |
| <tr key={i}> | |
| {Object.keys(row).map((column, j) => { | |
| const cell = row[column] | |
| return ( | |
| <td key={j}> | |
| <div className=""> | |
| {isNaN(Number(cell)) ? cell : Number(Number(cell).toFixed(3))} | |
| </div> | |
| </td> | |
| ) | |
| })} | |
| </tr> | |
| ))} | |
| </tbody> | |
| </table> | |
| </div> | |
| )} | |
| </div> | |
| ) | |
| } | |
| export default LeaderboardTable | |