Skip to content

Commit

Permalink
Merge pull request #1038 from porink0424/fix/duration-units-in-triallist
Browse files Browse the repository at this point in the history
Add a select box to select time unit of duration
  • Loading branch information
c-bata authored Mar 5, 2025
2 parents c76653f + 40724bd commit d8f57ab
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 19 deletions.
102 changes: 83 additions & 19 deletions optuna_dashboard/ts/components/TrialList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import StopCircleIcon from "@mui/icons-material/StopCircle"
import {
Box,
Button,
FormControl,
IconButton,
InputLabel,
Menu,
MenuItem,
Select,
Typography,
useTheme,
} from "@mui/material"
Expand All @@ -24,11 +27,11 @@ import React, { FC, ReactNode, useMemo } from "react"
import ListItemIcon from "@mui/material/ListItemIcon"
import { useVirtualizer } from "@tanstack/react-virtual"
import { useNavigate } from "react-router-dom"
import { useRecoilValue } from "recoil"
import { useRecoilState, useRecoilValue } from "recoil"
import { FormWidgets, StudyDetail, Trial } from "ts/types/optuna"
import { actionCreator } from "../action"
import { useConstants } from "../constantsProvider"
import { artifactIsAvailable } from "../state"
import { artifactIsAvailable, trialListDurationTimeUnitState } from "../state"
import { useQuery } from "../urlQuery"
import { TrialArtifactCards } from "./Artifact/TrialArtifactCards"
import { TrialNote } from "./Note"
Expand Down Expand Up @@ -134,11 +137,34 @@ export const TrialListDetail: FC<{
const artifactEnabled = useRecoilValue<boolean>(artifactIsAvailable)
const startMs = trial.datetime_start?.getTime()
const completeMs = trial.datetime_complete?.getTime()
const [durationTimeUnit, setDurationTimeUnit] = useRecoilState(
trialListDurationTimeUnitState
)
const duration = useMemo(
() =>
startMs !== undefined && completeMs !== undefined
? (completeMs - startMs) /
10 **
(durationTimeUnit === "ms"
? 0
: durationTimeUnit === "s"
? 3
: durationTimeUnit === "min"
? 6
: 9)
: null,
[startMs, completeMs, durationTimeUnit]
)

const params = trial.state === "Waiting" ? trial.fixed_params : trial.params
const info: [string, string | null | ReactNode][] = [
["Value", trial.values?.map((v) => v.toString()).join(", ") || "None"],
const info: [string, string | ReactNode, string | null | ReactNode][] = [
[
"value",
"Value",
trial.values?.map((v) => v.toString()).join(", ") || "None",
],
[
"intermediate_values",
"Intermediate Values",
<Box component="div">
{trial.intermediate_values.map((v) => (
Expand All @@ -149,6 +175,7 @@ export const TrialListDetail: FC<{
</Box>,
],
[
"parameter",
"Parameter",
<Box component="div">
{params.map((p) => (
Expand All @@ -159,20 +186,52 @@ export const TrialListDetail: FC<{
</Box>,
],
[
"started_at",
"Started At",
trial?.datetime_start ? trial?.datetime_start.toString() : null,
],
[
"completed_at",
"Completed At",
trial?.datetime_complete ? trial?.datetime_complete.toString() : null,
],
[
"Duration (ms)",
startMs !== undefined && completeMs !== undefined
? (completeMs - startMs).toString()
: null,
"duration",
<Box
component="div"
sx={{ display: "flex", alignItems: "center", minWidth: "200px" }}
>
<Typography
sx={{ p: theme.spacing(1) }}
color="text.secondary"
fontWeight={theme.typography.fontWeightLight}
fontSize={theme.typography.fontSize}
>
Duration
</Typography>
<FormControl sx={{ width: 80 }} size="small">
<InputLabel id="trial-list-duration-select-label">
Time Unit
</InputLabel>
<Select
labelId="trial-list-duration-select-label"
label="Time Unit"
value={durationTimeUnit}
onChange={(e) =>
setDurationTimeUnit(e.target.value as "ms" | "s" | "min" | "h")
}
>
<MenuItem value="ms">ms</MenuItem>
<MenuItem value="s">s</MenuItem>
<MenuItem value="min">min</MenuItem>
<MenuItem value="h">h</MenuItem>
</Select>
</FormControl>
</Box>,
duration,
],
[
"user_attrs",
"User Attributes",
<Box component="div">
{trial.user_attrs.map((t) => (
Expand All @@ -185,6 +244,7 @@ export const TrialListDetail: FC<{
]
const renderInfo = (
key: string,
attribute: string | ReactNode,
value: string | null | ReactNode
): ReactNode => (
<Box
Expand All @@ -196,15 +256,19 @@ export const TrialListDetail: FC<{
marginBottom: theme.spacing(0.5),
}}
>
<Typography
sx={{ p: theme.spacing(1) }}
color="text.secondary"
minWidth={"200px"}
fontWeight={theme.typography.fontWeightLight}
fontSize={theme.typography.fontSize}
>
{key}
</Typography>
{typeof attribute === "string" ? (
<Typography
sx={{ p: theme.spacing(1) }}
color="text.secondary"
minWidth={"200px"}
fontWeight={theme.typography.fontWeightLight}
fontSize={theme.typography.fontSize}
>
{attribute}
</Typography>
) : (
attribute
)}
<Box
component="div"
sx={{
Expand Down Expand Up @@ -301,8 +365,8 @@ export const TrialListDetail: FC<{
flexDirection: "column",
}}
>
{info.map(([key, value]) =>
value !== null ? renderInfo(key, value) : null
{info.map(([key, attribute, value]) =>
value !== null ? renderInfo(key, attribute, value) : null
)}
</Box>
{artifactEnabled && <TrialArtifactCards trial={trial} />}
Expand Down
5 changes: 5 additions & 0 deletions optuna_dashboard/ts/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export const studyDetailLoadingState = atom<Record<number, boolean>>({
default: {},
})

export const trialListDurationTimeUnitState = atom<"ms" | "s" | "min" | "h">({
key: "trialListDurationTimeUnit",
default: "ms",
})

export const usePlotBackendRendering = () => {
return useLocalStorage<boolean>("plotBackendRendering", false)
}
Expand Down

0 comments on commit d8f57ab

Please sign in to comment.