From b5fd26e2d9c04f7ccf1de06c68b8a993ff86f256 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 30 Jun 2024 13:54:26 +0900 Subject: [PATCH 1/4] Use tslib DataGrid in optuna-dashboard --- .../ts/components/Artifact/TableArtifactViewer.tsx | 2 +- .../ts/components/Preferential/PreferentialAnalytics.tsx | 2 +- optuna_dashboard/ts/components/StudyHistory.tsx | 2 +- optuna_dashboard/ts/components/TrialTable.tsx | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/optuna_dashboard/ts/components/Artifact/TableArtifactViewer.tsx b/optuna_dashboard/ts/components/Artifact/TableArtifactViewer.tsx index c0338259..a36088cb 100644 --- a/optuna_dashboard/ts/components/Artifact/TableArtifactViewer.tsx +++ b/optuna_dashboard/ts/components/Artifact/TableArtifactViewer.tsx @@ -1,10 +1,10 @@ import ClearIcon from "@mui/icons-material/Clear" import { Box, Modal, useTheme } from "@mui/material" import IconButton from "@mui/material/IconButton" +import { DataGrid } from "@optuna/react" import { useSnackbar } from "notistack" import Papa from "papaparse" import React, { useState, useEffect, ReactNode } from "react" -import { DataGrid } from "../DataGrid" import { Artifact } from "ts/types/optuna" diff --git a/optuna_dashboard/ts/components/Preferential/PreferentialAnalytics.tsx b/optuna_dashboard/ts/components/Preferential/PreferentialAnalytics.tsx index 554e6ea4..90c3614c 100644 --- a/optuna_dashboard/ts/components/Preferential/PreferentialAnalytics.tsx +++ b/optuna_dashboard/ts/components/Preferential/PreferentialAnalytics.tsx @@ -7,11 +7,11 @@ import { useTheme, } from "@mui/material" import Grid2 from "@mui/material/Unstable_Grid2" +import { DataGrid } from "@optuna/react" import * as Optuna from "@optuna/types" import React, { FC } from "react" import { useStudyDetailValue, useStudySummaryValue } from "../../state" import { BestTrialsCard } from "../BestTrialsCard" -import { DataGrid } from "../DataGrid" import { Contour } from "../GraphContour" import { ColumnDef, createColumnHelper } from "@tanstack/react-table" diff --git a/optuna_dashboard/ts/components/StudyHistory.tsx b/optuna_dashboard/ts/components/StudyHistory.tsx index 6577f050..ab8a4110 100644 --- a/optuna_dashboard/ts/components/StudyHistory.tsx +++ b/optuna_dashboard/ts/components/StudyHistory.tsx @@ -9,6 +9,7 @@ import { } from "@mui/material" import FormControlLabel from "@mui/material/FormControlLabel" import Grid2 from "@mui/material/Unstable_Grid2" +import { DataGrid } from "@optuna/react" import * as Optuna from "@optuna/types" import React, { FC, useState } from "react" import { useRecoilValue } from "recoil" @@ -21,7 +22,6 @@ import { import { artifactIsAvailable } from "../state" import { StudyArtifactCards } from "./Artifact/StudyArtifactCards" import { BestTrialsCard } from "./BestTrialsCard" -import { DataGrid } from "./DataGrid" import { GraphHistory } from "./GraphHistory" import { GraphHyperparameterImportance } from "./GraphHyperparameterImportances" import { GraphIntermediateValues } from "./GraphIntermediateValues" diff --git a/optuna_dashboard/ts/components/TrialTable.tsx b/optuna_dashboard/ts/components/TrialTable.tsx index 55fdc2e0..df62cf97 100644 --- a/optuna_dashboard/ts/components/TrialTable.tsx +++ b/optuna_dashboard/ts/components/TrialTable.tsx @@ -3,9 +3,10 @@ import LinkIcon from "@mui/icons-material/Link" import { Button, IconButton, useTheme } from "@mui/material" import React, { FC } from "react" +import { DataGrid } from "@optuna/react" + import { Link } from "react-router-dom" import { StudyDetail, Trial } from "ts/types/optuna" -import { DataGrid } from "./DataGrid" import { ColumnDef, From c97536a947c137921188bec0acd070b8b8c3be0b Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 30 Jun 2024 13:56:28 +0900 Subject: [PATCH 2/4] Delete DataGrid.tsx in optuna-dashboard --- optuna_dashboard/ts/components/DataGrid.tsx | 383 -------------------- 1 file changed, 383 deletions(-) delete mode 100644 optuna_dashboard/ts/components/DataGrid.tsx diff --git a/optuna_dashboard/ts/components/DataGrid.tsx b/optuna_dashboard/ts/components/DataGrid.tsx deleted file mode 100644 index 607f580c..00000000 --- a/optuna_dashboard/ts/components/DataGrid.tsx +++ /dev/null @@ -1,383 +0,0 @@ -import CheckBoxIcon from "@mui/icons-material/CheckBox" -import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank" -import FilterListIcon from "@mui/icons-material/FilterList" -import FirstPageIcon from "@mui/icons-material/FirstPage" -import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft" -import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight" -import LastPageIcon from "@mui/icons-material/LastPage" -import { - Box, - IconButton, - Menu, - MenuItem, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TablePagination, - TableRow, - TableSortLabel, - TextField, - useTheme, -} from "@mui/material" -import ListItemIcon from "@mui/material/ListItemIcon" -import Paper from "@mui/material/Paper" -import { TablePaginationActionsProps } from "@mui/material/TablePagination/TablePaginationActions" -import { styled } from "@mui/system" -import React from "react" - -import { - ColumnDef, - ColumnFiltersState, - Header, - PaginationState, - SortingState, - flexRender, - getCoreRowModel, - getFacetedRowModel, - getFacetedUniqueValues, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from "@tanstack/react-table" - -const TableHeaderCellSpan = styled("span")({ - display: "inline-flex", -}) - -const HiddenSpan = styled("span")({ - border: 0, - clip: "rect(0 0 0 0)", - height: 1, - margin: -1, - overflow: "hidden", - padding: 0, - position: "absolute", - top: 20, - width: 1, -}) - -function FilterMenu({ - header, - filterChoices, -}: { - header: Header - filterChoices: string[] -}): React.ReactElement { - const [filterMenuAnchorEl, setFilterMenuAnchorEl] = - React.useState(null) - return ( - <> - { - setFilterMenuAnchorEl(e.currentTarget) - }} - > - - - { - setFilterMenuAnchorEl(null) - }} - > - {filterChoices.map((choice) => ( - { - const skippedValues = header.column.getFilterValue() as string[] - const isSkipped = skippedValues.includes(choice) - const newSkippedValues = isSkipped - ? skippedValues.filter((v) => v !== choice) - : skippedValues.concat(choice) - header.column.setFilterValue(newSkippedValues) - }} - > - - {header.column.getFilterValue() !== undefined ? ( - (header.column.getFilterValue() as string[]).includes( - choice - ) ? ( - - ) : ( - - ) - ) : null} - - {choice ?? "(missing value)"} - - ))} - - - ) -} - -function DataGrid({ - data, - columns, - initialRowsPerPage, -}: { - data: T[] - columns: ColumnDef[] - initialRowsPerPage?: number -}): React.ReactElement { - const [sorting, setSorting] = React.useState([]) - const [columnFilters, setColumnFilters] = React.useState( - [] - ) - const rowsPerPageOptions = [10, 50, 100, { label: "All", value: data.length }] - - const [pagination, setPagination] = React.useState({ - pageIndex: 0, - pageSize: - initialRowsPerPage && rowsPerPageOptions.includes(initialRowsPerPage) - ? initialRowsPerPage - : 50, - }) - - const table = useReactTable({ - data, - columns, - state: { - columnFilters, - sorting, - pagination, - }, - onColumnFiltersChange: setColumnFilters, - onSortingChange: setSorting, - onPaginationChange: setPagination, - getCoreRowModel: getCoreRowModel(), - getFacetedRowModel: getFacetedRowModel(), - getFacetedUniqueValues: getFacetedUniqueValues(), - getSortedRowModel: getSortedRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getFilteredRowModel: getFilteredRowModel(), - autoResetPageIndex: false, - }) - - return ( - - - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - if ( - header.column.getCanFilter() && - !header.column.getIsFiltered() - ) { - header.column.setFilterValue([]) - } - const order = header.column.getIsSorted() - const filterChoices = header.column.getCanFilter() - ? Array.from( - header.column.getFacetedUniqueValues().keys() - ).sort() - : null - return ( - - {header.isPlaceholder ? null : ( - - {header.column.getCanSort() ? ( - - {flexRender( - header.column.columnDef.header, - header.getContext() - )} - {order !== null ? ( - - {order === "desc" - ? "sorted descending" - : "sorted ascending"} - - ) : null} - - ) : ( - flexRender( - header.column.columnDef.header, - header.getContext() - ) - )} - {filterChoices !== null ? ( - - ) : null} - - )} - - ) - })} - - ))} - - - {table.getRowModel().rows.map((row) => { - return ( - - {row.getVisibleCells().map((cell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} - - ) - })} - - ) - })} - -
-
- - { - table.setPageIndex(page) - }} - onRowsPerPageChange={(e) => { - const size = e.target.value ? Number(e.target.value) : 10 - table.setPageSize(size) - }} - ActionsComponent={TablePaginationActions} - /> - {table.getPageCount() > 2 ? ( - table.setPageIndex(page)} - maxPageNumber={table.getPageCount()} - /> - ) : null} - -
- ) -} - -const TablePaginationActions = ({ - count, - page, - rowsPerPage, - onPageChange, -}: TablePaginationActionsProps) => { - const theme = useTheme() - const handleFirstPageButtonClick = ( - event: React.MouseEvent - ) => { - onPageChange(event, 0) - } - - const handleBackButtonClick = ( - event: React.MouseEvent - ) => { - onPageChange(event, page - 1) - } - - const handleNextButtonClick = ( - event: React.MouseEvent - ) => { - onPageChange(event, page + 1) - } - - const handleLastPageButtonClick = ( - event: React.MouseEvent - ) => { - onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1)) - } - - return ( - - - {theme.direction === "rtl" ? : } - - - {theme.direction === "rtl" ? ( - - ) : ( - - )} - - = Math.ceil(count / rowsPerPage) - 1} - aria-label="next page" - > - {theme.direction === "rtl" ? ( - - ) : ( - - )} - - = Math.ceil(count / rowsPerPage) - 1} - aria-label="last page" - > - {theme.direction === "rtl" ? : } - - - ) -} - -const PaginationForm1: React.FC<{ - onPageNumberSubmit: (value: number) => void - maxPageNumber: number -}> = ({ onPageNumberSubmit, maxPageNumber }) => { - // This component is separated from DataGrid to prevent `DataGrid` from re-rendering the page, - // every time any letters are input. - const [specifiedPageText, setSpecifiedPageText] = React.useState("") - - const handleSubmitPageNumber = (event: React.FormEvent) => { - event.preventDefault() - const newPageNumber = parseInt(specifiedPageText, 10) - // Page is 0-indexed in `TablePagination`. - onPageNumberSubmit(newPageNumber - 1) - setSpecifiedPageText("") // reset the input field - } - - return ( -
- { - setSpecifiedPageText(e.target.value) - }} - /> - - ) -} - -export { DataGrid } From d5392487c64096e543c20ea739115d0760a5a8be Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 30 Jun 2024 14:50:02 +0900 Subject: [PATCH 3/4] Fi package.json --- optuna_dashboard/package-lock.json | 31 +++--------------------------- optuna_dashboard/package.json | 2 +- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/optuna_dashboard/package-lock.json b/optuna_dashboard/package-lock.json index d039bfe3..a356da78 100644 --- a/optuna_dashboard/package-lock.json +++ b/optuna_dashboard/package-lock.json @@ -19,7 +19,7 @@ "@react-three/drei": "^9.96.4", "@react-three/fiber": "^8.15.15", "@tanstack/react-query": "^5.18.1", - "@tanstack/react-table": "^8.16.0", + "@tanstack/react-table": "file:../tslib/react/node_modules/@tanstack/react-table", "@tanstack/react-virtual": "^3.1.2", "@types/papaparse": "^5.3.14", "@types/three": "^0.160.0", @@ -14278,22 +14278,8 @@ } }, "node_modules/@tanstack/react-table": { - "version": "8.17.3", - "license": "MIT", - "dependencies": { - "@tanstack/table-core": "8.17.3" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } + "resolved": "../tslib/react/node_modules/@tanstack/react-table", + "link": true }, "node_modules/@tanstack/react-virtual": { "version": "3.5.1", @@ -14310,17 +14296,6 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@tanstack/table-core": { - "version": "8.17.3", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, "node_modules/@tanstack/virtual-core": { "version": "3.5.1", "license": "MIT", diff --git a/optuna_dashboard/package.json b/optuna_dashboard/package.json index 12dadc4e..2211df30 100644 --- a/optuna_dashboard/package.json +++ b/optuna_dashboard/package.json @@ -24,7 +24,7 @@ "@react-three/drei": "^9.96.4", "@react-three/fiber": "^8.15.15", "@tanstack/react-query": "^5.18.1", - "@tanstack/react-table": "^8.16.0", + "@tanstack/react-table": "file:../tslib/react/node_modules/@tanstack/react-table", "@tanstack/react-virtual": "^3.1.2", "@types/papaparse": "^5.3.14", "@types/three": "^0.160.0", From 74c1133877c6a0a4c497d6ce4cc5d369b5d785ce Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 7 Jul 2024 14:10:50 +0900 Subject: [PATCH 4/4] Fix import error of mui icons --- tslib/react/src/components/DataGrid.tsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tslib/react/src/components/DataGrid.tsx b/tslib/react/src/components/DataGrid.tsx index 4462768b..15d55bea 100644 --- a/tslib/react/src/components/DataGrid.tsx +++ b/tslib/react/src/components/DataGrid.tsx @@ -1,15 +1,19 @@ -import CheckBoxIcon from "@mui/icons-material/CheckBox" -import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank" -import FilterListIcon from "@mui/icons-material/FilterList" -import FirstPageIcon from "@mui/icons-material/FirstPage" -import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft" -import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight" -import LastPageIcon from "@mui/icons-material/LastPage" +import { + CheckBox as CheckBoxIcon, + CheckBoxOutlineBlank as CheckBoxOutlineBlankIcon, + FilterList as FilterListIcon, + FirstPage as FirstPageIcon, + KeyboardArrowLeft, + KeyboardArrowRight, + LastPage as LastPageIcon, +} from "@mui/icons-material" import { Box, IconButton, + ListItem as ListItemIcon, Menu, MenuItem, + Paper, Table, TableBody, TableCell, @@ -21,8 +25,6 @@ import { TextField, useTheme, } from "@mui/material" -import ListItemIcon from "@mui/material/ListItemIcon" -import Paper from "@mui/material/Paper" import { TablePaginationActionsProps } from "@mui/material/TablePagination/TablePaginationActions" import { styled } from "@mui/system" import React from "react"