mirror of
https://github.com/Team4388/ScoutingApp2022.git
synced 2026-06-09 08:48:05 -06:00
we ball
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
import React from "react";
|
||||
import ComparisonPanel from "./ComparisonPanel";
|
||||
|
||||
const AnalyticsPanel = (props) => {
|
||||
if (props.selectedTeams.length > 0) return <ComparisonPanel selectedTeams={props.selectedTeams} />;
|
||||
return <div />;
|
||||
};
|
||||
|
||||
export default AnalyticsPanel;
|
||||
@@ -0,0 +1,67 @@
|
||||
import React from "react";
|
||||
import { ProcessedDataBucketContext, useProcessedDataBucket } from "../../ProcessedDataBucketContext";
|
||||
import Chart from "react-apexcharts";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
const ComparativeBoxPlot = (props) => {
|
||||
let { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket();
|
||||
const getPercentile = (sorted_set, percentile) => {
|
||||
let idx = percentile * sorted_set.length;
|
||||
if (Math.floor(idx) == idx) return sorted_set[idx - 1] / 2 + sorted_set[idx] / 2;
|
||||
else return sorted_set[Math.floor(idx)];
|
||||
};
|
||||
const getFiveNumberSummary = (set) => {
|
||||
set.sort();
|
||||
return [set[0], getPercentile(set, 0.25), getPercentile(set, 0.5), getPercentile(set, 0.75), set[set.length - 1]];
|
||||
};
|
||||
const generateBoxPlotData = (pdb, setName, selectedTeams) => {
|
||||
let data = [];
|
||||
for (const teamNumber of selectedTeams) {
|
||||
//console.log(pdb.teamData[teamNumber].data_sets[setName]);
|
||||
data.push({
|
||||
x: teamNumber,
|
||||
y: getFiveNumberSummary(pdb.teamData[teamNumber].data_sets[setName]),
|
||||
});
|
||||
}
|
||||
return [
|
||||
{
|
||||
type: "boxPlot",
|
||||
data: data,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ width: "350px", height: "220px" }}>
|
||||
<Chart
|
||||
type="boxPlot"
|
||||
options={{
|
||||
chart: {
|
||||
type: "boxPlot",
|
||||
width: 350,
|
||||
},
|
||||
theme: {
|
||||
mode: "dark",
|
||||
},
|
||||
title: {
|
||||
text: props.title,
|
||||
},
|
||||
}}
|
||||
series={generateBoxPlotData(processedDataBucket, props.setName, props.selectedTeams)}
|
||||
/>
|
||||
</Box>
|
||||
/* <Chart
|
||||
options={{
|
||||
chart: {
|
||||
width: 384,
|
||||
type: "pie",
|
||||
},
|
||||
labels: ["None", "Low", "Mid", "High", "Transversal"],
|
||||
}}
|
||||
series={processedDataBucket.teamData[4388].climb_counts}
|
||||
type="pie"
|
||||
width={380}
|
||||
/> */
|
||||
);
|
||||
};
|
||||
export default ComparativeBoxPlot;
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from "react";
|
||||
import { ProcessedDataBucketContext, useProcessedDataBucket } from "../../ProcessedDataBucketContext";
|
||||
import Chart from "react-apexcharts";
|
||||
import { Box } from "@mui/material";
|
||||
import ComparativeBoxPlot from "./ComparativeBoxPlot";
|
||||
|
||||
const ComparisonPanel = (props) => {
|
||||
let { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket();
|
||||
if (processedDataBucket == null) return <div />;
|
||||
|
||||
//gets the given percentile of a sorted set
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: "400px",
|
||||
m: 1,
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
p: 1,
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<ComparativeBoxPlot setName="total_match_points" title="Total Match Points" selectedTeams={props.selectedTeams} />
|
||||
<ComparativeBoxPlot setName="auto_points" title="Auto Points" selectedTeams={props.selectedTeams} />
|
||||
<ComparativeBoxPlot setName="teleop_hub_points" title="Teleop Hub Points" selectedTeams={props.selectedTeams} />
|
||||
<ComparativeBoxPlot setName="climb_points" title="Climb Points" selectedTeams={props.selectedTeams} />
|
||||
<ComparativeBoxPlot setName="upper_hub_auto" title="Upper Hub Auto" selectedTeams={props.selectedTeams} />
|
||||
<ComparativeBoxPlot setName="lower_hub_auto" title="Lower Hub Auto" selectedTeams={props.selectedTeams} />
|
||||
<ComparativeBoxPlot setName="upper_hub_teleop" title="Upper Hub Teleop" selectedTeams={props.selectedTeams} />
|
||||
<ComparativeBoxPlot setName="lower_hub_teleop" title="Lower Hub Teleop" selectedTeams={props.selectedTeams} />
|
||||
{/* <Box sx={{ width: "300px", height: "200px" }}>
|
||||
<Chart
|
||||
type="boxPlot"
|
||||
options={{
|
||||
chart: {
|
||||
type: "boxPlot",
|
||||
width: 350,
|
||||
},
|
||||
theme: {
|
||||
mode: "dark",
|
||||
},
|
||||
}}
|
||||
series={generateBoxPlotData(processedDataBucket, "upper_hub_auto", props.selectedTeams)}
|
||||
/>
|
||||
</Box> */}
|
||||
{/* <Chart
|
||||
options={{
|
||||
chart: {
|
||||
width: 384,
|
||||
type: "pie",
|
||||
},
|
||||
labels: ["None", "Low", "Mid", "High", "Transversal"],
|
||||
}}
|
||||
series={processedDataBucket.teamData[4388].climb_counts}
|
||||
type="pie"
|
||||
width={380}
|
||||
/> */}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ComparisonPanel;
|
||||
@@ -1,9 +1,15 @@
|
||||
import React from "react";
|
||||
import React, { useState, useCallback, useRef } from "react";
|
||||
import { useLocalDb } from "../../DbContext";
|
||||
import { ProcessedDataBucketContext, useProcessedDataBucket } from "../../ProcessedDataBucketContext";
|
||||
import Chart from "react-apexcharts";
|
||||
import { DataGrid } from "@mui/x-data-grid";
|
||||
import { Box } from "@mui/material";
|
||||
import AnalyticsPanel from "./AnalyticsPanel";
|
||||
|
||||
//https://ag-grid.com/react-data-grid/
|
||||
import { AgGridReact } from "ag-grid-react";
|
||||
|
||||
import "ag-grid-community/dist/styles/ag-grid.css";
|
||||
import "ag-grid-community/dist/styles/ag-theme-alpine-dark.css";
|
||||
|
||||
const DashboardPage = () => {
|
||||
// <ProcessedDataBucketContext.Consumer>
|
||||
@@ -26,72 +32,90 @@ const DashboardPage = () => {
|
||||
// };
|
||||
// };
|
||||
let { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket();
|
||||
console.log(processedDataBucket);
|
||||
if (processedDataBucket == null) {
|
||||
return <div />;
|
||||
|
||||
let rowData = [];
|
||||
if (processedDataBucket != null) {
|
||||
//turns the values of the key value pairs in the list into an array
|
||||
let team_data_array = Object.values(processedDataBucket.teamData);
|
||||
// let team_data_array = Array.from(processedDataBucket.teamData);
|
||||
const roundPlaces = (n, d) => Math.round(n * Math.pow(10, d)) / Math.pow(10, d);
|
||||
// team_data_array.forEach((value, index, array) => {
|
||||
for (const property in processedDataBucket.teamData) {
|
||||
let value = processedDataBucket.teamData[property];
|
||||
rowData.push({
|
||||
id: value.team_number,
|
||||
average_auto_points: roundPlaces(value.average_auto_points, 2),
|
||||
average_teleop_hub_points: roundPlaces(value.average_teleop_hub_points, 2),
|
||||
average_climb_points: roundPlaces(value.average_climb_points, 2),
|
||||
average_total_match_points: roundPlaces(value.average_total_match_points, 2),
|
||||
matches_played: value.matches_played,
|
||||
num_disables: value.num_disables,
|
||||
num_flips: value.num_flips,
|
||||
fouls: value.fouls,
|
||||
fouls_tech: value.fouls_tech,
|
||||
red_cards: value.red_cards,
|
||||
yellow_cards: value.yellow_cards,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const [columnDefs] = useState([
|
||||
{ field: "id", headerName: "Team", width: 100, checkboxSelection: true, pinned: "left", sortable: true },
|
||||
{ field: "average_total_match_points", headerName: "Avg Total Pts", width: 120, sortable: true },
|
||||
{ field: "average_auto_points", headerName: "Avg Auto Pts", width: 120, sortable: true },
|
||||
{ field: "average_teleop_hub_points", headerName: "Avg Teleop Hub Pts", width: 160, sortable: true },
|
||||
{ field: "average_climb_points", headerName: "Avg Climb Pts", width: 120, sortable: true },
|
||||
{ field: "yellow_cards", headerName: "Yellow Cards", width: 120, sortable: true },
|
||||
{ field: "red_cards", headerName: "Red Cards", width: 100, sortable: true },
|
||||
{ field: "fouls", headerName: "Fouls", width: 70, sortable: true },
|
||||
{ field: "fouls_tech", headerName: "Tech Fouls", width: 100, sortable: true },
|
||||
{ field: "num_disables", headerName: "Disables", width: 100, sortable: true },
|
||||
{ field: "num_flips", headerName: "Flips", width: 80, sortable: true },
|
||||
{ field: "matches_played", headerName: "Matches", width: 100, sortable: true },
|
||||
{ field: "", headerName: "", width: 150, sortable: true },
|
||||
]);
|
||||
|
||||
const [selectedTeams, setSelectedTeams] = useState([]);
|
||||
|
||||
const gridRef = useRef();
|
||||
|
||||
const onSelectionChanged = useCallback(() => {
|
||||
let selectedRows = gridRef.current.api.getSelectedRows();
|
||||
// var selectedRowsString = "";
|
||||
// var maxToShow = 5;
|
||||
let selectedTeams = [];
|
||||
selectedRows.forEach(function (selectedRow, index) {
|
||||
selectedTeams.push(selectedRow.id);
|
||||
});
|
||||
// if (selectedRows.length > maxToShow) {
|
||||
// var othersCount = selectedRows.length - maxToShow;
|
||||
// selectedRowsString += " and " + othersCount + " other" + (othersCount !== 1 ? "s" : "");
|
||||
// }
|
||||
// document.querySelector("#selectedRows").innerHTML = selectedRowsString;
|
||||
setSelectedTeams(selectedTeams);
|
||||
}, [selectedTeams]);
|
||||
|
||||
// const { processedDataBucket, setProcessedDataBucket } = pdbCtx;
|
||||
// console.log(pdbCtx);
|
||||
|
||||
//format data for the data grid
|
||||
let grid_data = [];
|
||||
//turns the values of the key value pairs in the list into an array
|
||||
console.log(processedDataBucket.teamData);
|
||||
let team_data_array = Object.values(processedDataBucket.teamData);
|
||||
// let team_data_array = Array.from(processedDataBucket.teamData);
|
||||
const roundPlaces = (n, d) => Math.round(n * Math.pow(10, d)) / Math.pow(10, d);
|
||||
// team_data_array.forEach((value, index, array) => {
|
||||
for (const property in processedDataBucket.teamData) {
|
||||
console.log(property);
|
||||
let value = processedDataBucket.teamData[property];
|
||||
console.log(value);
|
||||
grid_data.push({
|
||||
id: value.team_number,
|
||||
average_auto_points: roundPlaces(value.average_auto_points, 2),
|
||||
average_teleop_hub_points: roundPlaces(value.average_teleop_hub_points, 2),
|
||||
average_climb_points: roundPlaces(value.average_climb_points, 2),
|
||||
average_total_match_points: roundPlaces(value.average_total_match_points, 2),
|
||||
});
|
||||
}
|
||||
// });
|
||||
console.log(grid_data);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* <Pie data={makePieChartData(pdb, 4388)} /> */}
|
||||
<Box
|
||||
sx={{
|
||||
height: "600px",
|
||||
height: "400px",
|
||||
m: 2,
|
||||
}}
|
||||
>
|
||||
<DataGrid
|
||||
rows={grid_data}
|
||||
columns={[
|
||||
{ field: "id", headerName: "Team", width: 100 },
|
||||
{ field: "average_total_match_points", headerName: "Avg Total Pts", width: 150 },
|
||||
{ field: "average_auto_points", headerName: "Avg Auto Pts", width: 150 },
|
||||
{ field: "average_teleop_hub_points", headerName: "Avg Teleop Hub Pts", width: 190 },
|
||||
{ field: "average_climb_points", headerName: "Avg Climb Pts", width: 150 },
|
||||
// { field: "matched_played", headerName: "Matches", width: 100 },
|
||||
]}
|
||||
checkboxSelection
|
||||
pageSize={15}
|
||||
rowsPerPageOptions={[15]}
|
||||
/>
|
||||
{/* <h2>{JSON.stringify(selectedTeams)}</h2> */}
|
||||
<div className="ag-theme-alpine-dark" style={{ height: 400, width: "100%" }}>
|
||||
<AgGridReact ref={gridRef} rowData={rowData} columnDefs={columnDefs} rowSelection={"multiple"} rowMultiSelectWithClick={true} onSelectionChanged={onSelectionChanged}></AgGridReact>
|
||||
</div>
|
||||
</Box>
|
||||
{/* <Chart
|
||||
options={{
|
||||
chart: {
|
||||
width: 384,
|
||||
type: "pie",
|
||||
},
|
||||
labels: ["None", "Low", "Mid", "High", "Transversal"],
|
||||
}}
|
||||
series={pdb.teamData[4388].climb_counts}
|
||||
type="pie"
|
||||
width={380}
|
||||
/> */}
|
||||
<AnalyticsPanel selectedTeams={selectedTeams} />
|
||||
</div>
|
||||
);
|
||||
//}}
|
||||
|
||||
Reference in New Issue
Block a user