import Plot from "react-plotly.js";
import type { SettingsUi, TrajectoryValues } from "./types.ts";
interface IterationHistoryPlotProps {
mode: SettingsUi["mode"];
trajectoryValues?: TrajectoryValues | null;
currentIteration: number;
}
export default function IterationHistoryPlot({ mode, trajectoryValues, currentIteration }: IterationHistoryPlotProps) {
const xValues = trajectoryValues?.x ?? [];
const yValues = trajectoryValues?.y ?? [];
const objectiveValues = mode === "Bivariate" ? trajectoryValues?.z ?? [] : yValues;
const iterations = xValues.map((_, index) => index);
const traces = mode === "Bivariate"
? [
{ name: "x", values: xValues, color: "#2563eb" },
{ name: "y", values: yValues, color: "#16a34a" },
{ name: "Objective", values: objectiveValues, color: "#dc2626" },
]
: [
{ name: "x", values: xValues, color: "#2563eb" },
{ name: "Objective", values: objectiveValues, color: "#dc2626" },
];
return (
({
x: iterations.slice(0, trace.values.length),
y: trace.values,
name: trace.name,
type: "scatter" as const,
mode: "lines+markers" as const,
line: { color: trace.color, width: 2 },
marker: { color: trace.color, size: 5 },
hovertemplate: `${trace.name}: %{y:.5g}`,
})),
...traces.map((trace) => ({
x: trace.values[currentIteration] !== undefined ? [currentIteration] : [],
y: trace.values[currentIteration] !== undefined ? [trace.values[currentIteration]] : [],
name: `${trace.name} selected`,
type: "scatter" as const,
mode: "markers" as const,
marker: { color: trace.color, size: 11, line: { color: "white", width: 2 } },
hoverinfo: "skip" as const,
showlegend: false,
})),
]}
layout={{
title: { text: "Optimization history", font: { size: 14 } },
xaxis: {
title: { text: "Iteration" },
showticklabels: false,
ticks: "",
rangemode: "tozero",
},
yaxis: { title: { text: "Value" }, automargin: true },
legend: { orientation: "h", x: 0.5, xanchor: "center", y: 1.12 },
margin: { t: 58, r: 18, b: 45, l: 55 },
hovermode: "x unified",
paper_bgcolor: "transparent",
plot_bgcolor: "transparent",
}}
style={{ width: "100%", height: "100%" }}
config={{ responsive: true, displayModeBar: false }}
/>
);
}