mirror of
https://github.com/wassname/optuna-dashboard.git
synced 2026-09-24 13:41:07 +08:00
Fix layout when no trials available
This commit is contained in:
@@ -1,115 +1,100 @@
|
||||
import React, { FC } from "react"
|
||||
import {Button, Card, CardContent, Typography, useTheme} from "@mui/material";
|
||||
import {Link} from "react-router-dom";
|
||||
import LinkIcon from '@mui/icons-material/Link';
|
||||
import { Button, Card, CardContent, Typography, useTheme } from "@mui/material"
|
||||
import { Link } from "react-router-dom"
|
||||
import LinkIcon from "@mui/icons-material/Link"
|
||||
|
||||
export const BestTrialsCard: FC<{
|
||||
studyDetail: StudyDetail | null
|
||||
studyDetail: StudyDetail | null
|
||||
}> = ({ studyDetail }) => {
|
||||
const theme = useTheme()
|
||||
const theme = useTheme()
|
||||
|
||||
let content: React.ReactNode = null
|
||||
if (studyDetail !== null && studyDetail.best_trials.length === 1) {
|
||||
const bestTrial = studyDetail.best_trials[0]
|
||||
content = (
|
||||
<>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ margin: "1em 0", fontWeight: 600 }}
|
||||
>
|
||||
Best Trial (number={bestTrial.number})
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="h3"
|
||||
sx={{ fontWeight: 600, marginBottom: theme.spacing(2) }}
|
||||
color="secondary"
|
||||
>
|
||||
{bestTrial.values}
|
||||
</Typography>
|
||||
<Typography>
|
||||
Params = [
|
||||
{bestTrial.params
|
||||
.map((p) => `${p.name}: ${p.value}`)
|
||||
.join(", ")}
|
||||
]
|
||||
</Typography>
|
||||
<Typography>
|
||||
Intermediate Values = [
|
||||
{studyDetail.best_trials[0].intermediate_values
|
||||
.map((p) => `${p.step}: ${p.value}`)
|
||||
.join(", ")}
|
||||
]
|
||||
</Typography>
|
||||
<Typography>
|
||||
User Attributes = [
|
||||
{studyDetail.best_trials[0].user_attrs
|
||||
.map((p) => `${p.key}: ${p.value}`)
|
||||
.join(", ")}
|
||||
]
|
||||
</Typography>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<LinkIcon />}
|
||||
component={Link}
|
||||
to={`${URL_PREFIX}/studies/${bestTrial.study_id}/trials/${bestTrial.number}/`}
|
||||
sx={{ margin: theme.spacing(1)}}
|
||||
>
|
||||
Details
|
||||
</Button>
|
||||
</>
|
||||
|
||||
)
|
||||
} else if (studyDetail !== null && studyDetail.best_trials.length > 1) {
|
||||
const bestTrials = studyDetail.best_trials
|
||||
content = (
|
||||
<>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ margin: "1em 0", fontWeight: 600 }}
|
||||
>
|
||||
Best Trials ({bestTrials.length} trials)
|
||||
</Typography>
|
||||
{bestTrials.map((trial, i) => (
|
||||
<Card
|
||||
key={i}
|
||||
sx={{
|
||||
border: "1px solid rgba(128,128,128,0.5)",
|
||||
margin: theme.spacing(1, 0),
|
||||
}}
|
||||
>
|
||||
<CardContent>
|
||||
<Typography variant="h6">
|
||||
Trial number={trial.number} (trial_id=
|
||||
{trial.trial_id})
|
||||
</Typography>
|
||||
<Typography>
|
||||
Objective Values = [{trial.values?.join(", ")}]
|
||||
</Typography>
|
||||
<Typography>
|
||||
Params = [
|
||||
{trial.params
|
||||
.map((p) => `${p.name}: ${p.value}`)
|
||||
.join(", ")}
|
||||
]
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Card>
|
||||
<CardContent
|
||||
sx={{
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
</CardContent>
|
||||
</Card>
|
||||
let header = "Best Trials"
|
||||
let content: React.ReactNode = null
|
||||
if (studyDetail !== null && studyDetail.best_trials.length === 1) {
|
||||
const bestTrial = studyDetail.best_trials[0]
|
||||
header = `Best Trial (number=${bestTrial.number})`
|
||||
content = (
|
||||
<>
|
||||
<Typography
|
||||
variant="h3"
|
||||
sx={{ fontWeight: 600, marginBottom: theme.spacing(2) }}
|
||||
color="secondary"
|
||||
>
|
||||
{bestTrial.values}
|
||||
</Typography>
|
||||
<Typography>
|
||||
Params = [
|
||||
{bestTrial.params.map((p) => `${p.name}: ${p.value}`).join(", ")}]
|
||||
</Typography>
|
||||
<Typography>
|
||||
Intermediate Values = [
|
||||
{studyDetail.best_trials[0].intermediate_values
|
||||
.map((p) => `${p.step}: ${p.value}`)
|
||||
.join(", ")}
|
||||
]
|
||||
</Typography>
|
||||
<Typography>
|
||||
User Attributes = [
|
||||
{studyDetail.best_trials[0].user_attrs
|
||||
.map((p) => `${p.key}: ${p.value}`)
|
||||
.join(", ")}
|
||||
]
|
||||
</Typography>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<LinkIcon />}
|
||||
component={Link}
|
||||
to={`${URL_PREFIX}/studies/${bestTrial.study_id}/trials/${bestTrial.number}/`}
|
||||
sx={{ margin: theme.spacing(1) }}
|
||||
>
|
||||
Details
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
} else if (studyDetail !== null && studyDetail.best_trials.length > 1) {
|
||||
const bestTrials = studyDetail.best_trials
|
||||
content = (
|
||||
<>
|
||||
{bestTrials.map((trial, i) => (
|
||||
<Card
|
||||
key={i}
|
||||
sx={{
|
||||
border: "1px solid rgba(128,128,128,0.5)",
|
||||
margin: theme.spacing(1, 0),
|
||||
}}
|
||||
>
|
||||
<CardContent>
|
||||
<Typography variant="h6">
|
||||
Trial number={trial.number} (trial_id=
|
||||
{trial.trial_id})
|
||||
</Typography>
|
||||
<Typography>
|
||||
Objective Values = [{trial.values?.join(", ")}]
|
||||
</Typography>
|
||||
<Typography>
|
||||
Params = [
|
||||
{trial.params.map((p) => `${p.name}: ${p.value}`).join(", ")}]
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Card>
|
||||
<CardContent
|
||||
sx={{
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6" sx={{ margin: "1em 0", fontWeight: 600 }}>
|
||||
{header}
|
||||
</Typography>
|
||||
{content}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -214,7 +214,9 @@ const plotContour = (
|
||||
const filteredTrials = trials.filter((t) => filterFunc(t, objectiveId))
|
||||
|
||||
if (filteredTrials.length === 0) {
|
||||
plotly.react(plotDomId, [])
|
||||
plotly.react(plotDomId, [], {
|
||||
template: mode === "dark" ? plotlyDarkTemplate : {},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,9 @@ const plotEdf = (study: StudyDetail, objectiveId: number, mode: string) => {
|
||||
const filteredTrials = trials.filter((t) => filterFunc(t, objectiveId))
|
||||
|
||||
if (filteredTrials.length === 0) {
|
||||
plotly.react(plotDomId, [])
|
||||
plotly.react(plotDomId, [], {
|
||||
template: mode === "dark" ? plotlyDarkTemplate : {},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ const plotHistory = (
|
||||
filteredTrials = filteredTrials.filter((t) => t.state !== "Pruned")
|
||||
}
|
||||
if (filteredTrials.length === 0) {
|
||||
plotly.react(plotDomId, [])
|
||||
plotly.react(plotDomId, [], layout)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import { DataGrid, DataGridColumn } from "./DataGrid"
|
||||
import { GraphIntermediateValues } from "./GraphIntermediateValues"
|
||||
import { Edf } from "./GraphEdf"
|
||||
import { TrialList } from "./TrialList"
|
||||
import {BestTrialsCard} from "./BestTrialsCard";
|
||||
import { BestTrialsCard } from "./BestTrialsCard"
|
||||
|
||||
interface ParamTypes {
|
||||
studyId: string
|
||||
@@ -124,7 +124,7 @@ export const StudyDetailBeta: FC<{
|
||||
graphHeight="450px"
|
||||
/>
|
||||
<Grid2 xs={6} spacing={2}>
|
||||
<BestTrialsCard studyDetail={studyDetail} />
|
||||
<BestTrialsCard studyDetail={studyDetail} />
|
||||
</Grid2>
|
||||
<Grid2 xs={6}>
|
||||
<Card>
|
||||
|
||||
Reference in New Issue
Block a user