diff --git a/optuna_dashboard/ts/components/GraphRank.tsx b/optuna_dashboard/ts/components/GraphRank.tsx index d1ce9d19..b288874c 100644 --- a/optuna_dashboard/ts/components/GraphRank.tsx +++ b/optuna_dashboard/ts/components/GraphRank.tsx @@ -14,8 +14,9 @@ import { import { plotlyDarkTemplate } from "./PlotlyDarkMode" import { getAxisInfo, makeHovertext } from "../graphUtil" import { useMergedUnionSearchSpace } from "../searchSpace" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" import { useBackendRender } from "../state" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-rank" @@ -47,18 +48,23 @@ const GraphRankBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.Rank, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.Rank) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return } diff --git a/optuna_dashboard/ts/hooks/useParamImportance.ts b/optuna_dashboard/ts/hooks/useParamImportance.ts index 8b145b2b..3728320f 100644 --- a/optuna_dashboard/ts/hooks/useParamImportance.ts +++ b/optuna_dashboard/ts/hooks/useParamImportance.ts @@ -10,7 +10,10 @@ export const useParamImportance = ({ }: { numCompletedTrials: number; studyId: number }) => { const { enqueueSnackbar } = useSnackbar() - const { data, isLoading, error } = useQuery>({ + const { data, isLoading, error } = useQuery< + ParamImportance[][], + AxiosError<{ reason: string }> + >({ queryKey: ["paramImportance", studyId, numCompletedTrials], queryFn: () => getParamImportances(studyId), staleTime: Infinity, diff --git a/optuna_dashboard/ts/hooks/usePlot.ts b/optuna_dashboard/ts/hooks/usePlot.ts new file mode 100644 index 00000000..3c3036ad --- /dev/null +++ b/optuna_dashboard/ts/hooks/usePlot.ts @@ -0,0 +1,37 @@ +import * as plotly from "plotly.js-dist-min" +import { useQuery } from "@tanstack/react-query" +import { AxiosError } from "axios" +import { PlotType, getPlotAPI } from "../apiClient" + +export const usePlot = ({ + numCompletedTrials, + studyId, + plotType, +}: { + numCompletedTrials: number + studyId: number | undefined + plotType: PlotType +}) => { + const { data, isLoading, error } = useQuery< + { data: plotly.Data[]; layout: plotly.Layout }, + AxiosError + >({ + enabled: studyId !== undefined, + queryKey: ["plot", studyId, numCompletedTrials], + queryFn: () => { + if (studyId === undefined) { + return Promise.reject(new Error("Invalid studyId")) + } + return getPlotAPI(studyId, plotType) + }, + staleTime: Infinity, + gcTime: Infinity, + }) + + return { + data: data?.data, + layout: data?.layout, + isLoading, + error, + } +}