From 09f23e730c4637f32c0831d1ad0ca253d3e1999b Mon Sep 17 00:00:00 2001 From: Samed Rouven Vossberg <57455873+SamedVossberg@users.noreply.github.com> Date: Mon, 30 Sep 2024 12:21:57 -0600 Subject: [PATCH] debugging channels, first draft decoding layout, added graphs --- gui_dev/bun.lockb | Bin 239053 -> 246999 bytes gui_dev/src/components/HeatmapGraph.jsx | 87 ++++++++++++ gui_dev/src/components/PSDGraph.jsx | 87 ++++++++++++ .../{Graph.jsx => RawDataGraph.jsx} | 2 +- gui_dev/src/components/index.js | 4 +- gui_dev/src/pages/Channels/Channels.jsx | 55 +++++--- gui_dev/src/pages/Dashboard.jsx | 20 ++- gui_dev/src/pages/Decoding.jsx | 133 ++++++++++++++++-- 8 files changed, 347 insertions(+), 41 deletions(-) create mode 100644 gui_dev/src/components/HeatmapGraph.jsx create mode 100644 gui_dev/src/components/PSDGraph.jsx rename gui_dev/src/components/{Graph.jsx => RawDataGraph.jsx} (94%) diff --git a/gui_dev/bun.lockb b/gui_dev/bun.lockb index ae7d827b00f431779b90f1d41f170aebf07b6c4f..6e17d8e8787bd61da9b5ac4ca165e8fb98b02780 100755 GIT binary patch delta 53005 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 delta 48262 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 f*Ty1 { + const [selectedChannel, setSelectedChannel] = useState('channel1'); + const heatmapData = useSocketStore((state) => state.heatmapData[selectedChannel] || { x: [], y: [], z: [] }); + const graphRef = useRef(null); + const plotlyRef = useRef(null); + + const handleChannelChange = (event) => { + setSelectedChannel(event.target.value); + }; + + useEffect(() => { + const layout = { + title: { text: 'Heatmap', font: { color: '#f4f4f4' } }, + autosize: true, + height: 400, + paper_bgcolor: '#333', + plot_bgcolor: '#333', + xaxis: { + title: { text: 'Time', font: { color: '#f4f4f4' } }, + color: '#cccccc', + }, + yaxis: { + title: { text: 'Features', font: { color: '#f4f4f4' } }, + color: '#cccccc', + }, + margin: { l: 50, r: 50, b: 50, t: 50 }, + font: { color: '#f4f4f4' }, + }; + + if (graphRef.current) { + Plotly.react( + graphRef.current, + [ + { + z: heatmapData.z, + x: heatmapData.x, + y: heatmapData.y, + type: 'heatmap', + colorscale: 'Viridis', + }, + ], + layout, + { responsive: true, displayModeBar: false } + ).then((gd) => { + plotlyRef.current = gd; + }); + } + }, [heatmapData]); + + return ( + + + + Heatmap + + + + Channel Selection + + + + +
+ + ); +}; diff --git a/gui_dev/src/components/PSDGraph.jsx b/gui_dev/src/components/PSDGraph.jsx new file mode 100644 index 00000000..7074aed5 --- /dev/null +++ b/gui_dev/src/components/PSDGraph.jsx @@ -0,0 +1,87 @@ +import { useEffect, useRef, useState } from 'react'; +import { useSocketStore } from '@/stores'; +import Plotly from 'plotly.js-basic-dist-min'; +import { + Box, + Typography, + FormControl, + InputLabel, + Select, + MenuItem, +} from '@mui/material'; + +export const PSDGraph = () => { + const [selectedChannel, setSelectedChannel] = useState('channel1'); + const psdData = useSocketStore((state) => state.psdData[selectedChannel] || { frequencies: [], powers: [] }); + const graphRef = useRef(null); + const plotlyRef = useRef(null); + + const handleChannelChange = (event) => { + setSelectedChannel(event.target.value); + }; + + useEffect(() => { + const layout = { + title: { text: 'PSD Trace', font: { color: '#f4f4f4' } }, + autosize: true, + height: 400, + paper_bgcolor: '#333', + plot_bgcolor: '#333', + xaxis: { + title: { text: 'Frequency (Hz)', font: { color: '#f4f4f4' } }, + color: '#cccccc', + }, + yaxis: { + title: { text: 'Power', font: { color: '#f4f4f4' } }, + color: '#cccccc', + }, + margin: { l: 50, r: 50, b: 50, t: 50 }, + font: { color: '#f4f4f4' }, + }; + + if (graphRef.current) { + Plotly.react( + graphRef.current, + [ + { + x: psdData.frequencies, + y: psdData.powers, + type: 'scatter', + mode: 'lines', + line: { simplify: false, color: '#1a73e8' }, + }, + ], + layout, + { responsive: true, displayModeBar: false } + ).then((gd) => { + plotlyRef.current = gd; + }); + } + }, [psdData]); + + return ( + + + + PSD Trace + + + + Channel Selection + + + + +
+ + ); +}; diff --git a/gui_dev/src/components/Graph.jsx b/gui_dev/src/components/RawDataGraph.jsx similarity index 94% rename from gui_dev/src/components/Graph.jsx rename to gui_dev/src/components/RawDataGraph.jsx index 95aec945..c6b583fb 100644 --- a/gui_dev/src/components/Graph.jsx +++ b/gui_dev/src/components/RawDataGraph.jsx @@ -2,7 +2,7 @@ import { useEffect, useRef } from "react"; import { useSocketStore } from "@/stores"; import { newPlot, react } from "plotly.js-basic-dist-min"; -export const Graph = ({ +export const RawDataGraph = ({ title = "EEG Data", xAxisTitle = "Sample", yAxisTitle = "Value", diff --git a/gui_dev/src/components/index.js b/gui_dev/src/components/index.js index b04a0b5e..d984b682 100644 --- a/gui_dev/src/components/index.js +++ b/gui_dev/src/components/index.js @@ -2,7 +2,9 @@ export { AppBar } from "./AppBar"; export { AppInfoModal } from "./AppInfoModal"; export { CollapsibleBox } from "./CollapsibleBox"; export { FileBrowser } from "./FileBrowser/FileBrowser"; -export { Graph } from "./Graph"; +export { RawDataGraph } from "./RawDataGraph"; export { Sidebar, SidebarDrawer } from "./Sidebar/Sidebar"; export { StatusBar } from "./StatusBar/StatusBar"; export { TitledBox } from "./TitledBox"; +export { HeatmapGraph } from "./HeatmapGraph"; +export { PSDGraph } from "./PSDGraph"; diff --git a/gui_dev/src/pages/Channels/Channels.jsx b/gui_dev/src/pages/Channels/Channels.jsx index 65e4be3d..873a1bd4 100644 --- a/gui_dev/src/pages/Channels/Channels.jsx +++ b/gui_dev/src/pages/Channels/Channels.jsx @@ -127,13 +127,13 @@ const ChannelsTable = () => { const updateChannel = useSessionStore((state) => state.updateChannel); const handleChange = (event, index, field) => { - updateChannel( - index, - field, - event.target.type === "checkbox" - ? event.target.checked - : event.target.value - ); + let value; + if (event.target.type === "checkbox") { + value = event.target.checked ? 1 : 0; + } else { + value = event.target.value; + } + updateChannel(index, field, value); }; return ( @@ -171,20 +171,33 @@ const ChannelsTable = () => { backgroundColor: index % 2 ? "background.main" : "#666666", }} > - {columns.map((column) => ( - - handleChange(e, index, column.id)} - {...column.props} - /> - - ))} + {columns.map((column) => { + const Component = column.component; + + if (Component === Switch) { + const switchProps = { + onChange: (e) => handleChange(e, index, column.id), + checked: channel[column.id] === 1, + ...column.props, + }; + return ( + + + + ); + } else { + const otherProps = { + onChange: (e) => handleChange(e, index, column.id), + value: channel[column.id], + ...column.props, + }; + return ( + + + + ); + } + })} ))} diff --git a/gui_dev/src/pages/Dashboard.jsx b/gui_dev/src/pages/Dashboard.jsx index c9d21aa5..7f1145de 100644 --- a/gui_dev/src/pages/Dashboard.jsx +++ b/gui_dev/src/pages/Dashboard.jsx @@ -1,8 +1,20 @@ -import { Graph } from "@/components"; -import { Box } from "@mui/material"; +import { RawDataGraph } from '@/components/RawDataGraph'; +import { PSDGraph } from '@/components/PSDGraph'; +import { HeatmapGraph } from '@/components/HeatmapGraph'; +import { Box, Grid } from '@mui/material'; export const Dashboard = () => ( - - + + + + + + + + + + + + ); diff --git a/gui_dev/src/pages/Decoding.jsx b/gui_dev/src/pages/Decoding.jsx index 472d98df..35c60aa8 100644 --- a/gui_dev/src/pages/Decoding.jsx +++ b/gui_dev/src/pages/Decoding.jsx @@ -1,14 +1,119 @@ -import { Box } from "@mui/material"; - -export const Decoding = () => ( - - Not implemented - -); +import React from 'react'; +import { Sidebar, SidebarDrawer } from '@/components'; // Adjust the import paths as needed +import { Settings } from '@/pages'; // Adjust the import paths as needed +import { + Switch, + FormControlLabel, + FormGroup, + Select, + MenuItem, + InputLabel, + Button, + Box, +} from '@mui/material'; +import { useNavigate } from 'react-router-dom'; + +export const Decoding = () => { + const navigate = useNavigate(); + + // State variables for toggles and select + const [movementDecoding, setMovementDecoding] = React.useState(false); + const [dyskinesiaDecoding, setDyskinesiaDecoding] = React.useState(false); + const [selectedDecoder, setSelectedDecoder] = React.useState(''); + const [trainModel, setTrainModel] = React.useState(false); + + const handleRunStream = () => { + navigate('/dashboard'); + }; + + return ( + + {/* If you plan to use the Sidebar, uncomment and adjust as needed */} + {/* + + + + +
Test
+
+
*/} + + + + setMovementDecoding(e.target.checked)} + color="primary" + /> + } + label="Movement Decoding" + /> + + + + + + setDyskinesiaDecoding(e.target.checked)} + color="primary" + /> + } + label="Dyskinesia Decoding" + /> + + + + + Load Predefined Decoder + + + + + + setTrainModel(e.target.checked)} + color="primary" + /> + } + label="Train Model for Target" + /> + + + + + + + +
+ ); +};