Spaces:
Running
Running
Download frontends/react/src/ComparePanel.tsx from elvis-hf/optimization: direct link, hf CLI and curl.
- Browser
- Download file 3.92 kB
-
https://huggingface.co/spaces/elvis-hf/optimization/resolve/main/frontends/react/src/ComparePanel.tsx
- Command line
-
hf download hf://spaces/elvis-hf/optimization/frontends/react/src/ComparePanel.tsx
-
curl -L -o ComparePanel.tsx https://huggingface.co/spaces/elvis-hf/optimization/resolve/main/frontends/react/src/ComparePanel.tsx
3.92 kB
| import { useState } from "react"; | |
| import AlgorithmControls, { DEFAULT_HYPERPARAMETERS } from "./AlgorithmControls"; | |
| import type { ComparisonEntry, ComparisonTrajectory, SettingsUi } from "./types"; | |
| export default function ComparePanel({ settings, entries, trajectories, onAdd, onRemove, onToggleVisibility, iteration, busy, ready, animating, onAction }: { | |
| settings: SettingsUi; | |
| entries: ComparisonEntry[]; | |
| trajectories: ComparisonTrajectory[]; | |
| onAdd: (settings: SettingsUi) => void; | |
| onRemove: (id: number) => void; | |
| onToggleVisibility: (id: number) => void; | |
| iteration: number; | |
| busy: boolean; | |
| ready: boolean; | |
| animating: boolean; | |
| onAction: (action: string) => void; | |
| }) { | |
| const [draft, setDraft] = useState(settings); | |
| const configured: SettingsUi = { algorithm: draft.algorithm, x0: draft.x0, y0: draft.y0, | |
| mode: settings.mode, functionExpr: settings.functionExpr, | |
| ...Object.fromEntries(Object.entries(DEFAULT_HYPERPARAMETERS[draft.algorithm]).map(([key, fallback]) => [key, draft[key as keyof SettingsUi] ?? fallback])) }; | |
| const valid = [configured.x0, ...(configured.mode === "Bivariate" ? [configured.y0] : []), | |
| ...Object.entries(configured).filter(([key]) => ["learningRate", "momentum", "beta", "beta1", "beta2", "epsilon"].includes(key)).map(([, value]) => value) | |
| ].every(value => value !== undefined && value.trim() !== "" && Number.isFinite(Number(value))); | |
| return <> | |
| <AlgorithmControls settings={configured} setSettings={setDraft} onRandomInitialPoint={() => setDraft({ ...configured, x0: (Math.random() * 2 - 1).toFixed(2), y0: (Math.random() * 2 - 1).toFixed(2) })} /> | |
| <button className="rounded border border-gray-300 bg-orange-200 px-3 py-1 disabled:opacity-50" disabled={!valid || !ready || busy || animating} onClick={() => onAdd(configured)}>Add</button> | |
| <div className="text-sm font-semibold">Selected algorithms</div> | |
| {entries.length === 0 && <p className="text-sm text-stone-500">Add algorithms to compare their trajectories on the same objective.</p>} | |
| <ul className="flex flex-col gap-2"> | |
| {entries.map((entry, index) => <li key={entry.id} className="rounded border border-stone-300 p-2 text-sm"> | |
| <div className="flex items-center gap-2"> | |
| <span className="h-3 w-3 rounded-full shrink-0" style={{ background: entry.color }} /> | |
| <span className="flex-1 font-semibold">{index + 1}. {entry.settings.algorithm}</span> | |
| <button | |
| aria-label={`${entry.visible ? "Hide" : "Show"} ${index + 1}. ${entry.settings.algorithm}`} | |
| aria-pressed={!entry.visible} | |
| onClick={() => onToggleVisibility(entry.id)} | |
| > | |
| {entry.visible ? "Hide" : "Show"} | |
| </button> | |
| <button aria-label={`Remove ${index + 1}. ${entry.settings.algorithm}`} onClick={() => onRemove(entry.id)}>Remove</button> | |
| </div> | |
| <div className="text-xs text-stone-600">{Object.entries(entry.settings).filter(([key]) => !["mode", "functionExpr", "algorithm"].includes(key) && (key !== "y0" || settings.mode === "Bivariate")).map(([key, value]) => `${key}: ${value}`).join(", ")}</div> | |
| {trajectories.find(item => item.id === entry.id)?.error && <p role="alert" className="text-red-700">Unable to compute this trajectory. Check its settings.</p>} | |
| </li>)} | |
| </ul> | |
| <div className="text-sm" role="status">Iteration {iteration}{busy ? " · Computing…" : ""}</div> | |
| <div className="flex flex-wrap gap-2"> | |
| {["Animate", "Previous", "Next", "Reset", "Pause"].map(action => <button key={action} | |
| className="rounded border border-gray-300 bg-orange-200 px-3 py-1 text-sm disabled:opacity-50" | |
| disabled={action === "Pause" ? !animating : !ready || !entries.length || busy || animating || ((action === "Previous" || action === "Reset") && iteration === 0)} | |
| onClick={() => onAction(action)}>{action}</button>)} | |
| </div> | |
| </>; | |
| } | |