/ concept-collection / benchcompress
Sign in
concept-collection / benchcompress
benchcompress / web-ui / src / components / benchmark / charts / BenchmarkCharts.tsx
187 lines · 5.6 KBBlameHistoryRaw
1import { useState } from "react";
2import Plot from "react-plotly.js";
4interface BenchmarkBarChartProps {
5 title: string;
6 data: ChartData[];
7 dataKey: keyof Pick<
8 ChartData,
9 "compression_ratio" | "encode_speed" | "decode_speed"
10 >;
11 color: string;
12 xAxisTitle: string;
13 normalize?: boolean;
16function BenchmarkBarChart({
17 title,
18 data,
19 dataKey,
20 color,
21 xAxisTitle,
22 normalize,
23}: BenchmarkBarChartProps) {
24 const normalizedData =
25 normalize && dataKey === "compression_ratio"
26 ? data.map((d) => ({
27 ...d,
28 compression_ratio: d.reference_compression_ratio
29 ? d.compression_ratio / d.reference_compression_ratio
30 : d.compression_ratio,
31 reference_compression_ratio: d.reference_compression_ratio ? 1 : null,
32 }))
33 : data;
35 return (
36 <div style={{ margin: "0 20px 20px 0" }}>
37 <h3 style={{ marginBottom: "10px" }}>{title}</h3>
38 <Plot
39 data={[
40 {
41 type: "bar",
42 orientation: "h",
43 y: normalizedData.map((d) => d.algorithmOrDataset),
44 x: normalizedData.map((d) => d[dataKey]),
45 marker: { color },
46 name: title,
47 hovertemplate:
48 normalize && dataKey === "compression_ratio"
49 ? "%{x:.3f}×<extra></extra>"
50 : "%{x:.2f}<extra></extra>",
51 },
52 ...(dataKey === "compression_ratio" &&
53 normalizedData.some((d) => d.reference_compression_ratio !== null)
54 ? [
55 ...normalizedData
56 .filter((d) => d.reference_compression_ratio !== null)
57 .flatMap((d) => [
58 {
59 type: "scatter" as const,
60 mode: "lines" as const,
61 y: [d.algorithmOrDataset, d.algorithmOrDataset],
62 x: [0, d.reference_compression_ratio],
63 line: { color, width: 1 },
64 showlegend: false,
65 hoverinfo: "skip" as const,
66 },
67 {
68 type: "scatter" as const,
69 mode: "markers" as const,
70 y: [d.algorithmOrDataset],
71 x: [d.reference_compression_ratio],
72 marker: { color: "#aaaaaa", size: 8 },
73 name: "Best Compression",
74 hovertemplate: normalize
75 ? "Best: 1.000×<extra></extra>"
76 : "Best: %{x:.2f}<extra></extra>",
77 showlegend:
78 d.algorithmOrDataset ===
79 normalizedData[0].algorithmOrDataset,
80 },
81 ]),
82 ]
83 : []),
84 ]}
85 layout={{
86 width: 700,
87 height: Math.max(300, data.length * 23 + 40),
88 margin: { t: 5, r: 30, l: 200, b: 30 },
89 xaxis: { title: xAxisTitle },
90 yaxis: { automargin: true, ticksuffix: " " },
91 dragmode: false,
92 }}
93 config={{ displayModeBar: false }}
94 />
95 </div>
96 );
99interface ChartData {
100 algorithmOrDataset: string;
101 compression_ratio: number;
102 reference_compression_ratio: number | null; // the highest compression ratio for the dataset (if algorithmOrDataset is a dataset)
103 encode_speed: number;
104 decode_speed: number;
107interface BenchmarkChartsProps {
108 chartData: ChartData[];
109 showSortByCompressionRatio?: boolean;
110 showNormalizeByReference?: boolean;
113export function BenchmarkCharts({
114 chartData,
115 showSortByCompressionRatio,
116 showNormalizeByReference,
117}: BenchmarkChartsProps) {
118 const [sortByRatio, setSortByRatio] = useState(
119 showSortByCompressionRatio ? true : false,
120 );
121 const [normalize, setNormalize] = useState(false);
123 if (!chartData.length) return null;
125 const sortedData = sortByRatio
126 ? [...chartData].sort((a, b) => a.compression_ratio - b.compression_ratio)
127 : chartData;
129 return (
130 <div>
131 {showSortByCompressionRatio && (
132 <div style={{ marginBottom: "10px" }}>
133 <label style={{ display: "flex", alignItems: "center", gap: "8px" }}>
134 <input
135 type="checkbox"
136 checked={sortByRatio}
137 onChange={(e) => setSortByRatio(e.target.checked)}
138 />
139 Sort by compression ratio
140 </label>
141 </div>
142 )}
143 {showNormalizeByReference && (
144 <div style={{ marginBottom: "10px" }}>
145 <label style={{ display: "flex", alignItems: "center", gap: "8px" }}>
146 <input
147 type="checkbox"
148 checked={normalize}
149 onChange={(e) => setNormalize(e.target.checked)}
150 />
151 Normalize to best compression
152 </label>
153 </div>
154 )}
155 <div
156 style={{
157 display: "flex",
158 flexWrap: "wrap",
159 gap: "20px",
160 }}
161 >
162 <BenchmarkBarChart
163 title="Compression Ratio"
164 data={sortedData}
165 dataKey="compression_ratio"
166 color="#8884d8"
167 xAxisTitle={normalize ? "Fraction of Best Compression" : "Ratio"}
168 normalize={normalize}
169 />
170 <BenchmarkBarChart
171 title="Encode Speed (MB/s)"
172 data={sortedData}
173 dataKey="encode_speed"
174 color="#82ca9d"
175 xAxisTitle="MB/s"
176 />
177 <BenchmarkBarChart
178 title="Decode Speed (MB/s)"
179 data={sortedData}
180 dataKey="decode_speed"
181 color="#ff7300"
182 xAxisTitle="MB/s"
183 />
184 </div>
185 </div>
186 );
moveopenescclose