fetch leaderboard table data from backend; optimize table style

This commit is contained in:
Songyi Huang 2020-07-19 18:28:39 -07:00
parent 362da09294
commit d7daa1da05
2 changed files with 153 additions and 72 deletions

View File

@ -10,19 +10,6 @@ import ExpandMore from '@material-ui/icons/ExpandMore';
import {makeStyles} from "@material-ui/core/styles";
import qs from 'query-string';
const gameList = [
{game: 'leduc-holdem', dispName: 'Leduc Hold\'em'},
{game: 'doudizhu', dispName: 'Dou Dizhu'},
];
const modelList = [
{model: 'leduc-holdem-random', dispName: 'Leduc Hold\'em Random'},
{model: 'leduc-holdem-cfr', dispName: 'Leduc Hold\'em CFR'},
{model: 'leduc-holdem-rule-v1', dispName: 'Leduc Hold\'em Rule V1'},
{model: 'doudizhu-random', dispName: 'Dou Dizhu Random'},
{model: 'doudizhu-rule-v1', dispName: 'Dou Dizhu Rule V1'}
];
const drawerWidth = 250;
const useStyles = makeStyles((theme) => ({
@ -60,7 +47,7 @@ const useStyles = makeStyles((theme) => ({
active: {}
}));
function MenuBar () {
function MenuBar (props) {
const classes = useStyles();
const [open, setOpen] = React.useState({game: true, agent: true});
@ -80,7 +67,7 @@ function MenuBar () {
}
const { type, name } = qs.parse(window.location.search);
const gameMenu = gameList.map(game => {
const gameMenu = props.gameList.map(game => {
return <List component="div" disablePadding key={"game-menu-"+game.game}>
<ListItem button className={classes.nested} onClick={() => {handleGameJump(game.game)}}>
<ListItemText primary={game.dispName} className={`${classes.menuLayer2} ${(type === 'game' && name === game.game) ? classes.active : classes.inactive}`} />
@ -88,7 +75,7 @@ function MenuBar () {
</List>
});
const agentMenu = modelList.map(model => {
const agentMenu = props.modelList.map(model => {
return <List component="div" disablePadding key={"game-menu-"+model.model}>
<ListItem button className={classes.nested} onClick={() => {handleAgentJump(model.model)}}>
<ListItemText primary={model.dispName} className={`${classes.menuLayer2} ${(type === 'agent' && name === model.model) ? classes.active : classes.inactive}`} />

View File

@ -1,4 +1,5 @@
import React from 'react';
import React, {useEffect} from 'react';
import qs from 'query-string';
import MenuBar from "../components/MenuBar";
import PropTypes from 'prop-types';
@ -14,73 +15,97 @@ import Typography from '@material-ui/core/Typography';
import Paper from '@material-ui/core/Paper';
import { apiUrl } from "../utils/config";
import axios from 'axios';
import TablePagination from "@material-ui/core/TablePagination";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import withStyles from "@material-ui/core/styles/withStyles";
const gameList = [
{game: 'leduc-holdem', dispName: 'Leduc Hold\'em'},
{game: 'doudizhu', dispName: 'Dou Dizhu'},
];
const modelList = [
{model: 'leduc-holdem-random', dispName: 'Leduc Hold\'em Random'},
{model: 'leduc-holdem-cfr', dispName: 'Leduc Hold\'em CFR'},
{model: 'leduc-holdem-rule-v1', dispName: 'Leduc Hold\'em Rule V1'},
{model: 'doudizhu-random', dispName: 'Dou Dizhu Random'},
{model: 'doudizhu-rule-v1', dispName: 'Dou Dizhu Rule V1'}
];
function LeaderBoard () {
console.log(`${apiUrl}/tournament/query_game?name=doudizhu`);
axios.get(`${apiUrl}/tournament/query_game?name=doudizhu`)
const [rows, setRows] = React.useState([]);
const { type, name } = qs.parse(window.location.search);
let requestUrl = `${apiUrl}/tournament/`;
if (type === 'game') {
requestUrl += `query_game?name=${name}`
} else if (type === 'agent') {
requestUrl += `query_game?agent0=${name}`
}
console.log(requestUrl);
useEffect(() => {
async function fetchData() {
const res = await axios.get(requestUrl);
console.log('wdnmd', res);
setRows(res.data.map((resRow) => {return createData(resRow);}));
}
fetchData();
}, [requestUrl])
return (
<div>
<MenuBar />
<MenuBar gameList={gameList} modelList={modelList} />
<div style={{marginLeft: '250px'}}>
<div style={{padding: 20}}>
{EnhancedTable()}
<EnhancedTable tableRows={rows} routeInfo={{type, name}}/>
</div>
</div>
</div>
)
}
function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
function createData(resData) {
return {
id: resData.pk,
game: resData.fields.name,
agent0: resData.fields.agent0,
agent1: resData.fields.agent1,
win: resData.fields.win ? 'Win' : 'Lose',
payoff: resData.fields.payoff
};
}
const rows = [
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Donut', 452, 25.0, 51, 4.9),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Gingerbread', 356, 16.0, 49, 3.9),
createData('Honeycomb', 408, 3.2, 87, 6.5),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Jelly Bean', 375, 0.0, 94, 0.0),
createData('KitKat', 518, 26.0, 65, 7.0),
createData('Lollipop', 392, 0.2, 98, 0.0),
createData('Marshmallow', 318, 0, 81, 2.0),
createData('Nougat', 360, 19.0, 9, 37.0),
createData('Oreo1', 437, 18.0, 63, 4.0),
createData('Oreo2', 437, 18.0, 63, 4.0),
createData('Oreo3', 437, 18.0, 63, 4.0),
createData('Oreo4', 437, 18.0, 63, 4.0),
createData('Oreo5', 437, 18.0, 63, 4.0),
createData('Oreo6', 437, 18.0, 63, 4.0),
createData('Oreo7', 437, 18.0, 63, 4.0),
createData('Oreo8', 437, 18.0, 63, 4.0),
createData('Oreo9', 437, 18.0, 63, 4.0),
createData('Oreo10', 437, 18.0, 63, 4.0),
createData('Oreo11', 437, 18.0, 63, 4.0)
const headCells = [
{ id: 'id', numeric: false, disablePadding: false, label: 'ID' },
{ id: 'game', numeric: false, disablePadding: false, label: 'Game' },
{ id: 'agent0', numeric: false, disablePadding: false, label: 'Agent 0' },
{ id: 'agent1', numeric: false, disablePadding: false, label: 'Agent 1' },
{ id: 'win', numeric: false, disablePadding: false, label: 'Result' },
{ id: 'payoff', numeric: false, disablePadding: false, label: 'Payoff' }
];
const headCells = [
{ id: 'name', numeric: false, disablePadding: false, label: 'Dessert (100g serving)' },
{ id: 'calories', numeric: true, disablePadding: false, label: 'Calories' },
{ id: 'fat', numeric: true, disablePadding: false, label: 'Fat (g)' },
{ id: 'carbs', numeric: true, disablePadding: false, label: 'Carbs (g)' },
{ id: 'protein', numeric: true, disablePadding: false, label: 'Protein (g)' },
];
const StyledTableCell = withStyles((theme) => ({
head: {
backgroundColor: '#373538',
color: theme.palette.common.white,
fontWeight: 600,
fontSize: 15
}
}))(TableCell);
function EnhancedTableHead() {
return (
<TableHead>
<TableRow>
{headCells.map((headCell) => (
<TableCell
<StyledTableCell
key={headCell.id}
align={headCell.numeric ? 'right' : 'left'}
padding={headCell.disablePadding ? 'none' : 'default'}
>
{headCell.label}
</TableCell>
</StyledTableCell>
))}
</TableRow>
</TableHead>
@ -96,6 +121,7 @@ const useToolbarStyles = makeStyles((theme) => ({
root: {
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(1),
minHeight: 52,
},
highlight:
theme.palette.type === 'light'
@ -110,22 +136,49 @@ const useToolbarStyles = makeStyles((theme) => ({
title: {
flex: '1 1 100%',
},
capitalize: {
textTransform: 'capitalize'
}
}));
const EnhancedTableToolbar = () => {
const EnhancedTableToolbar = (props) => {
const { routeInfo } = props;
const classes = useToolbarStyles();
let name = '';
if (routeInfo.type === 'game') {
const foundItem = gameList.find(game => {
return game.game === routeInfo.name;
});
name = foundItem.dispName;
} else if (routeInfo.type === 'agent') {
const foundItem = modelList.find(model => {
return model.model === routeInfo.name;
});
name = foundItem.dispName;
}
return (
<Toolbar
className={classes.root}
>
<Typography className={classes.title} variant="h6" id="tableTitle" component="div">
Nutrition
</Typography>
<Breadcrumbs aria-label="breadcrumb">
<Typography color="inherit">
LeaderBoards
</Typography>
<Typography color="inherit" className={classes.capitalize}>
{routeInfo.type}
</Typography>
<Typography color="textPrimary">{name}</Typography>
</Breadcrumbs>
</Toolbar>
);
};
EnhancedTableToolbar.propTypes = {
routeInfo: PropTypes.object.isRequired
}
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
@ -135,7 +188,7 @@ const useStyles = makeStyles((theme) => ({
marginBottom: theme.spacing(2),
},
table: {
minWidth: 750,
minWidth: 900,
},
visuallyHidden: {
border: 0,
@ -150,13 +203,33 @@ const useStyles = makeStyles((theme) => ({
},
}));
function EnhancedTable() {
const EnhancedTable = (props) => {
const initRowsPerPage = 10;
const { tableRows, routeInfo } = props;
const classes = useStyles();
const [rowsPerPage, setRowsPerPage] = React.useState(initRowsPerPage);
const [page, setPage] = React.useState(0);
useEffect(() => {
setRowsPerPage(initRowsPerPage);
setPage(0);
}, [tableRows]);
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
const emptyRows = rowsPerPage - Math.min(rowsPerPage, tableRows.length - page * rowsPerPage);
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<EnhancedTableToolbar />
<EnhancedTableToolbar routeInfo={routeInfo}/>
<TableContainer>
<Table
className={classes.table}
@ -166,35 +239,56 @@ function EnhancedTable() {
>
<EnhancedTableHead
classes={classes}
rowCount={rows.length}
rowCount={tableRows.length}
/>
<TableBody>
{rows.map((row, index) => {
{tableRows
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row, index) => {
const labelId = `enhanced-table-checkbox-${index}`;
return (
<TableRow
hover
role="checkbox"
tabIndex={-1}
key={row.name}
key={row.id}
>
<TableCell component="th" id={labelId} scope="row">
{row.name}
{row.id}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
<TableCell>{row.game}</TableCell>
<TableCell>{row.agent0}</TableCell>
<TableCell>{row.agent1}</TableCell>
<TableCell>{row.win}</TableCell>
<TableCell>{row.payoff}</TableCell>
</TableRow>
);
})}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 50, 100]}
component="div"
count={tableRows.length}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
/>
</Paper>
</div>
);
}
EnhancedTable.propTypes = {
routeInfo: PropTypes.object.isRequired,
tableRows: PropTypes.array.isRequired
}
export default LeaderBoard;