/ concept-collection / benchcompress
Sign in
concept-collection / benchcompress
benchcompress / web-ui / src / components / benchmark / table / BenchmarkTable.tsx
232 lines · 7.4 KBCodeBlameHistory
0968553routingJeremy Magland 1import { useMemo } from "react";
2import { useSearchParams } from "react-router-dom";
eacabc8test real dataJeremy Magland 3import {
4 flexRender,
5 getCoreRowModel,
6 useReactTable,
7 getSortedRowModel,
70a7a71code formattingJeremy Magland 8} from "@tanstack/react-table";
9import { BenchmarkResult } from "../../../types";
10import { columns } from "./columns";
11import { BenchmarkCharts } from "../charts/BenchmarkCharts";
12import { exportToCsv } from "../export/csvExport";
eacabc8test real dataJeremy Magland 13
0968553routingJeremy Magland 14interface BenchmarkTableProps {
15 results: BenchmarkResult[];
eacabc8test real dataJeremy Magland 17
0968553routingJeremy Magland 18export function BenchmarkTable({ results }: BenchmarkTableProps) {
19 const [searchParams, setSearchParams] = useSearchParams();
20 const selectedDataset = searchParams.get("dataset") || "";
6c17da5about pageJeremy Magland 21 const selectedAlgorithm = searchParams.get("algorithm") || "";
0968553routingJeremy Magland 23 const availableDatasets = useMemo(() => {
24 return Array.from(new Set(results.map((result) => result.dataset))).sort();
25 }, [results]);
eacabc8test real dataJeremy Magland 26
6c17da5about pageJeremy Magland 27 const availableAlgorithms = useMemo(() => {
28 return Array.from(
29 new Set(results.map((result) => result.algorithm)),
30 ).sort();
31 }, [results]);
eacabc8test real dataJeremy Magland 33 // Memoize filtered data to prevent unnecessary recalculations
34 const filteredData = useMemo(() => {
6c17da5about pageJeremy Magland 35 let filtered = results;
36 if (selectedDataset) {
37 filtered = filtered.filter((row) => row.dataset === selectedDataset);
38 }
39 if (selectedAlgorithm) {
40 filtered = filtered.filter((row) => row.algorithm === selectedAlgorithm);
41 }
42 return filtered;
43 }, [results, selectedDataset, selectedAlgorithm]);
eacabc8test real dataJeremy Magland 44
45 const table = useReactTable({
46 data: filteredData || [],
47 columns,
48 getCoreRowModel: getCoreRowModel(),
49 getSortedRowModel: getSortedRowModel(),
50 });
6c17da5about pageJeremy Magland 52 // Prepare data for bar charts when either dataset or algorithm is selected
eacabc8test real dataJeremy Magland 53 const chartData = useMemo(() => {
6c17da5about pageJeremy Magland 54 if (selectedDataset) {
55 return results
56 .filter((row: BenchmarkResult) => row.dataset === selectedDataset)
57 .map((row: BenchmarkResult) => ({
58 algorithm: row.algorithm,
59 compression_ratio: row.compression_ratio,
60 encode_speed: row.encode_mb_per_sec,
61 decode_speed: row.decode_mb_per_sec,
62 }));
63 } else if (selectedAlgorithm) {
64 return results
65 .filter((row: BenchmarkResult) => row.algorithm === selectedAlgorithm)
66 .map((row: BenchmarkResult) => ({
67 algorithm: row.dataset, // Use dataset as the x-axis label when algorithm is selected
68 compression_ratio: row.compression_ratio,
69 encode_speed: row.encode_mb_per_sec,
70 decode_speed: row.decode_mb_per_sec,
71 }));
72 }
73 return [];
74 }, [results, selectedDataset, selectedAlgorithm]);
eacabc8test real dataJeremy Magland 75
76 return (
77 <div className="table-container">
70a7a71code formattingJeremy Magland 78 <div
79 style={{
a3cad9bformat codeJeremy Magland 80 marginBottom: "12px",
70a7a71code formattingJeremy Magland 81 display: "flex",
82 alignItems: "center",
a3cad9bformat codeJeremy Magland 83 gap: "8px",
70a7a71code formattingJeremy Magland 84 justifyContent: "space-between",
85 }}
86 >
a3cad9bformat codeJeremy Magland 87 <div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
88 <div style={{ display: "flex", alignItems: "center", gap: "6px" }}>
6c17da5about pageJeremy Magland 89 <label htmlFor="dataset-select">Dataset:</label>
90 <select
91 id="dataset-select"
92 value={selectedDataset}
93 onChange={(e) => {
94 if (e.target.value) {
95 setSearchParams({ dataset: e.target.value });
96 } else {
97 setSearchParams(
98 selectedAlgorithm ? { algorithm: selectedAlgorithm } : {},
99 );
100 }
101 }}
102 style={{
a3cad9bformat codeJeremy Magland 103 padding: "4px 8px",
6c17da5about pageJeremy Magland 104 borderRadius: "4px",
105 border: "1px solid #ccc",
a3cad9bformat codeJeremy Magland 106 minWidth: "150px",
6c17da5about pageJeremy Magland 107 backgroundColor: "#fff",
a3cad9bformat codeJeremy Magland 108 fontSize: "0.9rem",
6c17da5about pageJeremy Magland 109 }}
110 >
111 <option value="">All Datasets</option>
112 {availableDatasets.map((dataset) => (
113 <option key={dataset} value={dataset}>
114 {dataset}
115 </option>
116 ))}
117 </select>
118 </div>
119 <div style={{ display: "flex", alignItems: "center", gap: "10px" }}>
120 <label htmlFor="algorithm-select">Algorithm:</label>
121 <select
122 id="algorithm-select"
123 value={selectedAlgorithm}
124 onChange={(e) => {
125 if (e.target.value) {
126 setSearchParams({ algorithm: e.target.value });
127 } else {
128 setSearchParams(
129 selectedDataset ? { dataset: selectedDataset } : {},
130 );
131 }
132 }}
133 style={{
a3cad9bformat codeJeremy Magland 134 padding: "4px 8px",
6c17da5about pageJeremy Magland 135 borderRadius: "4px",
136 border: "1px solid #ccc",
a3cad9bformat codeJeremy Magland 137 minWidth: "150px",
6c17da5about pageJeremy Magland 138 backgroundColor: "#fff",
a3cad9bformat codeJeremy Magland 139 fontSize: "0.9rem",
6c17da5about pageJeremy Magland 140 }}
141 >
142 <option value="">All Algorithms</option>
143 {availableAlgorithms.map((algorithm) => (
144 <option key={algorithm} value={algorithm}>
145 {algorithm}
146 </option>
147 ))}
148 </select>
149 </div>
eacabc8test real dataJeremy Magland 150 </div>
151 </div>
6c17da5about pageJeremy Magland 153 {(selectedDataset || selectedAlgorithm) && chartData.length > 0 && (
eacabc8test real dataJeremy Magland 154 <BenchmarkCharts chartData={chartData} />
155 )}
157 <table>
158 <thead>
70a7a71code formattingJeremy Magland 159 {table.getHeaderGroups().map((headerGroup) => (
eacabc8test real dataJeremy Magland 160 <tr key={headerGroup.id}>
70a7a71code formattingJeremy Magland 161 {headerGroup.headers.map((header) => (
eacabc8test real dataJeremy Magland 162 <th
163 key={header.id}
164 onClick={header.column.getToggleSortingHandler()}
70a7a71code formattingJeremy Magland 165 style={{ cursor: "pointer" }}
eacabc8test real dataJeremy Magland 166 >
167 {flexRender(
168 header.column.columnDef.header,
70a7a71code formattingJeremy Magland 169 header.getContext(),
eacabc8test real dataJeremy Magland 170 )}
171 {header.column.getIsSorted() && (
70a7a71code formattingJeremy Magland 172 <span style={{ marginLeft: "4px" }}>
173 {header.column.getIsSorted() === "asc" ? "↑" : "↓"}
eacabc8test real dataJeremy Magland 174 </span>
175 )}
176 </th>
177 ))}
178 </tr>
179 ))}
180 </thead>
181 <tbody>
70a7a71code formattingJeremy Magland 182 {table.getRowModel().rows.map((row) => (
eacabc8test real dataJeremy Magland 183 <tr key={row.id}>
70a7a71code formattingJeremy Magland 184 {row.getVisibleCells().map((cell) => (
eacabc8test real dataJeremy Magland 185 <td key={cell.id}>
186 {flexRender(cell.column.columnDef.cell, cell.getContext())}
187 </td>
188 ))}
189 </tr>
190 ))}
191 </tbody>
192 </table>
a10d266update UIJeremy Magland 193
a3cad9bformat codeJeremy Magland 194 <div
195 style={{
196 marginTop: "12px",
197 display: "flex",
198 justifyContent: "flex-end",
199 }}
200 >
a10d266update UIJeremy Magland 201 <button
202 onClick={() =>
203 exportToCsv(filteredData, selectedDataset || selectedAlgorithm)
204 }
205 style={{
206 padding: "8px 16px",
207 backgroundColor: "#4CAF50",
208 color: "white",
209 border: "none",
210 borderRadius: "4px",
211 cursor: "pointer",
212 display: "flex",
213 alignItems: "center",
214 gap: "8px",
215 }}
216 >
217 <svg
218 width="16"
219 height="16"
220 viewBox="0 0 16 16"
221 fill="none"
222 xmlns="http://www.w3.org/2000/svg"
223 >
224 <path d="M8 12L3 7H6V1H10V7H13L8 12Z" fill="currentColor" />
225 <path d="M2 14V15H14V14H2Z" fill="currentColor" />
226 </svg>
227 Download CSV
228 </button>
229 </div>
eacabc8test real dataJeremy Magland 230 </div>
231 );
moveopenescclose