Merge the implementation of GraphEdf and GraphEdfMultiStudies

This commit is contained in:
keisuke-umezawa committed 2023-08-19 15:07:30 +09:00
1 parent d6df55bfec
commit f6bc5ba77a
3 files changed
+40 -163

No files matched your search

@@ -12,6 +12,7 @@ import {
useTheme,
IconButton,
} from "@mui/material"
import Grid2 from "@mui/material/Unstable_Grid2"
import ChevronRightIcon from "@mui/icons-material/ChevronRight"
import Chip from "@mui/material/Chip"
import FormControlLabel from "@mui/material/FormControlLabel"
@@ -325,19 +326,24 @@ const StudiesGraph: FC<{ studies: StudySummary[] }> = ({ studies }) => {
</CardContent>
</Card>
) : null}
{showStudyDetails !== null &&
showStudyDetails.length > 0 &&
showStudyDetails.every((s) => s) ? (
<Card
sx={{
margin: theme.spacing(2),
}}
>
<CardContent>
<GraphEdfMultiStudies studies={showStudyDetails} />
</CardContent>
</Card>
) : null}
<Grid2 container spacing={2} sx={{ padding: theme.spacing(0, 2) }}>
{showStudyDetails !== null &&
showStudyDetails.length > 0 &&
showStudyDetails.every((s) => s)
? showStudyDetails[0].directions.map((d, i) => (
<Grid2 xs={6} key={i}>
<Card>
<CardContent>
<GraphEdfMultiStudies
studies={showStudyDetails}
objectiveId={i}
/>
</CardContent>
</Card>
</Grid2>
))
: null}
</Grid2>
</Box>
)
}
+16 -148
View File
@@ -1,25 +1,9 @@
import * as plotly from "plotly.js-dist-min"
import React, { FC, useEffect, useMemo } from "react"
import {
Grid,
FormControl,
FormLabel,
MenuItem,
Select,
Typography,
SelectChangeEvent,
useTheme,
Box,
} from "@mui/material"
import { Typography, useTheme, Box } from "@mui/material"
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
import {
Target,
useFilteredTrials,
useFilteredTrialsFromStudies,
useObjectiveTargets,
} from "../trialFilter"
import { Target, useFilteredTrialsFromStudies } from "../trialFilter"
const plotDomId = "graph-edf"
const getPlotDomId = (objectiveId: number) => `graph-edf-${objectiveId}`
interface EdfPlotInfo {
@@ -27,45 +11,17 @@ interface EdfPlotInfo {
trials: Trial[]
}
export const GraphEdf: FC<{
study: StudyDetail | null
export const GraphEdfMultiStudies: FC<{
studies: StudyDetail[]
objectiveId: number
}> = ({ study, objectiveId }) => {
}> = ({ studies, objectiveId }) => {
const theme = useTheme()
const domId = getPlotDomId(objectiveId)
const target = useMemo<Target>(
() => new Target("objective", objectiveId),
[objectiveId]
)
const trials = useFilteredTrials(study, [target], false)
useEffect(() => {
if (study !== null) {
plotEdf(trials, target, domId, theme.palette.mode)
}
}, [trials, target, domId, theme.palette.mode])
return (
<Box>
<Typography
variant="h6"
sx={{ margin: "1em 0", fontWeight: theme.typography.fontWeightBold }}
>
{`EDF for ${target.toLabel(study?.objective_names)}`}
</Typography>
<Box id={domId} sx={{ height: "450px" }} />
</Box>
)
}
export const GraphEdfMultiStudies: FC<{
studies: StudyDetail[]
}> = ({ studies }) => {
const theme = useTheme()
const [targets, selected, setTarget] = useObjectiveTargets(
studies.length !== 0 ? studies[0] : null
)
const trials = useFilteredTrialsFromStudies(studies, [selected], false)
const trials = useFilteredTrialsFromStudies(studies, [target], false)
const edfPlotInfos = studies.map((study, index) => {
const e: EdfPlotInfo = {
study_name: study?.name,
@@ -74,111 +30,23 @@ export const GraphEdfMultiStudies: FC<{
return e
})
const handleObjectiveChange = (event: SelectChangeEvent<string>) => {
setTarget(event.target.value)
}
useEffect(() => {
plotEdfMultiStudies(edfPlotInfos, selected, plotDomId, theme.palette.mode)
}, [studies, selected, theme.palette.mode])
plotEdfMultiStudies(edfPlotInfos, target, domId, theme.palette.mode)
}, [studies, target, theme.palette.mode])
return (
<Grid container direction="row">
<Grid
item
xs={3}
container
direction="column"
sx={{ paddingRight: theme.spacing(2) }}
<Box>
<Typography
variant="h6"
sx={{ margin: "1em 0", fontWeight: theme.typography.fontWeightBold }}
>
<Typography
variant="h6"
sx={{ margin: "1em 0", fontWeight: theme.typography.fontWeightBold }}
>
EDF
</Typography>
{studies.length > 0 && studies[0].directions.length !== 1 ? (
<FormControl component="fieldset">
<FormLabel component="legend">Objective:</FormLabel>
<Select
value={selected.identifier()}
onChange={handleObjectiveChange}
>
{targets.map((target, i) => (
<MenuItem value={target.identifier()} key={i}>
{target.toLabel(studies[0].objective_names)}
</MenuItem>
))}
</Select>
</FormControl>
) : null}
</Grid>
<Grid item xs={9}>
<Box id={plotDomId} sx={{ height: "450px" }} />
</Grid>
</Grid>
{`EDF for ${target.toLabel(studies[0].objective_names)}`}
</Typography>
<Box id={domId} sx={{ height: "450px" }} />
</Box>
)
}
const plotEdf = (
trials: Trial[],
target: Target,
domId: string,
mode: string
) => {
if (document.getElementById(domId) === null) {
return
}
if (trials.length === 0) {
plotly.react(domId, [], {
template: mode === "dark" ? plotlyDarkTemplate : {},
})
return
}
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,
},
uirevision: "true",
template: mode === "dark" ? plotlyDarkTemplate : {},
}
const values = 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)
}
const plotData: Partial<plotly.PlotData>[] = [
{
type: "scatter",
x: xValues,
y: yValues,
},
]
plotly.react(domId, plotData, layout)
}
const plotEdfMultiStudies = (
edfPlotInfos: EdfPlotInfo[],
target: Target,
@@ -25,7 +25,7 @@ import { AppDrawer, PageId } from "./AppDrawer"
import { GraphParallelCoordinate } from "./GraphParallelCoordinate"
import { Contour } from "./GraphContour"
import { GraphSlice } from "./GraphSlice"
import { GraphEdf } from "./GraphEdf"
import { GraphEdfMultiStudies } from "./GraphEdf"
import { TrialList } from "./TrialList"
import { StudyHistory } from "./StudyHistory"
@@ -113,7 +113,10 @@ export const StudyDetail: FC<{
<Grid2 xs={6} key={i}>
<Card>
<CardContent>
<GraphEdf study={studyDetail} objectiveId={i} />
<GraphEdfMultiStudies
studies={[studyDetail]}
objectiveId={i}
/>
</CardContent>
</Card>
</Grid2>