Use PlotEdf from tslib/react as GraphEdfFrontend

This commit is contained in:
porink0424
2024-06-12 17:31:11 +09:00
parent 9b5ae54305
commit 15a7dc8980
+10 -123
View File
@@ -1,19 +1,15 @@
import { Box, Typography, useTheme } from "@mui/material"
import {
GraphContainer,
PlotEdf,
getPlotDomId,
useGraphComponentState,
} from "@optuna/react"
import * as plotly from "plotly.js-dist-min"
import React, { FC, useEffect, useMemo } from "react"
import { StudyDetail, Trial } from "ts/types/optuna"
import React, { FC, useEffect } from "react"
import { StudyDetail } from "ts/types/optuna"
import { CompareStudiesPlotType } from "../apiClient"
import { useAPIClient } from "../apiClientProvider"
import { useGraphComponentState, GraphContainer } from "@optuna/react"
import { useBackendRender, usePlotlyColorTheme } from "../state"
import { Target, useFilteredTrialsFromStudies } from "../trialFilter"
const getPlotDomId = (objectiveId: number) => `graph-edf-${objectiveId}`
interface EdfPlotInfo {
study_name: string
trials: Trial[]
}
import { useBackendRender } from "../state"
export const GraphEdf: FC<{
studies: StudyDetail[]
@@ -22,7 +18,7 @@ export const GraphEdf: FC<{
if (useBackendRender()) {
return <GraphEdfBackend studies={studies} />
} else {
return <GraphEdfFrontend studies={studies} objectiveId={objectiveId} />
return <PlotEdf studies={studies} objectiveId={objectiveId} />
}
}
@@ -61,112 +57,3 @@ const GraphEdfBackend: FC<{
/>
)
}
const GraphEdfFrontend: FC<{
studies: StudyDetail[]
objectiveId: number
}> = ({ studies, objectiveId }) => {
const { graphComponentState, notifyGraphDidRender } = useGraphComponentState()
const theme = useTheme()
const colorTheme = usePlotlyColorTheme(theme.palette.mode)
const domId = getPlotDomId(objectiveId)
const target = useMemo<Target>(
() => new Target("objective", objectiveId),
[objectiveId]
)
const trials = useFilteredTrialsFromStudies(studies, [target], false)
const edfPlotInfos = studies.map((study, index) => {
const e: EdfPlotInfo = {
study_name: study?.name,
trials: trials[index],
}
return e
})
useEffect(() => {
if (graphComponentState !== "componentWillMount") {
plotEdf(edfPlotInfos, target, domId, colorTheme)?.then(
notifyGraphDidRender
)
}
}, [studies, target, colorTheme, graphComponentState])
return (
<Box component="div">
<Typography
variant="h6"
sx={{ margin: "1em 0", fontWeight: theme.typography.fontWeightBold }}
>
{`EDF for ${target.toLabel(studies[0].objective_names)}`}
</Typography>
<GraphContainer
plotDomId={domId}
graphComponentState={graphComponentState}
/>
</Box>
)
}
const plotEdf = (
edfPlotInfos: EdfPlotInfo[],
target: Target,
domId: string,
colorTheme: Partial<Plotly.Template>
) => {
if (document.getElementById(domId) === null) {
return
}
if (edfPlotInfos.length === 0) {
return plotly.react(domId, [], {
template: colorTheme,
})
}
const target_name = "Objective Value"
const layout: Partial<plotly.Layout> = {
xaxis: {
title: target_name,
},
yaxis: {
title: "Cumulative Probability",
},
margin: {
l: 50,
t: 0,
r: 50,
b: 50,
},
template: colorTheme,
legend: {
x: 1.0,
y: 0.95,
},
}
const plotData: Partial<plotly.PlotData>[] = edfPlotInfos.map((h) => {
const values = h.trials.map((t) => target.getTargetValue(t) as number)
const numValues = values.length
const minX = Math.min(...values)
const maxX = Math.max(...values)
const numStep = 100
const _step = (maxX - minX) / (numStep - 1)
const xValues = []
const yValues = []
for (let i = 0; i < numStep; i++) {
const boundary_right = minX + _step * i
xValues.push(boundary_right)
yValues.push(values.filter((v) => v <= boundary_right).length / numValues)
}
return {
type: "scatter",
name: `${h.study_name}`,
x: xValues,
y: yValues,
}
})
return plotly.react(domId, plotData, layout)
}