mirror of
https://github.com/wassname/optuna-dashboard.git
synced 2026-09-11 12:30:25 +08:00
Merge pull request #863 from porink0424/fix/type-replace
Align the types defined in `optuna_dashboard/ts` to `@optuna/types` as much as possible
This commit is contained in:
@@ -23,9 +23,32 @@ jobs:
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- run: npm install
|
||||
- run: npm run lint
|
||||
|
||||
type-check:
|
||||
name: Type checking on optuna-dashboard
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Setup tslib
|
||||
run: make tslib
|
||||
|
||||
- name: Type Check
|
||||
working-directory: optuna_dashboard
|
||||
run: |
|
||||
npm install
|
||||
npm run type-check
|
||||
|
||||
build:
|
||||
name: JS build check
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
+2
-1
@@ -15,7 +15,8 @@
|
||||
"ignore": [
|
||||
"optuna_dashboard/ts/components/PlotlyColorTemplates.ts",
|
||||
"tslib/react/src/components/PlotlyDarkMode.ts",
|
||||
"tslib/**/pkg/*"
|
||||
"tslib/**/pkg/*",
|
||||
"tslib/react/types/*"
|
||||
]
|
||||
},
|
||||
"javascript": {
|
||||
|
||||
@@ -62,7 +62,7 @@ if TYPE_CHECKING:
|
||||
"type": Literal["FloatDistribution"],
|
||||
"low": float,
|
||||
"high": float,
|
||||
"step": float,
|
||||
"step": Union[float, None],
|
||||
"log": bool,
|
||||
},
|
||||
)
|
||||
|
||||
Generated
+11
-873
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,8 @@
|
||||
"watch": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack --watch",
|
||||
"build": "webpack",
|
||||
"build:dev": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack",
|
||||
"build:prd": "NODE_ENV=production webpack"
|
||||
"build:prd": "NODE_ENV=production webpack",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"author": "Masashi Shibata",
|
||||
"license": "MIT",
|
||||
@@ -45,6 +46,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/preset-env": "^7.23.9",
|
||||
"@optuna/types": "../tslib/types/",
|
||||
"@types/plotly.js": "^2.12.32",
|
||||
"@types/react": "^18.2.48",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { useRecoilState, useSetRecoilState } from "recoil"
|
||||
import { useSnackbar } from "notistack"
|
||||
import {
|
||||
@@ -33,6 +34,15 @@ import {
|
||||
studySummariesLoadingState,
|
||||
} from "./state"
|
||||
import { getDominatedTrials } from "./dominatedTrials"
|
||||
import {
|
||||
Artifact,
|
||||
FeedbackComponentType,
|
||||
Note,
|
||||
StudyDetail,
|
||||
StudyDetails,
|
||||
StudySummary,
|
||||
Trial,
|
||||
} from "./types/optuna"
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const actionCreator = () => {
|
||||
@@ -143,8 +153,8 @@ export const actionCreator = () => {
|
||||
const setTrialStateValues = (
|
||||
studyId: number,
|
||||
index: number,
|
||||
state: TrialState,
|
||||
values?: TrialValueNumber[]
|
||||
state: Optuna.TrialState,
|
||||
values?: number[]
|
||||
) => {
|
||||
const newTrial: Trial = Object.assign(
|
||||
{},
|
||||
@@ -270,7 +280,10 @@ export const actionCreator = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const createNewStudy = (studyName: string, directions: StudyDirection[]) => {
|
||||
const createNewStudy = (
|
||||
studyName: string,
|
||||
directions: Optuna.StudyDirection[]
|
||||
) => {
|
||||
createNewStudyAPI(studyName, directions)
|
||||
.then((study_summary) => {
|
||||
const newVal = [...studySummaries, study_summary]
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
import * as plotly from "plotly.js-dist-min"
|
||||
import axios from "axios"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import {
|
||||
Artifact,
|
||||
FeedbackComponentType,
|
||||
FormWidgets,
|
||||
Note,
|
||||
ParamImportance,
|
||||
PlotlyGraphObject,
|
||||
PreferenceFeedbackMode,
|
||||
PreferenceHistory,
|
||||
SearchSpaceItem,
|
||||
StudyDetail,
|
||||
StudySummary,
|
||||
Trial,
|
||||
TrialParam,
|
||||
} from "./types/optuna"
|
||||
|
||||
const axiosInstance = axios.create({ baseURL: API_ENDPOINT })
|
||||
|
||||
@@ -18,9 +34,9 @@ interface TrialResponse {
|
||||
trial_id: number
|
||||
study_id: number
|
||||
number: number
|
||||
state: TrialState
|
||||
values?: TrialValueNumber[]
|
||||
intermediate_values: TrialIntermediateValue[]
|
||||
state: Optuna.TrialState
|
||||
values?: number[]
|
||||
intermediate_values: Optuna.TrialIntermediateValue[]
|
||||
datetime_start?: string
|
||||
datetime_complete?: string
|
||||
params: TrialParam[]
|
||||
@@ -28,7 +44,7 @@ interface TrialResponse {
|
||||
name: string
|
||||
param_external_value: string
|
||||
}[]
|
||||
user_attrs: Attribute[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
note: Note
|
||||
artifacts: Artifact[]
|
||||
constraints: number[]
|
||||
@@ -86,13 +102,13 @@ const convertPreferenceHistory = (
|
||||
interface StudyDetailResponse {
|
||||
name: string
|
||||
datetime_start: string
|
||||
directions: StudyDirection[]
|
||||
user_attrs: Attribute[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
trials: TrialResponse[]
|
||||
best_trials: TrialResponse[]
|
||||
intersection_search_space: SearchSpaceItem[]
|
||||
union_search_space: SearchSpaceItem[]
|
||||
union_user_attrs: AttributeSpec[]
|
||||
union_user_attrs: Optuna.AttributeSpec[]
|
||||
has_intermediate_values: boolean
|
||||
note: Note
|
||||
is_preferential: boolean
|
||||
@@ -155,8 +171,8 @@ interface StudySummariesResponse {
|
||||
study_summaries: {
|
||||
study_id: number
|
||||
study_name: string
|
||||
directions: StudyDirection[]
|
||||
user_attrs: Attribute[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
is_preferential: boolean
|
||||
datetime_start?: string
|
||||
}[]
|
||||
@@ -185,8 +201,8 @@ interface CreateNewStudyResponse {
|
||||
study_summary: {
|
||||
study_id: number
|
||||
study_name: string
|
||||
directions: StudyDirection[]
|
||||
user_attrs: Attribute[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
is_preferential: boolean
|
||||
datetime_start?: string
|
||||
}
|
||||
@@ -194,7 +210,7 @@ interface CreateNewStudyResponse {
|
||||
|
||||
export const createNewStudyAPI = (
|
||||
studyName: string,
|
||||
directions: StudyDirection[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
): Promise<StudySummary> => {
|
||||
return axiosInstance
|
||||
.post<CreateNewStudyResponse>(`/api/studies`, {
|
||||
@@ -226,8 +242,8 @@ export const deleteStudyAPI = (studyId: number): Promise<void> => {
|
||||
type RenameStudyResponse = {
|
||||
study_id: number
|
||||
study_name: string
|
||||
directions: StudyDirection[]
|
||||
user_attrs: Attribute[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
is_prefential: boolean
|
||||
datetime_start?: string
|
||||
}
|
||||
@@ -338,10 +354,10 @@ export const deleteStudyArtifactAPI = (
|
||||
|
||||
export const tellTrialAPI = (
|
||||
trialId: number,
|
||||
state: TrialStateFinished,
|
||||
state: Optuna.TrialStateFinished,
|
||||
values?: number[]
|
||||
): Promise<void> => {
|
||||
const req: { state: TrialState; values?: number[] } = {
|
||||
const req: { state: Optuna.TrialState; values?: number[] } = {
|
||||
state: state,
|
||||
values: values,
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ export const App: FC = () => {
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
backgroundColor: colorMode === "dark" ? "#121212" : "#ffffff",
|
||||
width: "100%",
|
||||
|
||||
@@ -175,7 +175,7 @@ export const AppDrawer: FC<{
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex", width: "100%" }}>
|
||||
<Box component="div" sx={{ display: "flex", width: "100%" }}>
|
||||
<AppBar position="fixed" open={open}>
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
@@ -316,7 +316,7 @@ export const AppDrawer: FC<{
|
||||
</ListItem>
|
||||
</List>
|
||||
)}
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box component="div" sx={{ flexGrow: 1 }} />
|
||||
<Divider />
|
||||
<List>
|
||||
{studyId !== undefined && (
|
||||
@@ -359,6 +359,7 @@ export const AppDrawer: FC<{
|
||||
aria-describedby="modal-modal-description"
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
import { WaveSurferArtifactViewer } from "./WaveSurferArtifactViewer"
|
||||
import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"
|
||||
import { CardMedia, Box } from "@mui/material"
|
||||
import { Artifact } from "ts/types/optuna"
|
||||
|
||||
export const ArtifactCardMedia: FC<{
|
||||
artifact: Artifact
|
||||
@@ -37,6 +38,7 @@ export const ArtifactCardMedia: FC<{
|
||||
} else if (artifact.mimetype.startsWith("audio")) {
|
||||
return (
|
||||
<Box
|
||||
component="div"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: height,
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
DialogActions,
|
||||
} from "@mui/material"
|
||||
import { actionCreator } from "../../action"
|
||||
import { Artifact } from "ts/types/optuna"
|
||||
|
||||
export const useDeleteTrialArtifactDialog = (): [
|
||||
(studyId: number, trialId: number, artifact: Artifact) => void,
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
isThreejsArtifact,
|
||||
} from "./ThreejsArtifactViewer"
|
||||
import { ArtifactCardMedia } from "./ArtifactCardMedia"
|
||||
import { StudyDetail } from "ts/types/optuna"
|
||||
|
||||
export const StudyArtifactCards: FC<{ study: StudyDetail }> = ({ study }) => {
|
||||
const theme = useTheme()
|
||||
@@ -40,7 +41,10 @@ export const StudyArtifactCards: FC<{ study: StudyDetail }> = ({ study }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box sx={{ display: "flex", flexWrap: "wrap", p: theme.spacing(1, 0) }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexWrap: "wrap", p: theme.spacing(1, 0) }}
|
||||
>
|
||||
{study.artifacts.map((artifact) => {
|
||||
const urlPath = `/artifacts/${study.id}/${artifact.artifact_id}`
|
||||
return (
|
||||
|
||||
@@ -9,6 +9,7 @@ import { PerspectiveCamera } from "three"
|
||||
import { Modal, Box, useTheme } from "@mui/material"
|
||||
import ClearIcon from "@mui/icons-material/Clear"
|
||||
import IconButton from "@mui/material/IconButton"
|
||||
import { Artifact } from "ts/types/optuna"
|
||||
|
||||
export const isThreejsArtifact = (artifact: Artifact): boolean => {
|
||||
return (
|
||||
@@ -145,6 +146,7 @@ export const useThreejsArtifactModal = (): [
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
isThreejsArtifact,
|
||||
} from "./ThreejsArtifactViewer"
|
||||
import { ArtifactCardMedia } from "./ArtifactCardMedia"
|
||||
import { Trial } from "ts/types/optuna"
|
||||
|
||||
export const TrialArtifactCards: FC<{ trial: Trial }> = ({ trial }) => {
|
||||
const theme = useTheme()
|
||||
@@ -49,7 +50,10 @@ export const TrialArtifactCards: FC<{ trial: Trial }> = ({ trial }) => {
|
||||
>
|
||||
Artifacts
|
||||
</Typography>
|
||||
<Box sx={{ display: "flex", flexWrap: "wrap", p: theme.spacing(1, 0) }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexWrap: "wrap", p: theme.spacing(1, 0) }}
|
||||
>
|
||||
{trial.artifacts.map((artifact) => {
|
||||
const urlPath = `/artifacts/${trial.study_id}/${trial.trial_id}/${artifact.artifact_id}`
|
||||
return (
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from "@mui/material"
|
||||
import { Link } from "react-router-dom"
|
||||
import LinkIcon from "@mui/icons-material/Link"
|
||||
import { StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const useBestTrials = (studyDetail: StudyDetail | null): Trial[] => {
|
||||
return useMemo(() => studyDetail?.best_trials || [], [studyDetail])
|
||||
@@ -75,6 +76,7 @@ export const BestTrialsCard: FC<{
|
||||
orientation="horizontal"
|
||||
/>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
overflow: "auto",
|
||||
height: "450px",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { FC, useEffect, useMemo, useState } from "react"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { useRecoilValue } from "recoil"
|
||||
import { useSnackbar } from "notistack"
|
||||
import { Link } from "react-router-dom"
|
||||
@@ -31,6 +32,7 @@ import { GraphEdf } from "./GraphEdf"
|
||||
import { GraphHistory } from "./GraphHistory"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { useQuery } from "../urlQuery"
|
||||
import { StudyDetails, StudySummary } from "ts/types/optuna"
|
||||
|
||||
const useQueriedStudies = (
|
||||
studies: StudySummary[],
|
||||
@@ -58,8 +60,8 @@ const getStudyListLink = (ids: number[]): string => {
|
||||
}
|
||||
|
||||
const isEqualDirections = (
|
||||
array1: StudyDirection[],
|
||||
array2: StudyDirection[]
|
||||
array1: Optuna.StudyDirection[],
|
||||
array2: Optuna.StudyDirection[]
|
||||
): boolean => {
|
||||
let i = array1.length
|
||||
if (i !== array2.length) return false
|
||||
@@ -115,10 +117,14 @@ export const CompareStudies: FC<{
|
||||
)
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<Box component="div" sx={{ display: "flex" }}>
|
||||
<AppDrawer toggleColorMode={toggleColorMode} toolbar={toolbar}>
|
||||
<Box sx={{ display: "flex", flexDirection: "row", width: "100%" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexDirection: "row", width: "100%" }}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
minWidth: studyListWidth,
|
||||
overflow: "auto",
|
||||
@@ -130,7 +136,7 @@ export const CompareStudies: FC<{
|
||||
<Typography sx={{ p: theme.spacing(1, 0) }}>
|
||||
Compare studies with Shift+Click
|
||||
</Typography>
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box component="div" sx={{ flexGrow: 1 }} />
|
||||
</ListSubheader>
|
||||
<Divider />
|
||||
{studies.map((study) => {
|
||||
@@ -200,6 +206,7 @@ export const CompareStudies: FC<{
|
||||
primary={`${study.study_id}. ${study.study_name}`}
|
||||
/>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
@@ -234,13 +241,17 @@ export const CompareStudies: FC<{
|
||||
</Box>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
overflow: "auto",
|
||||
height: `calc(100vh - ${theme.spacing(8)})`,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", flexDirection: "row", width: "100%" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexDirection: "row", width: "100%" }}
|
||||
>
|
||||
<StudiesGraph studies={selected} />
|
||||
</Box>
|
||||
</Box>
|
||||
@@ -274,7 +285,10 @@ const StudiesGraph: FC<{ studies: StudySummary[] }> = ({ studies }) => {
|
||||
const showStudyDetails = studies.map((study) => studyDetails[study.study_id])
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex", width: "100%", flexDirection: "column" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", width: "100%", flexDirection: "column" }}
|
||||
>
|
||||
<FormControl
|
||||
component="fieldset"
|
||||
sx={{
|
||||
|
||||
@@ -18,6 +18,8 @@ import { useRecoilValue } from "recoil"
|
||||
import { studySummariesState } from "../state"
|
||||
import RemoveIcon from "@mui/icons-material/Remove"
|
||||
import AddIcon from "@mui/icons-material/Add"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { StudySummary } from "ts/types/optuna"
|
||||
|
||||
export const useCreateStudyDialog = (): [() => void, () => ReactNode] => {
|
||||
const theme = useTheme()
|
||||
@@ -25,7 +27,9 @@ export const useCreateStudyDialog = (): [() => void, () => ReactNode] => {
|
||||
|
||||
const [newStudyName, setNewStudyName] = useState("")
|
||||
const [openNewStudyDialog, setOpenNewStudyDialog] = useState(false)
|
||||
const [directions, setDirections] = useState<StudyDirection[]>(["minimize"])
|
||||
const [directions, setDirections] = useState<Optuna.StudyDirection[]>([
|
||||
"minimize",
|
||||
])
|
||||
const studies = useRecoilValue<StudySummary[]>(studySummariesState)
|
||||
const newStudyNameAlreadyUsed = studies.some(
|
||||
(v) => v.study_name === newStudyName
|
||||
@@ -86,8 +90,8 @@ export const useCreateStudyDialog = (): [() => void, () => ReactNode] => {
|
||||
<Select
|
||||
value={directions[i]}
|
||||
onChange={(e) => {
|
||||
const newVal: StudyDirection[] = [...directions]
|
||||
newVal[i] = e.target.value as StudyDirection
|
||||
const newVal: Optuna.StudyDirection[] = [...directions]
|
||||
newVal[i] = e.target.value as Optuna.StudyDirection
|
||||
setDirections(newVal)
|
||||
}}
|
||||
>
|
||||
@@ -103,7 +107,10 @@ export const useCreateStudyDialog = (): [() => void, () => ReactNode] => {
|
||||
startIcon={<AddIcon />}
|
||||
sx={{ marginRight: theme.spacing(1) }}
|
||||
onClick={() => {
|
||||
const newVal: StudyDirection[] = [...directions, "minimize"]
|
||||
const newVal: Optuna.StudyDirection[] = [
|
||||
...directions,
|
||||
"minimize",
|
||||
]
|
||||
setDirections(newVal)
|
||||
}}
|
||||
>
|
||||
@@ -115,7 +122,7 @@ export const useCreateStudyDialog = (): [() => void, () => ReactNode] => {
|
||||
sx={{ marginRight: theme.spacing(1) }}
|
||||
disabled={directions.length <= 1}
|
||||
onClick={() => {
|
||||
const newVal: StudyDirection[] = [...directions]
|
||||
const newVal: Optuna.StudyDirection[] = [...directions]
|
||||
newVal.pop()
|
||||
setDirections(newVal)
|
||||
}}
|
||||
|
||||
@@ -20,6 +20,7 @@ import { getAxisInfo } from "../graphUtil"
|
||||
import { PlotType } from "../apiClient"
|
||||
import { useBackendRender } from "../state"
|
||||
import { usePlot } from "../hooks/usePlot"
|
||||
import { SearchSpaceItem, StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-contour"
|
||||
const CONTOUR_DISABLED_THRESHOLD = 100
|
||||
@@ -206,13 +207,8 @@ const ContourFrontend: FC<{
|
||||
)
|
||||
}
|
||||
|
||||
const filterFunc = (trial: Trial, objectiveId: number): boolean => {
|
||||
return (
|
||||
trial.state === "Complete" &&
|
||||
trial.values !== undefined &&
|
||||
trial.values[objectiveId] !== "inf" &&
|
||||
trial.values[objectiveId] !== "-inf"
|
||||
)
|
||||
const filterFunc = (trial: Trial): boolean => {
|
||||
return trial.state === "Complete" && trial.values !== undefined
|
||||
}
|
||||
|
||||
const plotContour = (
|
||||
@@ -227,7 +223,7 @@ const plotContour = (
|
||||
}
|
||||
|
||||
const trials: Trial[] = study ? study.trials : []
|
||||
const filteredTrials = trials.filter((t) => filterFunc(t, objectiveId))
|
||||
const filteredTrials = trials.filter((t) => filterFunc(t))
|
||||
if (filteredTrials.length < 2 || xParam === null || yParam === null) {
|
||||
plotly.react(plotDomId, [], {
|
||||
template: colorTheme,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Typography, useTheme, Box } from "@mui/material"
|
||||
import { Target, useFilteredTrialsFromStudies } from "../trialFilter"
|
||||
import { getCompareStudiesPlotAPI, CompareStudiesPlotType } from "../apiClient"
|
||||
import { usePlotlyColorTheme, useBackendRender } from "../state"
|
||||
import { StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const getPlotDomId = (objectiveId: number) => `graph-edf-${objectiveId}`
|
||||
|
||||
@@ -45,7 +46,7 @@ const GraphEdfBackend: FC<{
|
||||
console.error(err)
|
||||
})
|
||||
}, [studyIds, numCompletedTrials])
|
||||
return <Box id={domId} sx={{ height: "450px" }} />
|
||||
return <Box component="div" id={domId} sx={{ height: "450px" }} />
|
||||
}
|
||||
|
||||
const GraphEdfFrontend: FC<{
|
||||
@@ -74,14 +75,14 @@ const GraphEdfFrontend: FC<{
|
||||
}, [studies, target, colorTheme])
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box component="div">
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ margin: "1em 0", fontWeight: theme.typography.fontWeightBold }}
|
||||
>
|
||||
{`EDF for ${target.toLabel(studies[0].objective_names)}`}
|
||||
</Typography>
|
||||
<Box id={domId} sx={{ height: "450px" }} />
|
||||
<Box component="div" id={domId} sx={{ height: "450px" }} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,13 +22,15 @@ import {
|
||||
} from "../trialFilter"
|
||||
import { usePlotlyColorTheme } from "../state"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-history"
|
||||
|
||||
interface HistoryPlotInfo {
|
||||
study_name: string
|
||||
trials: Trial[]
|
||||
directions: StudyDirection[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
objective_names?: string[]
|
||||
}
|
||||
|
||||
@@ -210,6 +212,7 @@ export const GraphHistory: FC<{
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Box
|
||||
component="div"
|
||||
id={plotDomId}
|
||||
sx={{
|
||||
height: "450px",
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from "../state"
|
||||
import { PlotType } from "../apiClient"
|
||||
import { usePlot } from "../hooks/usePlot"
|
||||
import { ParamImportance, StudyDetail } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-hyperparameter-importances"
|
||||
|
||||
@@ -61,7 +62,7 @@ const GraphHyperparameterImportanceBackend: FC<{
|
||||
}
|
||||
}, [error])
|
||||
|
||||
return <Box id={plotDomId} sx={{ height: graphHeight }} />
|
||||
return <Box component="div" id={plotDomId} sx={{ height: graphHeight }} />
|
||||
}
|
||||
|
||||
const GraphHyperparameterImportanceFrontend: FC<{
|
||||
@@ -99,7 +100,7 @@ const GraphHyperparameterImportanceFrontend: FC<{
|
||||
>
|
||||
Hyperparameter Importance
|
||||
</Typography>
|
||||
<Box id={plotDomId} sx={{ height: graphHeight }} />
|
||||
<Box component="div" id={plotDomId} sx={{ height: graphHeight }} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as plotly from "plotly.js-dist-min"
|
||||
import React, { FC, useEffect } from "react"
|
||||
import { Box, Typography, useTheme, CardContent, Card } from "@mui/material"
|
||||
import { usePlotlyColorTheme } from "../state"
|
||||
import { Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-intermediate-values"
|
||||
|
||||
@@ -26,7 +27,7 @@ export const GraphIntermediateValues: FC<{
|
||||
>
|
||||
Intermediate values
|
||||
</Typography>
|
||||
<Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
<Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
@@ -76,13 +77,10 @@ const plotIntermediateValue = (
|
||||
t.state === "Running"
|
||||
)
|
||||
const plotData: Partial<plotly.PlotData>[] = filteredTrials.map((trial) => {
|
||||
const values = trial.intermediate_values.filter(
|
||||
(iv) => iv.value !== "inf" && iv.value !== "-inf" && iv.value !== "nan"
|
||||
)
|
||||
const isFeasible = trial.constraints.every((c) => c <= 0)
|
||||
return {
|
||||
x: values.map((iv) => iv.step),
|
||||
y: values.map((iv) => iv.value),
|
||||
x: trial.intermediate_values.map((iv) => iv.step),
|
||||
y: trial.intermediate_values.map((iv) => iv.value),
|
||||
marker: { maxdisplayed: 10 },
|
||||
mode: "lines+markers",
|
||||
type: "scatter",
|
||||
|
||||
@@ -20,6 +20,7 @@ import { useMergedUnionSearchSpace } from "../searchSpace"
|
||||
import { PlotType } from "../apiClient"
|
||||
import { useBackendRender } from "../state"
|
||||
import { usePlot } from "../hooks/usePlot"
|
||||
import { SearchSpaceItem, StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-parallel-coordinate"
|
||||
|
||||
@@ -121,7 +122,7 @@ const GraphParallelCoordinateBackend: FC<{
|
||||
}
|
||||
}, [error])
|
||||
|
||||
return <Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
return <Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
}
|
||||
|
||||
const GraphParallelCoordinateFrontend: FC<{
|
||||
@@ -161,7 +162,7 @@ const GraphParallelCoordinateFrontend: FC<{
|
||||
{renderCheckBoxes()}
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
<Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
@@ -246,7 +247,9 @@ const plotCoordinate = (
|
||||
)
|
||||
if (s.distribution.type === "CategoricalDistribution") {
|
||||
// categorical
|
||||
const vocabArr: string[] = s.distribution.choices.map((c) => c.value)
|
||||
const vocabArr: string[] = s.distribution.choices.map(
|
||||
(c) => c?.toString() ?? "null"
|
||||
)
|
||||
const tickvals: number[] = vocabArr.map((v, i) => i)
|
||||
return {
|
||||
label: breakLabelIfTooLong(s.name),
|
||||
|
||||
@@ -17,6 +17,8 @@ import { useNavigate } from "react-router-dom"
|
||||
import { PlotType } from "../apiClient"
|
||||
import { useBackendRender } from "../state"
|
||||
import { usePlot } from "../hooks/usePlot"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-pareto-front"
|
||||
|
||||
@@ -53,7 +55,7 @@ const GraphParetoFrontBackend: FC<{
|
||||
}
|
||||
}, [error])
|
||||
|
||||
return <Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
return <Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
}
|
||||
|
||||
const GraphParetoFrontFrontend: FC<{
|
||||
@@ -149,6 +151,7 @@ const GraphParetoFrontFrontend: FC<{
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Box
|
||||
component="div"
|
||||
id={plotDomId}
|
||||
sx={{
|
||||
height: "450px",
|
||||
@@ -159,12 +162,14 @@ const GraphParetoFrontFrontend: FC<{
|
||||
)
|
||||
}
|
||||
|
||||
const filterFunc = (trial: Trial, directions: StudyDirection[]): boolean => {
|
||||
const filterFunc = (
|
||||
trial: Trial,
|
||||
directions: Optuna.StudyDirection[]
|
||||
): boolean => {
|
||||
return (
|
||||
trial.state === "Complete" &&
|
||||
trial.values !== undefined &&
|
||||
trial.values.length === directions.length &&
|
||||
trial.values.every((v) => v !== "inf" && v !== "-inf")
|
||||
trial.values.length === directions.length
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import { useMergedUnionSearchSpace } from "../searchSpace"
|
||||
import { PlotType } from "../apiClient"
|
||||
import { usePlotlyColorTheme, useBackendRender } from "../state"
|
||||
import { usePlot } from "../hooks/usePlot"
|
||||
import { SearchSpaceItem, StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-rank"
|
||||
|
||||
@@ -65,7 +66,7 @@ const GraphRankBackend: FC<{
|
||||
}
|
||||
}, [error])
|
||||
|
||||
return <Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
return <Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
}
|
||||
|
||||
const GraphRankFrontend: FC<{
|
||||
@@ -163,7 +164,7 @@ const GraphRankFrontend: FC<{
|
||||
) : null}
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
<Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
@@ -193,21 +194,13 @@ const getRankPlotInfo = (
|
||||
const zValues: number[] = []
|
||||
const isFeasible: boolean[] = []
|
||||
const hovertext: string[] = []
|
||||
const convertTrialValueToNumber = (value: TrialValueNumber): number => {
|
||||
// TrialValueNumber takes `number`, "inf", or "-inf".
|
||||
return typeof value === "number"
|
||||
? value
|
||||
: value.includes("-")
|
||||
? -Infinity
|
||||
: Infinity
|
||||
}
|
||||
filteredTrials.forEach((trial, i) => {
|
||||
const xValue = xAxis.values[i]
|
||||
const yValue = yAxis.values[i]
|
||||
if (xValue && yValue && trial.values) {
|
||||
xValues.push(xValue)
|
||||
yValues.push(yValue)
|
||||
const zValue = convertTrialValueToNumber(trial.values[objectiveId])
|
||||
const zValue = trial.values[objectiveId]
|
||||
zValues.push(zValue)
|
||||
const feasibility = trial.constraints.every((c) => c <= 0)
|
||||
isFeasible.push(feasibility)
|
||||
|
||||
@@ -22,6 +22,7 @@ import { useMergedUnionSearchSpace } from "../searchSpace"
|
||||
import { PlotType } from "../apiClient"
|
||||
import { usePlotlyColorTheme, useBackendRender } from "../state"
|
||||
import { usePlot } from "../hooks/usePlot"
|
||||
import { SearchSpaceItem, StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-slice"
|
||||
|
||||
@@ -66,7 +67,7 @@ const GraphSliceBackend: FC<{
|
||||
}
|
||||
}, [error])
|
||||
|
||||
return <Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
return <Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
}
|
||||
|
||||
const GraphSliceFrontend: FC<{
|
||||
@@ -175,7 +176,7 @@ const GraphSliceFrontend: FC<{
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
<Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
@@ -291,7 +292,9 @@ const plotSlice = (
|
||||
automargin: true, // Otherwise the label is outside of the plot
|
||||
}
|
||||
} else {
|
||||
const vocabArr = selectedParamSpace.distribution.choices.map((c) => c.value)
|
||||
const vocabArr = selectedParamSpace.distribution.choices.map(
|
||||
(c) => c?.toString() ?? "null"
|
||||
)
|
||||
const tickvals: number[] = vocabArr.map((v, i) => i)
|
||||
layout["xaxis"] = {
|
||||
title: selectedParamTarget.toLabel(),
|
||||
|
||||
@@ -6,6 +6,8 @@ import { usePlotlyColorTheme } from "../state"
|
||||
import { PlotType } from "../apiClient"
|
||||
import { useBackendRender } from "../state"
|
||||
import { usePlot } from "../hooks/usePlot"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const plotDomId = "graph-timeline"
|
||||
const maxBars = 100
|
||||
@@ -96,7 +98,7 @@ const plotTimeline = (
|
||||
return
|
||||
}
|
||||
|
||||
const cm: Record<TrialState, string> = {
|
||||
const cm: Record<Optuna.TrialState, string> = {
|
||||
Complete: "blue",
|
||||
Fail: "red",
|
||||
Pruned: "orange",
|
||||
|
||||
@@ -31,6 +31,7 @@ import React, {
|
||||
import ReactMarkdown from "react-markdown"
|
||||
import remarkGfm from "remark-gfm"
|
||||
import remarkMath from "remark-math"
|
||||
// @ts-ignore
|
||||
import rehypeMathjax from "rehype-mathjax"
|
||||
import rehypeRaw from "rehype-raw"
|
||||
import LoadingButton from "@mui/lab/LoadingButton"
|
||||
@@ -41,6 +42,7 @@ import { Theme } from "@mui/material/styles"
|
||||
import {
|
||||
CodeComponent,
|
||||
ReactMarkdownNames,
|
||||
// @ts-ignore
|
||||
} from "react-markdown/lib/ast-to-react"
|
||||
import HtmlIcon from "@mui/icons-material/Html"
|
||||
import ModeEditIcon from "@mui/icons-material/ModeEdit"
|
||||
@@ -51,6 +53,7 @@ import { darcula } from "react-syntax-highlighter/dist/esm/styles/prism"
|
||||
import { actionCreator } from "../action"
|
||||
import { useRecoilValue } from "recoil"
|
||||
import { artifactIsAvailable, isFileUploading, useArtifacts } from "../state"
|
||||
import { Note } from "ts/types/optuna"
|
||||
|
||||
const placeholder = `## What is this feature for?
|
||||
|
||||
@@ -74,8 +77,11 @@ $$
|
||||
`
|
||||
|
||||
const CodeBlock: CodeComponent | ReactMarkdownNames = ({
|
||||
// @ts-ignore
|
||||
inline,
|
||||
// @ts-ignore
|
||||
className,
|
||||
// @ts-ignore
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
@@ -296,6 +302,7 @@ const MarkdownEditorModal: FC<{
|
||||
title="Markdown Editor"
|
||||
/>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
padding: theme.spacing(2),
|
||||
@@ -306,6 +313,7 @@ const MarkdownEditorModal: FC<{
|
||||
<MarkdownRenderer body={previewMarkdown} />
|
||||
</Box>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
width: "100%",
|
||||
flexGrow: 1,
|
||||
@@ -345,7 +353,10 @@ const MarkdownEditorModal: FC<{
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", flexDirection: "row", alignItems: "center" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexDirection: "row", alignItems: "center" }}
|
||||
>
|
||||
{notLatest && !saving && (
|
||||
<>
|
||||
<Typography
|
||||
@@ -369,7 +380,7 @@ const MarkdownEditorModal: FC<{
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box component="div" sx={{ flexGrow: 1 }} />
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => {
|
||||
@@ -452,6 +463,7 @@ const ArtifactUploader: FC<{
|
||||
|
||||
return (
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
width: "300px",
|
||||
padding: theme.spacing(0, 1),
|
||||
@@ -486,6 +498,7 @@ const ArtifactUploader: FC<{
|
||||
style={{ display: "none" }}
|
||||
/>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
border: dragOver
|
||||
? `3px dashed ${theme.palette.mode === "dark" ? "white" : "black"}`
|
||||
@@ -499,6 +512,7 @@ const ArtifactUploader: FC<{
|
||||
>
|
||||
{dragOver && (
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
|
||||
@@ -12,6 +12,7 @@ import { DataGrid, DataGridColumn } from "../DataGrid"
|
||||
import { BestTrialsCard } from "../BestTrialsCard"
|
||||
import { useStudyDetailValue, useStudySummaryValue } from "../../state"
|
||||
import { Contour } from "../GraphContour"
|
||||
import * as Optuna from "@optuna/types"
|
||||
|
||||
export const PreferentialAnalytics: FC<{ studyId: number }> = ({ studyId }) => {
|
||||
const theme = useTheme()
|
||||
@@ -19,7 +20,7 @@ export const PreferentialAnalytics: FC<{ studyId: number }> = ({ studyId }) => {
|
||||
const studyDetail = useStudyDetailValue(studyId)
|
||||
|
||||
const userAttrs = studySummary?.user_attrs || studyDetail?.user_attrs || []
|
||||
const userAttrColumns: DataGridColumn<Attribute>[] = [
|
||||
const userAttrColumns: DataGridColumn<Optuna.Attribute>[] = [
|
||||
{ field: "key", label: "Key", sortable: true },
|
||||
{ field: "value", label: "Value", sortable: true },
|
||||
]
|
||||
@@ -54,7 +55,7 @@ export const PreferentialAnalytics: FC<{ studyId: number }> = ({ studyId }) => {
|
||||
>
|
||||
Study User Attributes
|
||||
</Typography>
|
||||
<DataGrid<Attribute>
|
||||
<DataGrid<Optuna.Attribute>
|
||||
columns={userAttrColumns}
|
||||
rows={userAttrs}
|
||||
keyField={"key"}
|
||||
|
||||
@@ -26,6 +26,7 @@ import { ElkNode } from "elkjs/lib/elk-api.js"
|
||||
import { useStudyDetailValue } from "../../state"
|
||||
import { getArtifactUrlPath } from "./PreferentialTrials"
|
||||
import { PreferentialOutputComponent } from "./PreferentialOutputComponent"
|
||||
import { StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const elk = new ELK()
|
||||
const nodeWidth = 400
|
||||
@@ -67,6 +68,7 @@ const GraphNode: FC<NodeProps<NodeData>> = ({ data, isConnectable }) => {
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
display: "flex",
|
||||
displayDirection: "row",
|
||||
|
||||
@@ -21,6 +21,7 @@ import { formatDate } from "../../dateUtil"
|
||||
import { actionCreator } from "../../action"
|
||||
import { useStudyDetailValue } from "../../state"
|
||||
import { PreferentialOutputComponent } from "./PreferentialOutputComponent"
|
||||
import { PreferenceHistory, StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
type TrialType = "worst" | "none"
|
||||
|
||||
@@ -93,6 +94,7 @@ const CandidateTrial: FC<{
|
||||
</CardActions>
|
||||
<CardContent aria-label="trial" sx={cardComponentSx}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
padding: theme.spacing(2),
|
||||
}}
|
||||
@@ -126,6 +128,7 @@ const CandidateTrial: FC<{
|
||||
</CardContent>
|
||||
<Modal open={detailShown} onClose={() => setDetailShown(false)}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
@@ -141,6 +144,7 @@ const CandidateTrial: FC<{
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
@@ -182,12 +186,14 @@ const ChoiceTrials: FC<{
|
||||
|
||||
return (
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
marginBottom: theme.spacing(4),
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
@@ -232,6 +238,7 @@ const ChoiceTrials: FC<{
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
@@ -281,6 +288,7 @@ export const PreferentialHistory: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
|
||||
return (
|
||||
<Box
|
||||
component="div"
|
||||
padding={theme.spacing(2)}
|
||||
sx={{ display: "flex", flexDirection: "column" }}
|
||||
>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { FC, useMemo } from "react"
|
||||
import { ArtifactCardMedia } from "../Artifact/ArtifactCardMedia"
|
||||
import { MarkdownRenderer } from "../Note"
|
||||
import { Artifact, FeedbackComponentType, Trial } from "ts/types/optuna"
|
||||
|
||||
export const PreferentialOutputComponent: FC<{
|
||||
trial: Trial
|
||||
|
||||
@@ -34,6 +34,14 @@ import {
|
||||
useThreejsArtifactModal,
|
||||
} from "../Artifact/ThreejsArtifactViewer"
|
||||
import { PreferentialOutputComponent } from "./PreferentialOutputComponent"
|
||||
import {
|
||||
Artifact,
|
||||
FeedbackComponentArtifact,
|
||||
FeedbackComponentNote,
|
||||
FeedbackComponentType,
|
||||
StudyDetail,
|
||||
Trial,
|
||||
} from "ts/types/optuna"
|
||||
|
||||
const SettingsPage: FC<{
|
||||
studyDetail: StudyDetail
|
||||
@@ -216,6 +224,7 @@ const PreferentialTrial: FC<{
|
||||
if (trial === undefined) {
|
||||
return (
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
width: trialWidth,
|
||||
minHeight: trialHeight,
|
||||
@@ -244,6 +253,7 @@ const PreferentialTrial: FC<{
|
||||
>
|
||||
<CardActions>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
margin: theme.spacing(0, 2),
|
||||
maxWidth: `calc(${trialWidth}px - ${
|
||||
@@ -322,6 +332,7 @@ const PreferentialTrial: FC<{
|
||||
urlPath={urlPath}
|
||||
/>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
@@ -491,8 +502,8 @@ export const PreferentialTrials: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
null
|
||||
|
||||
return (
|
||||
<Box padding={theme.spacing(2)}>
|
||||
<Box display="flex">
|
||||
<Box component="div" padding={theme.spacing(2)}>
|
||||
<Box component="div" display="flex">
|
||||
<Typography
|
||||
variant="h4"
|
||||
sx={{
|
||||
@@ -502,6 +513,7 @@ export const PreferentialTrials: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
Which trial is the worst?
|
||||
</Typography>
|
||||
<Box
|
||||
component="div"
|
||||
display="flex"
|
||||
sx={{
|
||||
marginLeft: "auto",
|
||||
@@ -541,7 +553,10 @@ export const PreferentialTrials: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", flexDirection: "row", flexWrap: "wrap" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexDirection: "row", flexWrap: "wrap" }}
|
||||
>
|
||||
{displayTrials.display.map((t, index) => {
|
||||
const trial = activeTrials.find((trial) => trial.number === t)
|
||||
const candidates = displayTrials.display.filter(
|
||||
@@ -573,6 +588,7 @@ export const PreferentialTrials: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
{detailTrial !== null && (
|
||||
<Modal open={true} onClose={() => setDetailTrial(null)}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
@@ -588,6 +604,7 @@ export const PreferentialTrials: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from "@mui/material"
|
||||
import { actionCreator } from "../action"
|
||||
import { DebouncedInputTextField } from "./Debounce"
|
||||
import { StudySummary } from "ts/types/optuna"
|
||||
|
||||
export const useRenameStudyDialog = (
|
||||
studies: StudySummary[]
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from "@mui/material"
|
||||
import ClearIcon from "@mui/icons-material/Clear"
|
||||
import { usePlotBackendRendering, usePlotlyColorThemeState } from "../state"
|
||||
import { PlotlyColorThemeDark, PlotlyColorThemeLight } from "ts/types/optuna"
|
||||
|
||||
interface SettingsProps {
|
||||
handleClose: () => void
|
||||
|
||||
@@ -35,12 +35,12 @@ import { PreferentialHistory } from "./Preferential/PreferentialHistory"
|
||||
import { PreferentialAnalytics } from "./Preferential/PreferentialAnalytics"
|
||||
import { PreferentialGraph } from "./Preferential/PreferentialGraph"
|
||||
|
||||
interface ParamTypes {
|
||||
studyId: string
|
||||
}
|
||||
|
||||
export const useURLVars = (): number => {
|
||||
const { studyId } = useParams<ParamTypes>()
|
||||
const { studyId } = useParams<{ studyId: string }>()
|
||||
|
||||
if (studyId === undefined) {
|
||||
throw new Error("studyId is not defined")
|
||||
}
|
||||
|
||||
return useMemo(() => parseInt(studyId, 10), [studyId])
|
||||
}
|
||||
@@ -102,7 +102,10 @@ export const StudyDetail: FC<{
|
||||
content = isPreferential ? (
|
||||
<PreferentialAnalytics studyId={studyId} />
|
||||
) : (
|
||||
<Box sx={{ display: "flex", width: "100%", flexDirection: "column" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", width: "100%", flexDirection: "column" }}
|
||||
>
|
||||
<Typography
|
||||
variant="h5"
|
||||
sx={{
|
||||
@@ -162,7 +165,10 @@ export const StudyDetail: FC<{
|
||||
content = <TrialList studyDetail={studyDetail} />
|
||||
} else if (page === "trialTable") {
|
||||
content = (
|
||||
<Box sx={{ display: "flex", width: "100%", flexDirection: "column" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", width: "100%", flexDirection: "column" }}
|
||||
>
|
||||
<Card sx={{ margin: theme.spacing(2) }}>
|
||||
<CardContent>
|
||||
<TrialTable studyDetail={studyDetail} initialRowsPerPage={50} />
|
||||
@@ -173,6 +179,7 @@ export const StudyDetail: FC<{
|
||||
} else if (page === "note" && studyDetail !== null) {
|
||||
content = (
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
height: `calc(100vh - ${theme.spacing(8)})`,
|
||||
display: "flex",
|
||||
@@ -199,6 +206,7 @@ export const StudyDetail: FC<{
|
||||
} else if (page === "graph") {
|
||||
content = (
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
height: `calc(100vh - ${theme.spacing(8)})`,
|
||||
padding: theme.spacing(2),
|
||||
@@ -234,7 +242,7 @@ export const StudyDetail: FC<{
|
||||
)
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<Box component="div" sx={{ display: "flex" }}>
|
||||
<AppDrawer
|
||||
studyId={studyId}
|
||||
page={page}
|
||||
|
||||
@@ -26,6 +26,8 @@ import {
|
||||
} from "../state"
|
||||
import FormControlLabel from "@mui/material/FormControlLabel"
|
||||
import { artifactIsAvailable } from "../state"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { Trial } from "ts/types/optuna"
|
||||
|
||||
export const StudyHistory: FC<{ studyId: number }> = ({ studyId }) => {
|
||||
const theme = useTheme()
|
||||
@@ -45,13 +47,16 @@ export const StudyHistory: FC<{ studyId: number }> = ({ studyId }) => {
|
||||
}
|
||||
|
||||
const userAttrs = studySummary?.user_attrs || studyDetail?.user_attrs || []
|
||||
const userAttrColumns: DataGridColumn<Attribute>[] = [
|
||||
const userAttrColumns: DataGridColumn<Optuna.Attribute>[] = [
|
||||
{ field: "key", label: "Key", sortable: true },
|
||||
{ field: "value", label: "Value", sortable: true },
|
||||
]
|
||||
const trials: Trial[] = studyDetail?.trials || []
|
||||
return (
|
||||
<Box sx={{ display: "flex", width: "100%", flexDirection: "column" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", width: "100%", flexDirection: "column" }}
|
||||
>
|
||||
<FormControl
|
||||
component="fieldset"
|
||||
sx={{
|
||||
@@ -148,7 +153,7 @@ export const StudyHistory: FC<{ studyId: number }> = ({ studyId }) => {
|
||||
>
|
||||
Study User Attributes
|
||||
</Typography>
|
||||
<DataGrid<Attribute>
|
||||
<DataGrid<Optuna.Attribute>
|
||||
columns={userAttrColumns}
|
||||
rows={userAttrs}
|
||||
keyField={"key"}
|
||||
|
||||
@@ -39,6 +39,7 @@ import { useCreateStudyDialog } from "./CreateStudyDialog"
|
||||
import { useDeleteStudyDialog } from "./DeleteStudyDialog"
|
||||
import { useRenameStudyDialog } from "./RenameStudyDialog"
|
||||
import { useQuery } from "../urlQuery"
|
||||
import { StudySummary } from "ts/types/optuna"
|
||||
|
||||
export const StudyList: FC<{
|
||||
toggleColorMode: () => void
|
||||
@@ -97,6 +98,7 @@ export const StudyList: FC<{
|
||||
}))
|
||||
const sortBySelect = (
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
position: "relative",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
@@ -104,6 +106,7 @@ export const StudyList: FC<{
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
padding: theme.spacing(0, 2),
|
||||
height: "100%",
|
||||
@@ -134,7 +137,7 @@ export const StudyList: FC<{
|
||||
let studyListContent
|
||||
if (isLoading) {
|
||||
studyListContent = (
|
||||
<Box sx={{ margin: theme.spacing(2) }}>
|
||||
<Box component="div" sx={{ margin: theme.spacing(2) }}>
|
||||
<SvgIcon fontSize="small" color="action">
|
||||
<HourglassTop />
|
||||
</SvgIcon>
|
||||
@@ -170,7 +173,7 @@ export const StudyList: FC<{
|
||||
</CardContent>
|
||||
</CardActionArea>
|
||||
<CardActions disableSpacing sx={{ paddingTop: 0 }}>
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box component="div" sx={{ flexGrow: 1 }} />
|
||||
<IconButton
|
||||
aria-label="rename study"
|
||||
size="small"
|
||||
@@ -197,7 +200,7 @@ export const StudyList: FC<{
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<Box component="div" sx={{ display: "flex" }}>
|
||||
<AppDrawer toggleColorMode={toggleColorMode} toolbar={toolbar}>
|
||||
<Container
|
||||
sx={{
|
||||
@@ -208,7 +211,7 @@ export const StudyList: FC<{
|
||||
>
|
||||
<Card sx={{ margin: theme.spacing(2) }}>
|
||||
<CardContent>
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<Box component="div" sx={{ display: "flex" }}>
|
||||
<TextField
|
||||
onChange={(e) => {
|
||||
setStudyFilterText(e.target.value)
|
||||
@@ -229,7 +232,7 @@ export const StudyList: FC<{
|
||||
}}
|
||||
/>
|
||||
{sortBySelect}
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box component="div" sx={{ flexGrow: 1 }} />
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<Refresh />}
|
||||
@@ -262,7 +265,7 @@ export const StudyList: FC<{
|
||||
</Box>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Box sx={{ display: "flex", flexWrap: "wrap" }}>
|
||||
<Box component="div" sx={{ display: "flex", flexWrap: "wrap" }}>
|
||||
{studyListContent}
|
||||
</Box>
|
||||
</Container>
|
||||
|
||||
@@ -16,6 +16,16 @@ import {
|
||||
import { DebouncedInputTextField } from "./Debounce"
|
||||
import { actionCreator } from "../action"
|
||||
import { useTrialUpdatingValue } from "../state"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import {
|
||||
FormWidgets,
|
||||
ObjectiveChoiceWidget,
|
||||
ObjectiveSliderWidget,
|
||||
ObjectiveTextInputWidget,
|
||||
ObjectiveUserAttrRef,
|
||||
Trial,
|
||||
UserAttrFormWidget,
|
||||
} from "ts/types/optuna"
|
||||
|
||||
type WidgetState = {
|
||||
isValid: boolean
|
||||
@@ -26,7 +36,7 @@ type WidgetState = {
|
||||
export const TrialFormWidgets: FC<{
|
||||
trial: Trial
|
||||
objectiveNames: string[]
|
||||
directions: StudyDirection[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
formWidgets?: FormWidgets
|
||||
}> = ({ trial, objectiveNames, directions, formWidgets }) => {
|
||||
if (
|
||||
@@ -136,7 +146,7 @@ const UpdatableFormWidgets: FC<{
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ p: theme.spacing(1, 0) }}>
|
||||
<Box component="div" sx={{ p: theme.spacing(1, 0) }}>
|
||||
<Card
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -149,6 +159,7 @@ const UpdatableFormWidgets: FC<{
|
||||
>
|
||||
{widgetStates.map((ws) => ws.render())}
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
@@ -283,7 +294,7 @@ export const useSliderWidget = (
|
||||
<FormLabel>
|
||||
{metricName} - {widget.description}
|
||||
</FormLabel>
|
||||
<Box sx={{ padding: theme.spacing(0, 2) }}>
|
||||
<Box component="div" sx={{ padding: theme.spacing(0, 2) }}>
|
||||
<Slider
|
||||
onChange={(e) => {
|
||||
// @ts-ignore
|
||||
@@ -348,7 +359,7 @@ const ReadonlyFormWidgets: FC<{
|
||||
formWidgets: FormWidgets
|
||||
}> = ({ trial, widgetNames, formWidgets }) => {
|
||||
const theme = useTheme()
|
||||
const getValue = (i: number): string | TrialValueNumber => {
|
||||
const getValue = (i: number): string | number => {
|
||||
if (formWidgets.output_type === "user_attr") {
|
||||
const widget = formWidgets.widgets[i] as UserAttrFormWidget
|
||||
return (
|
||||
@@ -369,7 +380,7 @@ const ReadonlyFormWidgets: FC<{
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ p: theme.spacing(1, 0) }}>
|
||||
<Box component="div" sx={{ p: theme.spacing(1, 0) }}>
|
||||
<Card
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -424,11 +435,9 @@ const ReadonlyFormWidgets: FC<{
|
||||
<FormLabel>
|
||||
{widgetName} - {widget.description}
|
||||
</FormLabel>
|
||||
<Box sx={{ padding: theme.spacing(0, 2) }}>
|
||||
<Box component="div" sx={{ padding: theme.spacing(0, 2) }}>
|
||||
<Slider
|
||||
defaultValue={
|
||||
value === "inf" || value === "-inf" ? undefined : value
|
||||
}
|
||||
defaultValue={value}
|
||||
min={widget.min}
|
||||
max={widget.max}
|
||||
step={widget.step}
|
||||
|
||||
@@ -19,6 +19,7 @@ import FilterListIcon from "@mui/icons-material/FilterList"
|
||||
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"
|
||||
import CheckBoxIcon from "@mui/icons-material/CheckBox"
|
||||
import StopCircleIcon from "@mui/icons-material/StopCircle"
|
||||
import * as Optuna from "@optuna/types"
|
||||
|
||||
import { TrialNote } from "./Note"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
@@ -29,10 +30,10 @@ import { actionCreator } from "../action"
|
||||
import { TrialFormWidgets } from "./TrialFormWidgets"
|
||||
import { TrialArtifactCards } from "./Artifact/TrialArtifactCards"
|
||||
import { useQuery } from "../urlQuery"
|
||||
|
||||
import { useVirtualizer } from "@tanstack/react-virtual"
|
||||
import { FormWidgets, StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
const states: TrialState[] = [
|
||||
const states: Optuna.TrialState[] = [
|
||||
"Complete",
|
||||
"Pruned",
|
||||
"Fail",
|
||||
@@ -49,7 +50,7 @@ type Color =
|
||||
| "success"
|
||||
| "warning"
|
||||
|
||||
const getChipColor = (state: TrialState): Color => {
|
||||
const getChipColor = (state: Optuna.TrialState): Color => {
|
||||
if (state === "Complete") {
|
||||
return "primary"
|
||||
} else if (state === "Running") {
|
||||
@@ -64,25 +65,25 @@ const getChipColor = (state: TrialState): Color => {
|
||||
return "default"
|
||||
}
|
||||
|
||||
const useExcludedStates = (query: URLSearchParams): TrialState[] => {
|
||||
const useExcludedStates = (query: URLSearchParams): Optuna.TrialState[] => {
|
||||
return useMemo(() => {
|
||||
const exclude = query.get("exclude")
|
||||
if (exclude === null) {
|
||||
return []
|
||||
}
|
||||
const excluded: TrialState[] = exclude
|
||||
const excluded: Optuna.TrialState[] = exclude
|
||||
.split(",")
|
||||
.map((s): TrialState | undefined => {
|
||||
.map((s): Optuna.TrialState | undefined => {
|
||||
return states.find((state) => state.toUpperCase() === s.toUpperCase())
|
||||
})
|
||||
.filter((s): s is TrialState => s !== undefined)
|
||||
.filter((s): s is Optuna.TrialState => s !== undefined)
|
||||
return excluded
|
||||
}, [query])
|
||||
}
|
||||
|
||||
const useTrials = (
|
||||
studyDetail: StudyDetail | null,
|
||||
excludedStates: TrialState[]
|
||||
excludedStates: Optuna.TrialState[]
|
||||
): Trial[] => {
|
||||
return useMemo(() => {
|
||||
let result = studyDetail !== null ? studyDetail.trials : []
|
||||
@@ -123,7 +124,7 @@ const useIsBestTrial = (
|
||||
export const TrialListDetail: FC<{
|
||||
trial: Trial
|
||||
isBestTrial: (trialId: number) => boolean
|
||||
directions: StudyDirection[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
objectiveNames: string[]
|
||||
formWidgets?: FormWidgets
|
||||
}> = ({ trial, isBestTrial, directions, objectiveNames, formWidgets }) => {
|
||||
@@ -138,7 +139,7 @@ export const TrialListDetail: FC<{
|
||||
["Value", trial.values?.map((v) => v.toString()).join(", ") || "None"],
|
||||
[
|
||||
"Intermediate Values",
|
||||
<Box>
|
||||
<Box component="div">
|
||||
{trial.intermediate_values.map((v) => (
|
||||
<Typography key={v.step}>
|
||||
{v.step} {v.value}
|
||||
@@ -148,7 +149,7 @@ export const TrialListDetail: FC<{
|
||||
],
|
||||
[
|
||||
"Parameter",
|
||||
<Box>
|
||||
<Box component="div">
|
||||
{params.map((p) => (
|
||||
<Typography key={p.name}>
|
||||
{p.name} {p.param_external_value}
|
||||
@@ -172,7 +173,7 @@ export const TrialListDetail: FC<{
|
||||
],
|
||||
[
|
||||
"User Attributes",
|
||||
<Box>
|
||||
<Box component="div">
|
||||
{trial.user_attrs.map((t) => (
|
||||
<Typography key={t.key}>
|
||||
{t.key} {t.value}
|
||||
@@ -186,6 +187,7 @@ export const TrialListDetail: FC<{
|
||||
value: string | null | ReactNode
|
||||
): ReactNode => (
|
||||
<Box
|
||||
component="div"
|
||||
key={key}
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -203,6 +205,7 @@ export const TrialListDetail: FC<{
|
||||
{key}
|
||||
</Typography>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
bgcolor:
|
||||
theme.palette.mode === "dark"
|
||||
@@ -223,7 +226,10 @@ export const TrialListDetail: FC<{
|
||||
)
|
||||
|
||||
return (
|
||||
<Box sx={{ width: "100%", padding: theme.spacing(2, 2, 0, 2) }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ width: "100%", padding: theme.spacing(2, 2, 0, 2) }}
|
||||
>
|
||||
<Typography
|
||||
variant="h4"
|
||||
sx={{
|
||||
@@ -234,6 +240,7 @@ export const TrialListDetail: FC<{
|
||||
Trial {trial.number} (trial_id={trial.trial_id})
|
||||
</Typography>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
marginBottom: theme.spacing(1),
|
||||
display: "flex",
|
||||
@@ -249,7 +256,7 @@ export const TrialListDetail: FC<{
|
||||
{isBestTrial(trial.trial_id) ? (
|
||||
<Chip label={"Best Trial"} color="secondary" variant="outlined" />
|
||||
) : null}
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box component="div" sx={{ flexGrow: 1 }} />
|
||||
{trial.state === "Running" ? (
|
||||
<Button
|
||||
variant="outlined"
|
||||
@@ -286,6 +293,7 @@ export const TrialListDetail: FC<{
|
||||
formWidgets={formWidgets}
|
||||
/>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
marginBottom: theme.spacing(2),
|
||||
display: "flex",
|
||||
@@ -303,7 +311,7 @@ export const TrialListDetail: FC<{
|
||||
|
||||
const getTrialListLink = (
|
||||
studyId: number,
|
||||
exclude: TrialState[],
|
||||
exclude: Optuna.TrialState[],
|
||||
numbers: number[]
|
||||
): string => {
|
||||
const base = URL_PREFIX + `/studies/${studyId}/trials`
|
||||
@@ -356,8 +364,12 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
queried.length > 0 ? queried : trials.length > 0 ? [trials[0]] : []
|
||||
|
||||
return (
|
||||
<Box sx={{ display: "flex", flexDirection: "row", width: "100%" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexDirection: "row", width: "100%" }}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
ref={listParentRef}
|
||||
sx={{
|
||||
minWidth: trialListWidth,
|
||||
@@ -370,7 +382,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
<Typography sx={{ p: theme.spacing(1, 0) }}>
|
||||
{trials.length} Trials
|
||||
</Typography>
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box component="div" sx={{ flexGrow: 1 }} />
|
||||
<IconButton
|
||||
aria-label="Filter"
|
||||
aria-controls={openFilterMenu ? "filter-trials" : undefined}
|
||||
@@ -424,6 +436,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
</ListSubheader>
|
||||
<Divider />
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: `${rowVirtualizer.getTotalSize()}px`,
|
||||
@@ -485,7 +498,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
}}
|
||||
>
|
||||
<ListItemText primary={`Trial ${trial.number}`} />
|
||||
<Box>
|
||||
<Box component="div">
|
||||
<Chip
|
||||
color={getChipColor(trial.state)}
|
||||
label={trial.state}
|
||||
@@ -512,13 +525,17 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({
|
||||
</Box>
|
||||
<Divider orientation="vertical" flexItem />
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
overflow: "auto",
|
||||
height: `calc(100vh - ${theme.spacing(8)})`,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", flexDirection: "row", width: "100%" }}>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{ display: "flex", flexDirection: "row", width: "100%" }}
|
||||
>
|
||||
{selected.length === 0
|
||||
? null
|
||||
: selected.map((t) => (
|
||||
|
||||
@@ -5,6 +5,7 @@ import DownloadIcon from "@mui/icons-material/Download"
|
||||
|
||||
import { DataGridColumn, DataGrid } from "./DataGrid"
|
||||
import { Link } from "react-router-dom"
|
||||
import { StudyDetail, Trial } from "ts/types/optuna"
|
||||
|
||||
export const TrialTable: FC<{
|
||||
studyDetail: StudyDetail | null
|
||||
@@ -26,8 +27,8 @@ export const TrialTable: FC<{
|
||||
},
|
||||
]
|
||||
const valueComparator = (
|
||||
firstVal?: TrialValueNumber,
|
||||
secondVal?: TrialValueNumber,
|
||||
firstVal?: number,
|
||||
secondVal?: number,
|
||||
ascending: boolean = true
|
||||
): number => {
|
||||
if (firstVal === secondVal) {
|
||||
@@ -38,11 +39,6 @@ export const TrialTable: FC<{
|
||||
} else if (secondVal === undefined) {
|
||||
return ascending ? 1 : -1
|
||||
}
|
||||
if (firstVal === "-inf" || secondVal === "inf") {
|
||||
return 1
|
||||
} else if (secondVal === "-inf" || firstVal === "inf") {
|
||||
return -1
|
||||
}
|
||||
return firstVal < secondVal ? 1 : -1
|
||||
}
|
||||
if (studyDetail === null || studyDetail.directions.length === 1) {
|
||||
@@ -96,7 +92,7 @@ export const TrialTable: FC<{
|
||||
const sortable = s.distribution.type !== "CategoricalDistribution"
|
||||
const filterChoices: (string | null)[] | undefined =
|
||||
s.distribution.type === "CategoricalDistribution"
|
||||
? s.distribution.choices.map((c) => c.value)
|
||||
? s.distribution.choices.map((c) => c?.toString() ?? "null")
|
||||
: undefined
|
||||
const hasMissingValue = trials.some(
|
||||
(t) => !t.params.some((p) => p.name === s.name)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as plotly from "plotly.js-dist-min"
|
||||
import React, { FC, useEffect } from "react"
|
||||
import { Box } from "@mui/material"
|
||||
import { PlotlyGraphObject } from "ts/types/optuna"
|
||||
|
||||
export const UserDefinedPlot: FC<{
|
||||
graphObject: PlotlyGraphObject
|
||||
@@ -17,5 +18,5 @@ export const UserDefinedPlot: FC<{
|
||||
}
|
||||
}, [graphObject])
|
||||
|
||||
return <Box id={plotDomId} sx={{ height: "450px" }} />
|
||||
return <Box component="div" id={plotDomId} sx={{ height: "450px" }} />
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const formatDate = (date: Date): string => {
|
||||
const options = {
|
||||
const options: Intl.DateTimeFormatOptions = {
|
||||
year: "numeric",
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
const filterFunc = (trial: Trial, directions: StudyDirection[]): boolean => {
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { Trial } from "./types/optuna"
|
||||
|
||||
const filterFunc = (
|
||||
trial: Trial,
|
||||
directions: Optuna.StudyDirection[]
|
||||
): boolean => {
|
||||
return (
|
||||
trial.state === "Complete" &&
|
||||
trial.values !== undefined &&
|
||||
trial.values.length === directions.length &&
|
||||
trial.values.every((v) => v !== "inf" && v !== "-inf")
|
||||
trial.values.length === directions.length
|
||||
)
|
||||
}
|
||||
|
||||
export const getDominatedTrials = (
|
||||
trials: Trial[],
|
||||
directions: StudyDirection[]
|
||||
directions: Optuna.StudyDirection[]
|
||||
): Trial[] => {
|
||||
// TODO(c-bata): Use log-linear algorithm like Optuna.
|
||||
// TODO(c-bata): Use this function at GraphParetoFront.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { SearchSpaceItem, Trial } from "./types/optuna"
|
||||
import * as Optuna from "@optuna/types"
|
||||
|
||||
const PADDING_RATIO = 0.05
|
||||
|
||||
export type AxisInfo = {
|
||||
@@ -33,7 +36,7 @@ export const getAxisInfo = (
|
||||
const getAxisInfoForCategoricalParams = (
|
||||
trials: Trial[],
|
||||
paramName: string,
|
||||
distribution: CategoricalDistribution
|
||||
distribution: Optuna.CategoricalDistribution
|
||||
): AxisInfo => {
|
||||
const values = trials.map(
|
||||
(trial) =>
|
||||
@@ -42,7 +45,7 @@ const getAxisInfoForCategoricalParams = (
|
||||
)
|
||||
|
||||
const indices = distribution.choices
|
||||
.map((c) => c.value)
|
||||
.map((c) => c?.toString() ?? "null")
|
||||
.sort((a, b) =>
|
||||
a.toLowerCase() < b.toLowerCase()
|
||||
? -1
|
||||
@@ -62,7 +65,7 @@ const getAxisInfoForCategoricalParams = (
|
||||
const getAxisInfoForNumericalParams = (
|
||||
trials: Trial[],
|
||||
paramName: string,
|
||||
distribution: FloatDistribution | IntDistribution
|
||||
distribution: Optuna.FloatDistribution | Optuna.IntDistribution
|
||||
): AxisInfo => {
|
||||
let min = 0
|
||||
let max = 0
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useSnackbar } from "notistack"
|
||||
import { getParamImportances } from "../apiClient"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { AxiosError } from "axios"
|
||||
import { ParamImportance } from "ts/types/optuna"
|
||||
|
||||
export const useParamImportance = ({
|
||||
numCompletedTrials,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { useMemo } from "react"
|
||||
import { SearchSpaceItem } from "./types/optuna"
|
||||
import * as Optuna from "@optuna/types"
|
||||
|
||||
export const mergeUnionSearchSpace = (
|
||||
unionSearchSpace: SearchSpaceItem[]
|
||||
): SearchSpaceItem[] => {
|
||||
const knownElements = new Map<string, Distribution>()
|
||||
const knownElements = new Map<string, Optuna.Distribution>()
|
||||
unionSearchSpace.forEach((s) => {
|
||||
const d = knownElements.get(s.name)
|
||||
if (d === undefined) {
|
||||
@@ -17,7 +19,7 @@ export const mergeUnionSearchSpace = (
|
||||
// CategoricalDistribution.choices will never be changed
|
||||
return
|
||||
}
|
||||
const updated: Distribution = {
|
||||
const updated: Optuna.Distribution = {
|
||||
...d,
|
||||
low: Math.min(d.low, s.distribution.low),
|
||||
high: Math.max(d.high, s.distribution.high),
|
||||
@@ -28,7 +30,7 @@ export const mergeUnionSearchSpace = (
|
||||
.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0))
|
||||
.map((name) => ({
|
||||
name: name,
|
||||
distribution: knownElements.get(name) as Distribution,
|
||||
distribution: knownElements.get(name) as Optuna.Distribution,
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { atom, useRecoilValue } from "recoil"
|
||||
import {
|
||||
LightColorTemplates,
|
||||
DarkColorTemplates,
|
||||
} from "./components/PlotlyColorTemplates"
|
||||
import { useLocalStorage } from "usehooks-ts"
|
||||
import {
|
||||
Artifact,
|
||||
PlotlyColorTheme,
|
||||
StudyDetail,
|
||||
StudyDetails,
|
||||
StudySummary,
|
||||
} from "./types/optuna"
|
||||
|
||||
export const studySummariesState = atom<StudySummary[]>({
|
||||
key: "studySummaries",
|
||||
@@ -86,7 +94,7 @@ export const useTrialUpdatingValue = (trialId: number): boolean => {
|
||||
|
||||
export const useStudyDirections = (
|
||||
studyId: number
|
||||
): StudyDirection[] | null => {
|
||||
): Optuna.StudyDirection[] | null => {
|
||||
const studyDetail = useStudyDetailValue(studyId)
|
||||
const studySummary = useStudySummaryValue(studyId)
|
||||
return studyDetail?.directions || studySummary?.directions || null
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useMemo, useState } from "react"
|
||||
import * as Optuna from "@optuna/types"
|
||||
import { SearchSpaceItem, StudyDetail, Trial } from "./types/optuna"
|
||||
|
||||
type TargetKind = "objective" | "user_attr" | "params"
|
||||
|
||||
@@ -67,7 +69,7 @@ export class Target {
|
||||
return null
|
||||
}
|
||||
const value = trial.values[objectiveId]
|
||||
if (value === "inf" || value === "-inf") {
|
||||
if (value === Infinity || value === -Infinity) {
|
||||
return null
|
||||
}
|
||||
return value
|
||||
@@ -209,8 +211,11 @@ export const useObjectiveAndUserAttrTargetsFromStudies = (
|
||||
}, Number.MAX_VALUE)
|
||||
}, [studies])
|
||||
|
||||
const intersect = (arrays: AttributeSpec[][]) => {
|
||||
const atrEqual = (obj1: AttributeSpec, obj2: AttributeSpec) => {
|
||||
const intersect = (arrays: Optuna.AttributeSpec[][]) => {
|
||||
const atrEqual = (
|
||||
obj1: Optuna.AttributeSpec,
|
||||
obj2: Optuna.AttributeSpec
|
||||
) => {
|
||||
return obj1.key === obj2.key
|
||||
}
|
||||
return arrays.reduce((a, b) =>
|
||||
|
||||
Vendored
-237
@@ -6,240 +6,3 @@ declare module "*.svg"
|
||||
declare const APP_BAR_TITLE: string
|
||||
declare const API_ENDPOINT: string
|
||||
declare const URL_PREFIX: string
|
||||
|
||||
type TrialValueNumber = number | "inf" | "-inf"
|
||||
type TrialIntermediateValueNumber = number | "inf" | "-inf" | "nan"
|
||||
type TrialState = "Running" | "Complete" | "Pruned" | "Fail" | "Waiting"
|
||||
type TrialStateFinished = "Complete" | "Fail" | "Pruned"
|
||||
type StudyDirection = "maximize" | "minimize" | "not_set"
|
||||
type PreferenceFeedbackMode = "ChooseWorst"
|
||||
|
||||
type FloatDistribution = {
|
||||
type: "FloatDistribution"
|
||||
low: number
|
||||
high: number
|
||||
step: number
|
||||
log: boolean
|
||||
}
|
||||
|
||||
type IntDistribution = {
|
||||
type: "IntDistribution"
|
||||
low: number
|
||||
high: number
|
||||
step: number
|
||||
log: boolean
|
||||
}
|
||||
|
||||
type CategoricalDistribution = {
|
||||
type: "CategoricalDistribution"
|
||||
choices: { pytype: string; value: string }[]
|
||||
}
|
||||
|
||||
type Distribution =
|
||||
| FloatDistribution
|
||||
| IntDistribution
|
||||
| CategoricalDistribution
|
||||
|
||||
type GraphVisibility = {
|
||||
history: boolean
|
||||
paretoFront: boolean
|
||||
parallelCoordinate: boolean
|
||||
intermediateValues: boolean
|
||||
edf: boolean
|
||||
contour: boolean
|
||||
importances: boolean
|
||||
slice: boolean
|
||||
}
|
||||
|
||||
type TrialIntermediateValue = {
|
||||
step: number
|
||||
value: TrialIntermediateValueNumber
|
||||
}
|
||||
|
||||
type TrialParam = {
|
||||
name: string
|
||||
param_internal_value: number
|
||||
param_external_value: string
|
||||
param_external_type: string
|
||||
distribution: Distribution
|
||||
}
|
||||
|
||||
type ParamImportance = {
|
||||
name: string
|
||||
importance: number
|
||||
distribution: Distribution
|
||||
}
|
||||
|
||||
type SearchSpaceItem = {
|
||||
name: string
|
||||
distribution: Distribution
|
||||
}
|
||||
|
||||
type Attribute = {
|
||||
key: string
|
||||
value: string
|
||||
}
|
||||
|
||||
type AttributeSpec = {
|
||||
key: string
|
||||
sortable: boolean
|
||||
}
|
||||
|
||||
type Note = {
|
||||
version: number
|
||||
body: string
|
||||
}
|
||||
|
||||
type Artifact = {
|
||||
artifact_id: string
|
||||
filename: string
|
||||
mimetype: string
|
||||
encoding: string
|
||||
}
|
||||
|
||||
type Trial = {
|
||||
trial_id: number
|
||||
study_id: number
|
||||
number: number
|
||||
state: TrialState
|
||||
values?: TrialValueNumber[]
|
||||
intermediate_values: TrialIntermediateValue[]
|
||||
datetime_start?: Date
|
||||
datetime_complete?: Date
|
||||
params: TrialParam[]
|
||||
fixed_params: {
|
||||
name: string
|
||||
param_external_value: string
|
||||
}[]
|
||||
user_attrs: Attribute[]
|
||||
constraints: number[]
|
||||
note: Note
|
||||
artifacts: Artifact[]
|
||||
}
|
||||
|
||||
type StudySummary = {
|
||||
study_id: number
|
||||
study_name: string
|
||||
directions: StudyDirection[]
|
||||
user_attrs: Attribute[]
|
||||
is_preferential: boolean
|
||||
datetime_start?: Date
|
||||
}
|
||||
|
||||
type ObjectiveChoiceWidget = {
|
||||
type: "choice"
|
||||
description: string
|
||||
user_attr_key?: string
|
||||
choices: string[]
|
||||
values: number[]
|
||||
}
|
||||
|
||||
type ObjectiveSliderWidget = {
|
||||
type: "slider"
|
||||
description: string
|
||||
user_attr_key?: string
|
||||
min: number
|
||||
max: number
|
||||
step: number | null
|
||||
labels:
|
||||
| {
|
||||
value: number
|
||||
label: string
|
||||
}[]
|
||||
| null
|
||||
}
|
||||
|
||||
type ObjectiveTextInputWidget = {
|
||||
type: "text"
|
||||
description: string
|
||||
optional: boolean
|
||||
user_attr_key?: string
|
||||
}
|
||||
|
||||
type ObjectiveUserAttrRef = {
|
||||
type: "user_attr"
|
||||
key: string
|
||||
}
|
||||
|
||||
type ObjectiveFormWidget =
|
||||
| ObjectiveChoiceWidget
|
||||
| ObjectiveSliderWidget
|
||||
| ObjectiveTextInputWidget
|
||||
| ObjectiveUserAttrRef
|
||||
|
||||
type UserAttrFormWidget =
|
||||
| ObjectiveChoiceWidget
|
||||
| ObjectiveSliderWidget
|
||||
| ObjectiveTextInputWidget
|
||||
|
||||
type FormWidgets =
|
||||
| {
|
||||
output_type: "objective"
|
||||
widgets: ObjectiveFormWidget[]
|
||||
}
|
||||
| {
|
||||
output_type: "user_attr"
|
||||
widgets: UserAttrFormWidget[]
|
||||
}
|
||||
|
||||
type PlotlyGraphObject = {
|
||||
id: string
|
||||
graph_object: string
|
||||
}
|
||||
|
||||
type FeedbackComponentNote = {
|
||||
output_type: "note"
|
||||
}
|
||||
|
||||
type FeedbackComponentArtifact = {
|
||||
output_type: "artifact"
|
||||
artifact_key: string
|
||||
}
|
||||
|
||||
type FeedbackComponentType = FeedbackComponentArtifact | FeedbackComponentNote
|
||||
|
||||
type StudyDetail = {
|
||||
id: number
|
||||
name: string
|
||||
directions: StudyDirection[]
|
||||
user_attrs: Attribute[]
|
||||
datetime_start: Date
|
||||
best_trials: Trial[]
|
||||
trials: Trial[]
|
||||
intersection_search_space: SearchSpaceItem[]
|
||||
union_search_space: SearchSpaceItem[]
|
||||
union_user_attrs: AttributeSpec[]
|
||||
has_intermediate_values: boolean
|
||||
note: Note
|
||||
is_preferential: boolean
|
||||
objective_names?: string[]
|
||||
form_widgets?: FormWidgets
|
||||
feedback_component_type: FeedbackComponentType
|
||||
preferences?: [number, number][]
|
||||
preference_history?: PreferenceHistory[]
|
||||
plotly_graph_objects: PlotlyGraphObject[]
|
||||
artifacts: Artifact[]
|
||||
skipped_trial_numbers: number[]
|
||||
}
|
||||
|
||||
type StudyDetails = {
|
||||
[study_id: string]: StudyDetail
|
||||
}
|
||||
|
||||
type PreferenceHistory = {
|
||||
id: string
|
||||
candidates: number[]
|
||||
clicked: number
|
||||
feedback_mode: PreferenceFeedbackMode
|
||||
timestamp: Date
|
||||
preferences: [number, number][]
|
||||
is_removed: boolean
|
||||
}
|
||||
|
||||
type PlotlyColorThemeDark = "default"
|
||||
type PlotlyColorThemeLight = "default" | "seaborn" | "presentation" | "ggplot2"
|
||||
|
||||
type PlotlyColorTheme = {
|
||||
dark: PlotlyColorThemeDark
|
||||
light: PlotlyColorThemeLight
|
||||
}
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
import * as Optuna from "@optuna/types"
|
||||
|
||||
export type PreferenceFeedbackMode = "ChooseWorst"
|
||||
|
||||
export type GraphVisibility = {
|
||||
history: boolean
|
||||
paretoFront: boolean
|
||||
parallelCoordinate: boolean
|
||||
intermediateValues: boolean
|
||||
edf: boolean
|
||||
contour: boolean
|
||||
importances: boolean
|
||||
slice: boolean
|
||||
}
|
||||
|
||||
export type TrialParam = {
|
||||
name: string
|
||||
param_internal_value: number
|
||||
param_external_value: string
|
||||
param_external_type: string
|
||||
distribution: Optuna.Distribution
|
||||
}
|
||||
|
||||
export type ParamImportance = {
|
||||
name: string
|
||||
importance: number
|
||||
distribution: Optuna.Distribution
|
||||
}
|
||||
|
||||
export type SearchSpaceItem = {
|
||||
name: string
|
||||
distribution: Optuna.Distribution
|
||||
}
|
||||
|
||||
export type Note = {
|
||||
version: number
|
||||
body: string
|
||||
}
|
||||
|
||||
export type Artifact = {
|
||||
artifact_id: string
|
||||
filename: string
|
||||
mimetype: string
|
||||
encoding: string
|
||||
}
|
||||
|
||||
export type Trial = {
|
||||
trial_id: number
|
||||
study_id: number
|
||||
number: number
|
||||
state: Optuna.TrialState
|
||||
values?: number[]
|
||||
intermediate_values: Optuna.TrialIntermediateValue[]
|
||||
datetime_start?: Date
|
||||
datetime_complete?: Date
|
||||
params: TrialParam[]
|
||||
fixed_params: {
|
||||
name: string
|
||||
param_external_value: string
|
||||
}[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
constraints: number[]
|
||||
note: Note
|
||||
artifacts: Artifact[]
|
||||
}
|
||||
|
||||
export type StudySummary = {
|
||||
study_id: number
|
||||
study_name: string
|
||||
directions: Optuna.StudyDirection[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
is_preferential: boolean
|
||||
datetime_start?: Date
|
||||
}
|
||||
|
||||
export type ObjectiveChoiceWidget = {
|
||||
type: "choice"
|
||||
description: string
|
||||
user_attr_key?: string
|
||||
choices: string[]
|
||||
values: number[]
|
||||
}
|
||||
|
||||
export type ObjectiveSliderWidget = {
|
||||
type: "slider"
|
||||
description: string
|
||||
user_attr_key?: string
|
||||
min: number
|
||||
max: number
|
||||
step: number | null
|
||||
labels:
|
||||
| {
|
||||
value: number
|
||||
label: string
|
||||
}[]
|
||||
| null
|
||||
}
|
||||
|
||||
export type ObjectiveTextInputWidget = {
|
||||
type: "text"
|
||||
description: string
|
||||
optional: boolean
|
||||
user_attr_key?: string
|
||||
}
|
||||
|
||||
export type ObjectiveUserAttrRef = {
|
||||
type: "user_attr"
|
||||
key: string
|
||||
}
|
||||
|
||||
export type ObjectiveFormWidget =
|
||||
| ObjectiveChoiceWidget
|
||||
| ObjectiveSliderWidget
|
||||
| ObjectiveTextInputWidget
|
||||
| ObjectiveUserAttrRef
|
||||
|
||||
export type UserAttrFormWidget =
|
||||
| ObjectiveChoiceWidget
|
||||
| ObjectiveSliderWidget
|
||||
| ObjectiveTextInputWidget
|
||||
|
||||
export type FormWidgets =
|
||||
| {
|
||||
output_type: "objective"
|
||||
widgets: ObjectiveFormWidget[]
|
||||
}
|
||||
| {
|
||||
output_type: "user_attr"
|
||||
widgets: UserAttrFormWidget[]
|
||||
}
|
||||
|
||||
export type PlotlyGraphObject = {
|
||||
id: string
|
||||
graph_object: string
|
||||
}
|
||||
|
||||
export type FeedbackComponentNote = {
|
||||
output_type: "note"
|
||||
}
|
||||
|
||||
export type FeedbackComponentArtifact = {
|
||||
output_type: "artifact"
|
||||
artifact_key: string
|
||||
}
|
||||
|
||||
export type FeedbackComponentType =
|
||||
| FeedbackComponentArtifact
|
||||
| FeedbackComponentNote
|
||||
|
||||
export type StudyDetail = {
|
||||
id: number
|
||||
name: string
|
||||
directions: Optuna.StudyDirection[]
|
||||
user_attrs: Optuna.Attribute[]
|
||||
datetime_start: Date
|
||||
best_trials: Trial[]
|
||||
trials: Trial[]
|
||||
intersection_search_space: SearchSpaceItem[]
|
||||
union_search_space: SearchSpaceItem[]
|
||||
union_user_attrs: Optuna.AttributeSpec[]
|
||||
has_intermediate_values: boolean
|
||||
note: Note
|
||||
is_preferential: boolean
|
||||
objective_names?: string[]
|
||||
form_widgets?: FormWidgets
|
||||
feedback_component_type: FeedbackComponentType
|
||||
preferences?: [number, number][]
|
||||
preference_history?: PreferenceHistory[]
|
||||
plotly_graph_objects: PlotlyGraphObject[]
|
||||
artifacts: Artifact[]
|
||||
skipped_trial_numbers: number[]
|
||||
}
|
||||
|
||||
export type StudyDetails = {
|
||||
[study_id: string]: StudyDetail
|
||||
}
|
||||
|
||||
export type PreferenceHistory = {
|
||||
id: string
|
||||
candidates: number[]
|
||||
clicked: number
|
||||
feedback_mode: PreferenceFeedbackMode
|
||||
timestamp: Date
|
||||
preferences: [number, number][]
|
||||
is_removed: boolean
|
||||
}
|
||||
|
||||
export type PlotlyColorThemeDark = "default"
|
||||
export type PlotlyColorThemeLight =
|
||||
| "default"
|
||||
| "seaborn"
|
||||
| "presentation"
|
||||
| "ggplot2"
|
||||
|
||||
export type PlotlyColorTheme = {
|
||||
dark: PlotlyColorThemeDark
|
||||
light: PlotlyColorThemeLight
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
"module": "esnext",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es5",
|
||||
"target": "es6",
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"strict": true
|
||||
|
||||
Generated
+3
-3
@@ -7170,9 +7170,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.734",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.734.tgz",
|
||||
"integrity": "sha512-pYfGUc+ll8AOzLbLC0lfgwkvCZIV+sKGuFFsSNuF3K3ujrmem8jIjg/t6DNq0J7biTSS1hCt/Hts0nmA3ZyprQ==",
|
||||
"version": "1.4.735",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.735.tgz",
|
||||
"integrity": "sha512-pkYpvwg8VyOTQAeBqZ7jsmpCjko1Qc6We1ZtZCjRyYbT5v4AIUKDy5cQTRotQlSSZmMr8jqpEt6JtOj5k7lR7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
|
||||
@@ -14,7 +14,7 @@ export type IntDistribution = {
|
||||
type: "IntDistribution"
|
||||
low: number
|
||||
high: number
|
||||
step: number | null
|
||||
step: number
|
||||
log: boolean
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user