Toggle DarkMode with Button

This commit is contained in:
c-bata
2022-03-05 17:10:59 +09:00
parent de54417553
commit fa8bd05f25
12 changed files with 108 additions and 41 deletions
+1
View File
@@ -0,0 +1 @@
optuna_dashboard/static/components/PlotlyDarkMode.ts
-5
View File
@@ -61,11 +61,6 @@ INDEX_HTML = """<!DOCTYPE html>
margin: 0;
padding: 0;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
}
}
</style>
<script defer src="/static/bundle.js"></script>
</head>
+35 -16
View File
@@ -1,38 +1,57 @@
import React, { FC, useMemo } from "react"
import React, { FC, useMemo, useState, useEffect } from "react"
import { RecoilRoot } from "recoil"
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"
import { SnackbarProvider } from "notistack"
import { createTheme, useMediaQuery, ThemeProvider, Box } from "@mui/material"
import { StudyDetail } from "./StudyDetail"
import { StudyList } from "./StudyList"
import {createTheme, useMediaQuery, ThemeProvider} from "@mui/material"
export const App: FC = () => {
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)")
const [colorMode, setColorMode] = useState<"light" | "dark">("light")
useEffect(() => {
setColorMode(prefersDarkMode ? "dark" : "light")
}, [prefersDarkMode])
const theme = useMemo(
() =>
createTheme({
palette: {
mode: prefersDarkMode ? 'dark' : 'light',
mode: colorMode,
},
}),
[prefersDarkMode],
);
[colorMode]
)
const toggleColorMode = () => {
setColorMode(colorMode === "dark" ? "light" : "dark")
}
return (
<RecoilRoot>
<ThemeProvider theme={theme}>
<SnackbarProvider maxSnack={3}>
<Router>
<Switch>
<Route
<Box
sx={{
backgroundColor: colorMode === "dark" ? "#121212" : "#ffffff",
width: "100%",
minHeight: "100vh",
paddingBottom: theme.spacing(2),
}}
>
<SnackbarProvider maxSnack={3}>
<Router>
<Switch>
<Route
path={URL_PREFIX + "/studies/:studyId"}
children={<StudyDetail />}
/>
<Route path={URL_PREFIX + "/"} children={<StudyList />} />
</Switch>
</Router>
</SnackbarProvider>
children={<StudyDetail toggleColorMode={toggleColorMode} />}
/>
<Route
path={URL_PREFIX + "/"}
children={<StudyList toggleColorMode={toggleColorMode} />}
/>
</Switch>
</Router>
</SnackbarProvider>
</Box>
</ThemeProvider>
</RecoilRoot>
)
@@ -10,7 +10,7 @@ import {
SelectChangeEvent,
useTheme,
} from "@mui/material"
import {plotlyDarkTemplate} from "./PlotlyDarkMode";
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
const plotDomId = "graph-edf"
@@ -15,7 +15,7 @@ import {
SelectChangeEvent,
useTheme,
} from "@mui/material"
import {plotlyDarkTemplate} from "./PlotlyDarkMode";
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
const plotDomId = "graph-history"
@@ -61,7 +61,7 @@ export const GraphHistory: FC<{
logScale,
filterCompleteTrial,
filterPrunedTrial,
theme.palette.mode
theme.palette.mode
)
}
}, [
@@ -12,7 +12,7 @@ import {
} from "@mui/material"
import { getParamImportances } from "../apiClient"
import {plotlyDarkTemplate} from "./PlotlyDarkMode";
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
const plotDomId = "graph-hyperparameter-importances"
// To match colors used by plot_param_importances in optuna.
@@ -103,7 +103,10 @@ export const GraphHyperparameterImportances: FC<{
)
}
const plotParamImportances = (paramsImportanceData: ParamImportances, mode: string) => {
const plotParamImportances = (
paramsImportanceData: ParamImportances,
mode: string
) => {
if (document.getElementById(plotDomId) === null) {
return
}
@@ -1,7 +1,7 @@
import * as plotly from "plotly.js-dist"
import React, { FC, useEffect } from "react"
import {Grid, Typography, useTheme} from "@mui/material"
import {plotlyDarkTemplate} from "./PlotlyDarkMode";
import { Grid, Typography, useTheme } from "@mui/material"
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
const plotDomId = "graph-intermediate-values"
@@ -10,7 +10,7 @@ import {
SelectChangeEvent,
useTheme,
} from "@mui/material"
import {plotlyDarkTemplate} from "./PlotlyDarkMode";
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
const plotDomId = "graph-parallel-coordinate"
@@ -65,7 +65,11 @@ export const GraphParallelCoordinate: FC<{
)
}
const plotCoordinate = (study: StudyDetail, objectiveId: number, mode: string) => {
const plotCoordinate = (
study: StudyDetail,
objectiveId: number,
mode: string
) => {
if (document.getElementById(plotDomId) === null) {
return
}
@@ -10,7 +10,7 @@ import {
SelectChangeEvent,
useTheme,
} from "@mui/material"
import {plotlyDarkTemplate} from "./PlotlyDarkMode";
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
const plotDomId = "graph-pareto-front"
@@ -12,7 +12,7 @@ import {
SelectChangeEvent,
useTheme,
} from "@mui/material"
import {plotlyDarkTemplate} from "./PlotlyDarkMode";
import { plotlyDarkTemplate } from "./PlotlyDarkMode"
const plotDomId = "graph-slice"
@@ -39,7 +39,14 @@ export const GraphSlice: FC<{
}
useEffect(() => {
plotSlice(trials, objectiveId, selected, logXScale, logYScale, theme.palette.mode)
plotSlice(
trials,
objectiveId,
selected,
logXScale,
logYScale,
theme.palette.mode
)
}, [trials, objectiveId, selected, logXScale, logYScale, theme.palette.mode])
const handleObjectiveChange = (event: SelectChangeEvent<number>) => {
@@ -26,6 +26,8 @@ import FormControlLabel from "@mui/material/FormControlLabel"
import MuiDialogTitle from "@mui/material/DialogTitle"
import MuiDialogContent from "@mui/material/DialogContent"
import CloseIcon from "@mui/icons-material/Close"
import Brightness4Icon from "@mui/icons-material/Brightness4"
import Brightness7Icon from "@mui/icons-material/Brightness7"
import { DataGridColumn, DataGrid } from "./DataGrid"
import { GraphParallelCoordinate } from "./GraphParallelCoordinate"
@@ -51,7 +53,9 @@ export const useStudyDetailValue = (studyId: number): StudyDetail | null => {
return studyDetails[studyId] || null
}
export const StudyDetail: FC = () => {
export const StudyDetail: FC<{
toggleColorMode: () => void
}> = ({ toggleColorMode }) => {
const theme = useTheme()
const action = actionCreator()
const { studyId } = useParams<ParamTypes>()
@@ -251,6 +255,18 @@ export const StudyDetail: FC = () => {
<Toolbar>
<Typography variant="h6">{APP_BAR_TITLE}</Typography>
<Box sx={{ flexGrow: 1 }} />
<IconButton
onClick={() => {
toggleColorMode()
}}
color="inherit"
>
{theme.palette.mode === "dark" ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</IconButton>
<IconButton color="inherit" onClick={handleClickOpen}>
<Settings />
</IconButton>
@@ -1,4 +1,4 @@
import React, {FC, useEffect, useMemo} from "react"
import React, { FC, useEffect, useMemo } from "react"
import { useRecoilValue } from "recoil"
import { Link } from "react-router-dom"
import {
@@ -31,8 +31,12 @@ import { Add, AddBox, Delete, Refresh, Remove } from "@mui/icons-material"
import { actionCreator } from "../action"
import { DataGrid, DataGridColumn } from "./DataGrid"
import { studySummariesState } from "../state"
import Brightness7Icon from "@mui/icons-material/Brightness7"
import Brightness4Icon from "@mui/icons-material/Brightness4"
export const StudyList: FC = () => {
export const StudyList: FC<{
toggleColorMode: () => void
}> = ({ toggleColorMode }) => {
const theme = useTheme()
const [newStudySelectionAnchorEl, setNewStudySelectionAnchorEl] =
@@ -55,10 +59,13 @@ export const StudyList: FC = () => {
const [directions, setDirections] = React.useState<StudyDirection[]>([
"minimize",
])
const linkColor= useMemo(
() => theme.palette.mode === 'dark' ? theme.palette.primary.light : theme.palette.primary.dark,
[theme.palette.mode],
);
const linkColor = useMemo(
() =>
theme.palette.mode === "dark"
? theme.palette.primary.light
: theme.palette.primary.dark,
[theme.palette.mode]
)
const action = actionCreator()
const studies = useRecoilValue<StudySummary[]>(studySummariesState)
@@ -82,7 +89,10 @@ export const StudyList: FC = () => {
label: "Name",
sortable: true,
toCellValue: (i) => (
<Link to={`${URL_PREFIX}/studies/${studies[i].study_id}`} style={{color: linkColor}}>
<Link
to={`${URL_PREFIX}/studies/${studies[i].study_id}`}
style={{ color: linkColor }}
>
{studies[i].study_name}
</Link>
),
@@ -216,6 +226,18 @@ export const StudyList: FC = () => {
<Toolbar>
<Typography variant="h6">{APP_BAR_TITLE}</Typography>
<Box sx={{ flexGrow: 1 }} />
<IconButton
onClick={() => {
toggleColorMode()
}}
color="inherit"
>
{theme.palette.mode === "dark" ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</IconButton>
<IconButton
aria-controls="menu-appbar"
aria-haspopup="true"