diff --git a/optuna_dashboard/ts/components/GraphSlice.tsx b/optuna_dashboard/ts/components/GraphSlice.tsx index 58576be4..d208395e 100644 --- a/optuna_dashboard/ts/components/GraphSlice.tsx +++ b/optuna_dashboard/ts/components/GraphSlice.tsx @@ -1,5 +1,4 @@ import { - Box, FormControl, FormLabel, Grid, @@ -12,7 +11,12 @@ import { } from "@mui/material" import * as plotly from "plotly.js-dist-min" import React, { FC, useEffect, useState } from "react" -import { SearchSpaceItem, StudyDetail, Trial } from "ts/types/optuna" +import { + GraphComponentState, + SearchSpaceItem, + StudyDetail, + Trial, +} from "ts/types/optuna" import { PlotType } from "../apiClient" import { usePlot } from "../hooks/usePlot" import { useMergedUnionSearchSpace } from "../searchSpace" @@ -23,6 +27,7 @@ import { useObjectiveAndUserAttrTargets, useParamTargets, } from "../trialFilter" +import GraphContainer from "./GraphContainer" const plotDomId = "graph-slice" @@ -46,6 +51,12 @@ export const GraphSlice: FC<{ const GraphSliceBackend: FC<{ study: StudyDetail | null }> = ({ study = null }) => { + const [graphComponentState, setGraphComponentState] = + useState("componentWillMount") + useEffect(() => { + setGraphComponentState("componentDidMount") + }, []) + const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 @@ -57,22 +68,35 @@ const GraphSliceBackend: FC<{ }) useEffect(() => { - if (data && layout) { - plotly.react(plotDomId, data, layout) + if (data && layout && graphComponentState !== "componentWillMount") { + plotly.react(plotDomId, data, layout).then(() => { + setGraphComponentState("graphDidRender") + }) } - }, [data, layout]) + }, [data, layout, graphComponentState]) useEffect(() => { if (error) { console.error(error) } }, [error]) - return + return ( + + ) } const GraphSliceFrontend: FC<{ study: StudyDetail | null }> = ({ study = null }) => { + const [graphComponentState, setGraphComponentState] = + useState("componentWillMount") + useEffect(() => { + setGraphComponentState("componentDidMount") + }, []) + const theme = useTheme() const colorTheme = usePlotlyColorTheme(theme.palette.mode) @@ -92,14 +116,18 @@ const GraphSliceFrontend: FC<{ ) useEffect(() => { - plotSlice( - trials, - selectedObjective, - selectedParamTarget, - searchSpace.find((s) => s.name === selectedParamTarget?.key) || null, - logYScale, - colorTheme - ) + if (graphComponentState !== "componentWillMount") { + plotSlice( + trials, + selectedObjective, + selectedParamTarget, + searchSpace.find((s) => s.name === selectedParamTarget?.key) || null, + logYScale, + colorTheme + )?.then(() => { + setGraphComponentState("graphDidRender") + }) + } }, [ trials, selectedObjective, @@ -107,6 +135,7 @@ const GraphSliceFrontend: FC<{ selectedParamTarget, logYScale, colorTheme, + graphComponentState, ]) const handleObjectiveChange = (event: SelectChangeEvent) => { @@ -176,7 +205,10 @@ const GraphSliceFrontend: FC<{ - + ) @@ -225,8 +257,7 @@ const plotSlice = ( selectedParamTarget === null || trials.length === 0 ) { - plotly.react(plotDomId, [], layout) - return + return plotly.react(plotDomId, [], layout) } const feasibleTrials: Trial[] = [] @@ -305,5 +336,5 @@ const plotSlice = ( automargin: true, // Otherwise the label is outside of the plot } } - plotly.react(plotDomId, trace, layout) + return plotly.react(plotDomId, trace, layout) }