From f7e82d1f5a48f8068496a0b1c47889a287dd7c0a Mon Sep 17 00:00:00 2001 From: Evan Lanham Date: Mon, 14 Mar 2022 16:17:39 -0600 Subject: [PATCH] re-render on pdb update --- .../testdata.1643440069.couch | Bin 725194 -> 733386 bytes webserver/src/DbContext.jsx | 48 ++--- .../src/Pages/DashboardPage/DashboardPage.jsx | 61 ++++--- webserver/src/ProcessedDataBucket.jsx | 164 +++++++++--------- webserver/src/ProcessedDataBucketContext.jsx | 16 +- 5 files changed, 152 insertions(+), 137 deletions(-) diff --git a/couchdb/data/shards/00000000-7fffffff/testdata.1643440069.couch b/couchdb/data/shards/00000000-7fffffff/testdata.1643440069.couch index 8157b6280958bdc2caa378c7cb7c049dba2c4d57..bcf30326e21250e2ec9b3059560b113777eefb72 100644 GIT binary patch delta 891 zcmb8tTSyd97zgk(XJ&Ngj7vMF8)2zyT5jyv?##HlfzoQZYh|^0sf7q;cU_k$%}pyU zx)Af!LsUXv1Vt89Z)F#HDYXj{7Nu^NrwVJehd?mG2cyeu5fu2+%Ynl=-#PI6|A%`W z!{d%4I;CTs))}4E)AV%Rq;opC#SdE;gs=rh2h)mRW{_N`BG5a{TA7L%R$<^id9qDi z?Q;iPOS;>)?62*rRyTNpzTGw6V*)-Qhn%H~Q*IWcrB0Wqcoa$WsIps(l*-Pq+wD=@ zvKlLj8dn)Lr)e)f-i&5WQW+`=7B(RD+F%RR&#|niOlwUh~*wu zI-q}?Ep{(2Nn&H)usMktS(+6vYB?%klM>iimBd-~dm7{IfyoKfmO6ILBoNc!eU(7a z)sQp~L-qRzbFf-)OQjsqvf>uTO0?W1hTLIA^te?;R$P)=9*w|y8?nui&HTT!VKj~VSWMt+ zUz#J`Jb?1*gm%c!Bv!s6RW&NsW)upF$GO6lMrAG<)MaAJX8~J+Ti4Z9JrMApG_O_) z`1l0+E?}?leHKm4BI9X&!+SFtjtiaA^w?Lws=lqA&UMN_#M}m|CRcMe4zgP eo9Eqk?!H*S9_{Yx$o`F7(3?VDL}1qidizg6qZ+jU delta 31 mcmX^0Q0LS_orV_17N!>F7M2#)7Pc1l7LFFq7OpMarvw1RL<;8s diff --git a/webserver/src/DbContext.jsx b/webserver/src/DbContext.jsx index c351159..0b912b2 100644 --- a/webserver/src/DbContext.jsx +++ b/webserver/src/DbContext.jsx @@ -1,6 +1,7 @@ import PouchDB from "pouchdb"; -import React, { useContext, useState } from "react"; -import { ProcessedDataBucketContext } from "./ProcessedDataBucketContext"; +import React, { useContext, useEffect, useState } from "react"; +import { ProcessedDataBucketContext, useProcessedDataBucket } from "./ProcessedDataBucketContext"; +import { getProcessedDataBucket, updateProcessedDataBucket } from "./ProcessedDataBucket"; const LocalDbContext = React.createContext(); const RemoteDbContext = React.createContext(); @@ -14,7 +15,9 @@ export function useRemoteDb() { } export function DbProvider({ children }) { - const pdb = React.useContext(ProcessedDataBucketContext); + // const pdbCtx = useProcessedDataBucket(); + const { processedDataBucket, setProcessedDataBucket } = useContext(ProcessedDataBucketContext); + // console.log(pdb); const [localdb, setLocaldb] = useState(new PouchDB("testdata")); //used in development server const [remotedb, setRemotedb] = useState( @@ -27,27 +30,28 @@ export function DbProvider({ children }) { }) ); - pdb.updateData(localdb); - localdb - .sync(remotedb, { - live: true, - retry: true, - }) - .on("change", function (change) { - console.log('DB CHANGED'); - pdb.updateData(localdb); - }) - .on("paused", function (info) { }) - .on("active", function (info) { }) - .on("error", function (err) { - console.error(err); - }); + useEffect(() => { + console.log("TEST"); + updateProcessedDataBucket(localdb, setProcessedDataBucket); + localdb + .sync(remotedb, { + live: true, + retry: true, + }) + .on("change", function (change) { + console.log("DB CHANGED"); + updateProcessedDataBucket(localdb, setProcessedDataBucket); + }) + .on("paused", function (info) {}) + .on("active", function (info) {}) + .on("error", function (err) { + console.error(err); + }); + }, [localdb, setProcessedDataBucket]); return ( - - - {children} - + + {children} ); } diff --git a/webserver/src/Pages/DashboardPage/DashboardPage.jsx b/webserver/src/Pages/DashboardPage/DashboardPage.jsx index 6f4c55c..839eb6d 100644 --- a/webserver/src/Pages/DashboardPage/DashboardPage.jsx +++ b/webserver/src/Pages/DashboardPage/DashboardPage.jsx @@ -1,35 +1,50 @@ import React from "react"; import { useLocalDb } from "../../DbContext"; -import { useProcessedDataBucket } from "../../ProcessedDataBucketContext"; +import { ProcessedDataBucketContext, useProcessedDataBucket } from "../../ProcessedDataBucketContext"; import Chart from "react-apexcharts"; import { DataGrid } from "@mui/x-data-grid"; import { Box } from "@mui/material"; const DashboardPage = () => { - //https://react-charts.js.org/examples/column - const pdb = useProcessedDataBucket(); - const makePieChartData = (pdb, team_num) => { - // console.log(team_num); - // console.log(pdb.teamData); - return { - labels: ["None", "Low", "Mid", "High", "Transversal"], - datasets: [ - { - label: "Climbs", - data: pdb.teamData[4388].climb_counts, - backgroundColor: ["rgba(230,20,20)", "rgba(230,150,20)", "rgba(160,220,20)", "rgba(20,230,70)", "rgba(20,200,180)"], - }, - ], - }; - }; - console.log(pdb); + // + { + /* {(pdbCtx) => { */ + } + // const pdb = useProcessedDataBucket().processedDataBucket; + // const makePieChartData = (pdb, team_num) => { + // // console.log(team_num); + // // console.log(pdb.teamData); + // return { + // labels: ["None", "Low", "Mid", "High", "Transversal"], + // datasets: [ + // { + // label: "Climbs", + // data: pdb.teamData[4388].climb_counts, + // backgroundColor: ["rgba(230,20,20)", "rgba(230,150,20)", "rgba(160,220,20)", "rgba(20,230,70)", "rgba(20,200,180)"], + // }, + // ], + // }; + // }; + let { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket(); + console.log(processedDataBucket); + if (processedDataBucket == null) { + return
; + } + // 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 - let team_data_array = Object.values(pdb.teamData); + 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) => { + // 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), @@ -37,7 +52,8 @@ const DashboardPage = () => { 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 ( @@ -60,6 +76,7 @@ const DashboardPage = () => { // { field: "matched_played", headerName: "Matches", width: 100 }, ]} checkboxSelection + pageSize={15} rowsPerPageOptions={[15]} /> @@ -77,6 +94,8 @@ const DashboardPage = () => { /> */}
); + //}} + //
}; export default DashboardPage; diff --git a/webserver/src/ProcessedDataBucket.jsx b/webserver/src/ProcessedDataBucket.jsx index 2f92ecc..ffa4335 100644 --- a/webserver/src/ProcessedDataBucket.jsx +++ b/webserver/src/ProcessedDataBucket.jsx @@ -1,92 +1,88 @@ -export class ProcessedDataBucket { - constructor() { - this.teamData = {}; - this.matchData = {}; - this.updateData = (db) => { - db.allDocs({ - include_docs: true, - }) - .then((result) => { - //reset data - this.teamData = {}; - this.matchData = {}; +export function updateProcessedDataBucket(db, setProcessedDataBucket) { + return db + .allDocs({ + include_docs: true, + }) + .then((result) => { + //reset data + let teamData = {}; + let matchData = {}; - // console.log(result); - result.rows.forEach((dbentry) => { - let doc = dbentry.doc; - // console.log(doc); + // console.log(result); + result.rows.forEach((dbentry) => { + let doc = dbentry.doc; + // console.log(doc); - //if there's no processed data on a team yet, create a default data entry - if (typeof this.teamData[doc.team_number] === "undefined") { - this.teamData[doc.team_number] = { - team_number: doc.team_number, - matched_played: 0, - data_sets: { - upper_hub_auto: [], - lower_hub_auto: [], - upper_hub_teleop: [], - lower_hub_teleop: [], - auto_points: [], - teleop_hub_points: [], - climb_points: [], - total_match_points: [], - }, - climb_counts: [0, 0, 0, 0, 0], - average_auto_points: 0, - average_teleop_hub_points: 0, - average_climb_points: 0, - average_total_match_points: 0, - num_disables: 0, - num_flips: 0, - fouls: 0, - fouls_tech: 0, - red_cards: 0, - yellow_cards: 0, - }; - } + //if there's no processed data on a team yet, create a default data entry + if (typeof teamData[doc.team_number] === "undefined") { + teamData[doc.team_number] = { + team_number: doc.team_number, + matched_played: 0, + data_sets: { + upper_hub_auto: [], + lower_hub_auto: [], + upper_hub_teleop: [], + lower_hub_teleop: [], + auto_points: [], + teleop_hub_points: [], + climb_points: [], + total_match_points: [], + }, + climb_counts: [0, 0, 0, 0, 0], + average_auto_points: 0, + average_teleop_hub_points: 0, + average_climb_points: 0, + average_total_match_points: 0, + num_disables: 0, + num_flips: 0, + fouls: 0, + fouls_tech: 0, + red_cards: 0, + yellow_cards: 0, + }; + } - //add this game's data to the respective team data: - let thisTeamData = this.teamData[doc.team_number]; - thisTeamData.matched_played++; + //add this game's data to the respective team data: + let thisTeamData = teamData[doc.team_number]; + thisTeamData.matched_played++; - let auto_points = (parseInt(doc.taxi_auto) ? 2 : 0) + parseInt(doc.upper_hub_auto) * 4 + parseInt(doc.lower_hub_auto) * 2; - let teleop_hub_points = parseInt(doc.upper_hub_teleop) * 2 + parseInt(doc.lower_hub_teleop) * 1; - let climb_points = (parseInt(doc.climb_level) == 0 ? 4 : 0) + (parseInt(doc.climb_level) == 1 ? 6 : 0) + (parseInt(doc.climb_level) == 2 ? 10 : 0) + (parseInt(doc.climb_level) == 3 ? 15 : 0); - let total_match_points = auto_points + teleop_hub_points + climb_points; - //data sets - thisTeamData.data_sets.upper_hub_auto.push(parseInt(doc.upper_hub_auto)); - thisTeamData.data_sets.lower_hub_auto.push(parseInt(doc.lower_hub_auto)); - thisTeamData.data_sets.upper_hub_teleop.push(parseInt(doc.upper_hub_teleop)); - thisTeamData.data_sets.lower_hub_teleop.push(parseInt(doc.lower_hub_teleop)); - thisTeamData.data_sets.auto_points.push(auto_points); - thisTeamData.data_sets.teleop_hub_points.push(teleop_hub_points); - thisTeamData.data_sets.climb_points.push(climb_points); - thisTeamData.data_sets.total_match_points.push(total_match_points); + let auto_points = (parseInt(doc.taxi_auto) ? 2 : 0) + parseInt(doc.upper_hub_auto) * 4 + parseInt(doc.lower_hub_auto) * 2; + let teleop_hub_points = parseInt(doc.upper_hub_teleop) * 2 + parseInt(doc.lower_hub_teleop) * 1; + let climb_points = (parseInt(doc.climb_level) == 0 ? 4 : 0) + (parseInt(doc.climb_level) == 1 ? 6 : 0) + (parseInt(doc.climb_level) == 2 ? 10 : 0) + (parseInt(doc.climb_level) == 3 ? 15 : 0); + let total_match_points = auto_points + teleop_hub_points + climb_points; + //data sets + thisTeamData.data_sets.upper_hub_auto.push(parseInt(doc.upper_hub_auto)); + thisTeamData.data_sets.lower_hub_auto.push(parseInt(doc.lower_hub_auto)); + thisTeamData.data_sets.upper_hub_teleop.push(parseInt(doc.upper_hub_teleop)); + thisTeamData.data_sets.lower_hub_teleop.push(parseInt(doc.lower_hub_teleop)); + thisTeamData.data_sets.auto_points.push(auto_points); + thisTeamData.data_sets.teleop_hub_points.push(teleop_hub_points); + thisTeamData.data_sets.climb_points.push(climb_points); + thisTeamData.data_sets.total_match_points.push(total_match_points); - //climb data - thisTeamData.climb_counts[parseInt(doc.climb_level)]++; + //climb data + thisTeamData.climb_counts[parseInt(doc.climb_level)]++; - //misc data - thisTeamData.num_disables += doc.disabled ? 1 : 0; - thisTeamData.num_flips += doc.flipped ? 1 : 0; - thisTeamData.fouls += parseInt(doc.fouls); - thisTeamData.fouls_tech += parseInt(doc.fouls_tech); - thisTeamData.red_cards += parseInt(doc.red_cards); - thisTeamData.yellow_cards += parseInt(doc.yellow_cards); + //misc data + thisTeamData.num_disables += doc.disabled ? 1 : 0; + thisTeamData.num_flips += doc.flipped ? 1 : 0; + thisTeamData.fouls += parseInt(doc.fouls); + thisTeamData.fouls_tech += parseInt(doc.fouls_tech); + thisTeamData.red_cards += parseInt(doc.red_cards); + thisTeamData.yellow_cards += parseInt(doc.yellow_cards); - //sum of all points in the match points data set for this team - //function for getting the sum of an array, use in reduce function of array - const sum = (accum, current) => accum + current; - thisTeamData.average_auto_points = thisTeamData.data_sets.auto_points.reduce(sum, 0) / thisTeamData.matched_played; - thisTeamData.average_teleop_hub_points = thisTeamData.data_sets.teleop_hub_points.reduce(sum, 0) / thisTeamData.matched_played; - thisTeamData.average_climb_points = thisTeamData.data_sets.climb_points.reduce(sum, 0) / thisTeamData.matched_played; - thisTeamData.average_total_match_points = thisTeamData.data_sets.total_match_points.reduce(sum, 0) / thisTeamData.matched_played; - }); - }) - .catch((err) => { - console.log("Error while processing data!"); - console.error(err); - }); - }; - } + //sum of all points in the match points data set for this team + //function for getting the sum of an array, use in reduce function of array + const sum = (accum, current) => accum + current; + thisTeamData.average_auto_points = thisTeamData.data_sets.auto_points.reduce(sum, 0) / thisTeamData.matched_played; + thisTeamData.average_teleop_hub_points = thisTeamData.data_sets.teleop_hub_points.reduce(sum, 0) / thisTeamData.matched_played; + thisTeamData.average_climb_points = thisTeamData.data_sets.climb_points.reduce(sum, 0) / thisTeamData.matched_played; + thisTeamData.average_total_match_points = thisTeamData.data_sets.total_match_points.reduce(sum, 0) / thisTeamData.matched_played; + }); + setProcessedDataBucket({ teamData: teamData, matchData: matchData }); + }) + .catch((err) => { + console.log("Error while processing data!"); + console.error(err); + }); } diff --git a/webserver/src/ProcessedDataBucketContext.jsx b/webserver/src/ProcessedDataBucketContext.jsx index 8fcc327..27cd43c 100644 --- a/webserver/src/ProcessedDataBucketContext.jsx +++ b/webserver/src/ProcessedDataBucketContext.jsx @@ -1,17 +1,13 @@ import React, { useContext, useState } from "react"; -import { ProcessedDataBucket } from "./ProcessedDataBucket.jsx" +import { ProcessedDataBucket } from "./ProcessedDataBucket.jsx"; export const ProcessedDataBucketContext = React.createContext(); export function useProcessedDataBucket() { - return useContext(ProcessedDataBucketContext); + return useContext(ProcessedDataBucketContext); } export function ProcessedDataBucketProvider({ children }) { - //create the processed data bucket object - const [processedDataBucket, setProcessedDataBucket] = useState(new ProcessedDataBucket()); - return ( - - {children} - - ); -}; \ No newline at end of file + //create the processed data bucket object + const [processedDataBucket, setProcessedDataBucket] = useState(null); + return {children}; +}