import { useState } from "react";
import Plot from "react-plotly.js";
interface BenchmarkBarChartProps {
title: string;
data: ChartData[];
dataKey: keyof Pick<
ChartData,
"compression_ratio" | "encode_speed" | "decode_speed"
>;
color: string;
xAxisTitle: string;
normalize?: boolean;
}
function BenchmarkBarChart({
title,
data,
dataKey,
color,
xAxisTitle,
normalize,
}: BenchmarkBarChartProps) {
const normalizedData =
normalize && dataKey === "compression_ratio"
? data.map((d) => ({
...d,
compression_ratio: d.reference_compression_ratio
? d.compression_ratio / d.reference_compression_ratio
: d.compression_ratio,
reference_compression_ratio: d.reference_compression_ratio ? 1 : null,
}))
: data;
return (
{title}
d.algorithmOrDataset),
x: normalizedData.map((d) => d[dataKey]),
marker: { color },
name: title,
hovertemplate:
normalize && dataKey === "compression_ratio"
? "%{x:.3f}×"
: "%{x:.2f}",
},
...(dataKey === "compression_ratio" &&
normalizedData.some((d) => d.reference_compression_ratio !== null)
? [
...normalizedData
.filter((d) => d.reference_compression_ratio !== null)
.flatMap((d) => [
{
type: "scatter" as const,
mode: "lines" as const,
y: [d.algorithmOrDataset, d.algorithmOrDataset],
x: [0, d.reference_compression_ratio],
line: { color, width: 1 },
showlegend: false,
hoverinfo: "skip" as const,
},
{
type: "scatter" as const,
mode: "markers" as const,
y: [d.algorithmOrDataset],
x: [d.reference_compression_ratio],
marker: { color: "#aaaaaa", size: 8 },
name: "Best Compression",
hovertemplate: normalize
? "Best: 1.000×"
: "Best: %{x:.2f}",
showlegend:
d.algorithmOrDataset ===
normalizedData[0].algorithmOrDataset,
},
]),
]
: []),
]}
layout={{
width: 700,
height: Math.max(300, data.length * 23 + 40),
margin: { t: 5, r: 30, l: 200, b: 30 },
xaxis: { title: xAxisTitle },
yaxis: { automargin: true, ticksuffix: " " },
dragmode: false,
}}
config={{ displayModeBar: false }}
/>
);
}
interface ChartData {
algorithmOrDataset: string;
compression_ratio: number;
reference_compression_ratio: number | null; // the highest compression ratio for the dataset (if algorithmOrDataset is a dataset)
encode_speed: number;
decode_speed: number;
}
interface BenchmarkChartsProps {
chartData: ChartData[];
showSortByCompressionRatio?: boolean;
showNormalizeByReference?: boolean;
}
export function BenchmarkCharts({
chartData,
showSortByCompressionRatio,
showNormalizeByReference,
}: BenchmarkChartsProps) {
const [sortByRatio, setSortByRatio] = useState(
showSortByCompressionRatio ? true : false,
);
const [normalize, setNormalize] = useState(false);
if (!chartData.length) return null;
const sortedData = sortByRatio
? [...chartData].sort((a, b) => a.compression_ratio - b.compression_ratio)
: chartData;
return (
{showSortByCompressionRatio && (
)}
{showNormalizeByReference && (
)}
);
}