nhamid289's picture
Deploy decision_boundary from optimization-design-system (plain background, shared UI updates)
6c17bbb verified
Raw History Blame Contribute Delete
3.29 kB
import { useEffect } from "react";
import { AppLayout, Button, DatasetPicker, describePlot, Divider, useDataset } from "@elvis/ui";
// import { LoadingScreen } from "@elvis/ui";
import { OKABE_ITO_COLORS } from "./colors.ts";
import { DATASETS } from "./datasets.ts";
import DecisionBoundaryPlot from "./DecisionBoundaryPlot.tsx";
import Sidebar from "./Sidebar.tsx";
import Usage from "./Usage.tsx";
import useAppLogic from "./useAppLogic.ts";
const MANUAL_CLASSES = OKABE_ITO_COLORS.map(({ name, value }) => ({ name, color: value }));
export default function App() {
const app = useAppLogic();
const dataset = useDataset({ task: "classification", builtins: DATASETS, classes: MANUAL_CLASSES });
const processed = dataset.result?.ok ? dataset.result.dataset : null;
// Plot whatever the picker produces and send it to Python. Drawing points by
// hand keeps the view still; loading a table zooms to fit it.
useEffect(() => {
app.handleSetDataset(processed, dataset.source !== "manual");
}, [dataset.result]);
//if (!app.backendReady) {
//return <LoadingScreen message="Loading" />;
//}
return (
<AppLayout
title="Decision Boundary"
usage={<Usage />}
examples={<p>Examples are coming soon.</p>}
panel={
<>
<DatasetPicker dataset={dataset} />
<Divider />
<Sidebar
modelSettings={app.modelSettings}
setModelSettings={app.handleModelSettingsChange}
/>
<Divider />
{app.pythonStatus === "loading" && (
<p className="text-sm text-ink-muted">Loading Python… actions will run once it is ready.</p>
)}
{app.pythonStatus === "failed" && (
<p className="text-red-600 font-semibold">Python failed to load. Try reloading the page.</p>
)}
<section className="flex flex-col gap-4">
<h3 className="text-xs font-semibold uppercase tracking-widest text-ink-muted">Fit</h3>
<Button
label="Get Decision Boundary"
onClick={app.handleGetDecisionBoundary}
variant="primary"
/>
<label className="flex items-center gap-2 text-sm text-gray-700 cursor-pointer">
<input
type="checkbox"
checked={app.autoFit}
onChange={(e) => app.handleAutoFitChange(e.target.checked)}
className="size-4 accent-ink"
/>
Fit automatically
</label>
{app.modelError && (
<p className="text-red-600 font-semibold">{app.modelError}</p>
)}
</section>
</>
}
>
<DecisionBoundaryPlot
dataPoints={app.dataPoints}
onDataClick={dataset.source === "manual" ? dataset.manual.add : null}
decisionBoundaryResult={app.decisionBoundaryResult}
xRangeRef={app.xRangeRef}
yRangeRef={app.yRangeRef}
setRanges={app.handleRangeChange}
labelColors={app.labelColors}
plotHandle={app.plotHandle}
/>
{dataset.source !== "manual" && dataset.result?.ok && (
<p className="mt-2 text-xs text-ink-muted">{describePlot(dataset.result.dataset)}</p>
)}
</AppLayout>
);
}