From 6560cabf6480ca01b7004c2c18b7f636cd365742 Mon Sep 17 00:00:00 2001 From: Aaron Wu <12989649+Aaron-Wu1@users.noreply.github.com> Date: Sun, 30 Jul 2023 23:33:30 -0700 Subject: [PATCH 1/3] added chart component --- frontend/src/charts/Chart.jsx | 104 ++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 frontend/src/charts/Chart.jsx diff --git a/frontend/src/charts/Chart.jsx b/frontend/src/charts/Chart.jsx new file mode 100644 index 00000000..3af08876 --- /dev/null +++ b/frontend/src/charts/Chart.jsx @@ -0,0 +1,104 @@ +import { React, useRef, useState, useMemo } from 'react'; +import { Line } from 'react-chartjs-2'; +import 'chartjs-adapter-luxon'; +import PropTypes from 'prop-types'; +import { Box, ToggleButton } from '@mui/material'; +import zoom from '../assets/zoom.svg'; +import reset from '../assets/reset.svg'; +import pan from '../assets/pan.svg'; + +function Chart(props) { + const chartRef = useRef(); + const [zoomSelected, setZoomSelected] = useState(false); + const [panSelected, setPanSelected] = useState(true); + const handleResetZoom = () => { + console.log('reset zoom'); + if (chartRef.current) { + chartRef.current.resetZoom(); + } + }; + const handleToggleZoom = () => { + console.log('toggle zoom'); + if (chartRef.current) { + chartRef.current.options.plugins.zoom.zoom.wheel.enabled = + !chartRef.current.options.plugins.zoom.zoom.wheel.enabled; + chartRef.current.update(); + setZoomSelected(!zoomSelected); + } + }; + const handleTogglePan = () => { + console.log('toggle pan'); + if (chartRef.current) { + const pan = chartRef.current.options.plugins.zoom.pan.enabled; + chartRef.current.options.plugins.zoom.pan.enabled = + !chartRef.current.options.plugins.zoom.pan.enabled; + chartRef.current.update(); + console.log(chartRef.current.options.plugins.zoom.pan.enabled); + setPanSelected(!panSelected); + } + }; + + const chart = useMemo( + () => , + [props.data, props.options] + ); + return ( + + {chart} + + + + + + + + + + + + + ); +} + +export default Chart; + +Chart.propTypes = { + data: PropTypes.object, + options: PropTypes.object, +}; From 9a4f5ba050508909a9158a2d885d261d2162454b Mon Sep 17 00:00:00 2001 From: Aaron Wu <12989649+Aaron-Wu1@users.noreply.github.com> Date: Mon, 31 Jul 2023 00:17:14 -0700 Subject: [PATCH 2/3] added zoom and pan btns --- frontend/src/charts/Chart.jsx | 13 +++--- frontend/src/charts/PwrChart/PwrChart.jsx | 39 +++++++++++------ frontend/src/charts/TempChart/TempChart.jsx | 45 +++++++++++++------- frontend/src/charts/VChart/VChart.jsx | 47 ++++++++++++++------- frontend/src/charts/VwcChart/VwcChart.jsx | 47 ++++++++++++++------- frontend/src/charts/defaultChartOptions.js | 12 ------ 6 files changed, 126 insertions(+), 77 deletions(-) delete mode 100644 frontend/src/charts/defaultChartOptions.js diff --git a/frontend/src/charts/Chart.jsx b/frontend/src/charts/Chart.jsx index 3af08876..c3ef7b32 100644 --- a/frontend/src/charts/Chart.jsx +++ b/frontend/src/charts/Chart.jsx @@ -8,7 +8,7 @@ import reset from '../assets/reset.svg'; import pan from '../assets/pan.svg'; function Chart(props) { - const chartRef = useRef(); + const chartRef = useRef([]); const [zoomSelected, setZoomSelected] = useState(false); const [panSelected, setPanSelected] = useState(true); const handleResetZoom = () => { @@ -38,10 +38,10 @@ function Chart(props) { } }; - const chart = useMemo( - () => , - [props.data, props.options] - ); + // const chart = useMemo( + // () => , + // [props.data, props.options] + // ); return ( - {chart} + {/* {chart} */} + ; + return ; } PwrChart.propTypes = { diff --git a/frontend/src/charts/TempChart/TempChart.jsx b/frontend/src/charts/TempChart/TempChart.jsx index 9210be48..476cda7e 100644 --- a/frontend/src/charts/TempChart/TempChart.jsx +++ b/frontend/src/charts/TempChart/TempChart.jsx @@ -1,8 +1,8 @@ -import { React } from "react"; -import { Line } from "react-chartjs-2"; -import "chartjs-adapter-luxon"; -import { zoomOptions } from "../defaultChartOptions"; -import PropTypes from "prop-types"; +import { React } from 'react'; +import 'chartjs-adapter-luxon'; +import { zoomOptions } from '../defaultChartOptions'; +import PropTypes from 'prop-types'; +import Chart from '../Chart'; export default function TempChart(props) { const data = props.data; @@ -11,12 +11,12 @@ export default function TempChart(props) { responsive: true, scales: { x: { - position: "bottom", + position: 'bottom', title: { display: true, - text: "Time", + text: 'Time', }, - type: "time", + type: 'time', ticks: { autoSkip: false, autoSkipPadding: 50, @@ -27,28 +27,43 @@ export default function TempChart(props) { }, time: { displayFormats: { - hour: "hh:mm a", - day: "MM/dd", + hour: 'hh:mm a', + day: 'MM/dd', }, }, }, y: { - type: "linear", - position: "left", + type: 'linear', + position: 'left', beginAtZero: true, suggestedMax: 35, title: { display: true, - text: "Temperature (°C)", + text: 'Temperature (°C)', }, }, }, plugins: { - zoom: zoomOptions, + zoom: { + zoom: { + wheel: { + enabled: false, + }, + pinch: { + enabled: false, + }, + mode: 'xy', + scaleMode: 'xy', + }, + pan: { + enabled: true, + mode: 'xy', + }, + }, }, }; - return ; + return ; } TempChart.propTypes = { data: PropTypes.object, diff --git a/frontend/src/charts/VChart/VChart.jsx b/frontend/src/charts/VChart/VChart.jsx index b5988567..03c03c34 100644 --- a/frontend/src/charts/VChart/VChart.jsx +++ b/frontend/src/charts/VChart/VChart.jsx @@ -1,8 +1,8 @@ -import { React } from "react"; -import { Line } from "react-chartjs-2"; -import "chartjs-adapter-luxon"; -import { zoomOptions } from "../defaultChartOptions"; -import PropTypes from "prop-types"; +import { React } from 'react'; +import 'chartjs-adapter-luxon'; +import { zoomOptions } from '../defaultChartOptions'; +import PropTypes from 'prop-types'; +import Chart from '../Chart'; export default function VChart(props) { const data = props.data; @@ -11,12 +11,12 @@ export default function VChart(props) { responsive: true, scales: { x: { - position: "bottom", + position: 'bottom', title: { display: true, - text: "Time", + text: 'Time', }, - type: "time", + type: 'time', ticks: { autoSkip: false, autoSkipPadding: 50, @@ -27,17 +27,17 @@ export default function VChart(props) { }, time: { displayFormats: { - hour: "hh:mm", - day: "D", + hour: 'hh:mm', + day: 'D', }, }, }, vAxis: { - position: "left", + position: 'left', beginAtZero: true, title: { display: true, - text: "Cell Voltage (V)", + text: 'Cell Voltage (V)', }, suggestedMax: 0.28, min: 0, @@ -47,20 +47,35 @@ export default function VChart(props) { }, }, cAxis: { - position: "right", + position: 'right', beginAtZero: true, title: { display: true, - text: "Current (µA)", + text: 'Current (µA)', }, }, }, plugins: { - zoom: zoomOptions, + zoom: { + zoom: { + wheel: { + enabled: false, + }, + pinch: { + enabled: false, + }, + mode: 'xy', + scaleMode: 'xy', + }, + pan: { + enabled: true, + mode: 'xy', + }, + }, }, }; - return ; + return ; } VChart.propTypes = { diff --git a/frontend/src/charts/VwcChart/VwcChart.jsx b/frontend/src/charts/VwcChart/VwcChart.jsx index 8eb9eba4..997e8ff4 100644 --- a/frontend/src/charts/VwcChart/VwcChart.jsx +++ b/frontend/src/charts/VwcChart/VwcChart.jsx @@ -1,8 +1,8 @@ -import { React } from "react"; -import { Line } from "react-chartjs-2"; -import "chartjs-adapter-luxon"; -import { zoomOptions } from "../defaultChartOptions"; -import PropTypes from "prop-types"; +import { React } from 'react'; +import 'chartjs-adapter-luxon'; +import { zoomOptions } from '../defaultChartOptions'; +import PropTypes from 'prop-types'; +import Chart from '../Chart'; export default function VwcChart(props) { const data = props.data; @@ -11,12 +11,12 @@ export default function VwcChart(props) { responsive: true, scales: { x: { - position: "bottom", + position: 'bottom', title: { display: true, - text: "Time", + text: 'Time', }, - type: "time", + type: 'time', ticks: { autoSkip: false, autoSkipPadding: 50, @@ -27,26 +27,26 @@ export default function VwcChart(props) { }, time: { displayFormats: { - hour: "hh:mm a", - day: "D", + hour: 'hh:mm a', + day: 'D', }, }, }, ecAxis: { - position: "right", + position: 'right', beginAtZero: true, title: { display: true, - text: "EC (µS/cm)", + text: 'EC (µS/cm)', }, }, vwcAxis: { - position: "left", + position: 'left', beginAtZero: true, suggestedMax: 0.9, title: { display: true, - text: "VWC (%)", + text: 'VWC (%)', }, min: 0, grid: { @@ -55,11 +55,26 @@ export default function VwcChart(props) { }, }, plugins: { - zoom: zoomOptions, + zoom: { + zoom: { + wheel: { + enabled: false, + }, + pinch: { + enabled: false, + }, + mode: 'xy', + scaleMode: 'xy', + }, + pan: { + enabled: true, + mode: 'xy', + }, + }, }, }; - return ; + return ; } VwcChart.propTypes = { diff --git a/frontend/src/charts/defaultChartOptions.js b/frontend/src/charts/defaultChartOptions.js deleted file mode 100644 index 8b77ebfd..00000000 --- a/frontend/src/charts/defaultChartOptions.js +++ /dev/null @@ -1,12 +0,0 @@ -export const zoomOptions = { - zoom: { - pinch: { - enabled: true, - }, - mode: "xy", - }, - pan: { - enabled: true, - mode: "xy", - }, -}; From 115d375f926c339d8108b6d8e2f8cf9c6e795e2a Mon Sep 17 00:00:00 2001 From: Aaron Wu <12989649+Aaron-Wu1@users.noreply.github.com> Date: Mon, 31 Jul 2023 00:31:09 -0700 Subject: [PATCH 3/3] added spacing between charts --- frontend/src/pages/dashboard/Dashboard.jsx | 145 +++++++++++---------- 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/frontend/src/pages/dashboard/Dashboard.jsx b/frontend/src/pages/dashboard/Dashboard.jsx index ff229d0a..cdeea2f6 100644 --- a/frontend/src/pages/dashboard/Dashboard.jsx +++ b/frontend/src/pages/dashboard/Dashboard.jsx @@ -1,27 +1,27 @@ // import "./Dashboard.css"; -import { React, useState, useEffect } from "react"; -import Chart from "chart.js/auto"; -import { CategoryScale } from "chart.js"; -import "chartjs-adapter-luxon"; -import zoomPlugin from "chartjs-plugin-zoom"; -import { getCellIds } from "../../services/cell"; -import { getTerosData } from "../../services/teros"; -import { getPowerData } from "../../services/power"; -import PwrChart from "../../charts/PwrChart/PwrChart"; -import VChart from "../../charts/VChart/VChart"; -import VwcChart from "../../charts/VwcChart/VwcChart"; -import TempChart from "../../charts/TempChart/TempChart"; -import { DateTime } from "luxon"; -import DownloadBtn from "../../components/DownloadBtn"; -import Box from "@mui/material/Box"; -import Grid from "@mui/material/Grid"; -import Stack from "@mui/material/Stack"; -import Divider from "@mui/material/Divider"; -import InputLabel from "@mui/material/InputLabel"; -import MenuItem from "@mui/material/MenuItem"; -import FormControl from "@mui/material/FormControl"; -import Select from "@mui/material/Select"; -import DateRangeSel from "../../components/DateRangeSel"; +import { React, useState, useEffect } from 'react'; +import Chart from 'chart.js/auto'; +import { CategoryScale } from 'chart.js'; +import 'chartjs-adapter-luxon'; +import zoomPlugin from 'chartjs-plugin-zoom'; +import { getCellIds } from '../../services/cell'; +import { getTerosData } from '../../services/teros'; +import { getPowerData } from '../../services/power'; +import PwrChart from '../../charts/PwrChart/PwrChart'; +import VChart from '../../charts/VChart/VChart'; +import VwcChart from '../../charts/VwcChart/VwcChart'; +import TempChart from '../../charts/TempChart/TempChart'; +import { DateTime } from 'luxon'; +import DownloadBtn from '../../components/DownloadBtn'; +import Box from '@mui/material/Box'; +import Grid from '@mui/material/Grid'; +import Stack from '@mui/material/Stack'; +import Divider from '@mui/material/Divider'; +import InputLabel from '@mui/material/InputLabel'; +import MenuItem from '@mui/material/MenuItem'; +import FormControl from '@mui/material/FormControl'; +import Select from '@mui/material/Select'; +import DateRangeSel from '../../components/DateRangeSel'; Chart.register(CategoryScale); Chart.register(zoomPlugin); @@ -50,7 +50,7 @@ function Dashboard() { datasets: [ { data: [], - borderColor: "black", + borderColor: 'black', borderWidth: 2, }, ], @@ -60,15 +60,15 @@ function Dashboard() { datasets: [ { data: [], - borderColor: "black", + borderColor: 'black', borderWidth: 2, - yAxisID: "vAxis", + yAxisID: 'vAxis', }, { data: [], - borderColor: "black", + borderColor: 'black', borderWidth: 2, - yAxisID: "cAxis", + yAxisID: 'cAxis', }, ], }); @@ -76,9 +76,9 @@ function Dashboard() { label: [], datasets: [ { - label: "Voltage", + label: 'Voltage', data: [], - borderColor: "black", + borderColor: 'black', borderWidth: 2, }, ], @@ -87,18 +87,18 @@ function Dashboard() { label: [], datasets: [ { - label: "VWC", + label: 'VWC', data: [], - borderColor: "black", + borderColor: 'black', borderWidth: 2, - yAxisID: "vwcAxis", + yAxisID: 'vwcAxis', }, { - label: "EC", + label: 'EC', data: [], - borderColor: "black", + borderColor: 'black', borderWidth: 2, - yAxisID: "ecAxis", + yAxisID: 'ecAxis', }, ], }); @@ -119,22 +119,22 @@ function Dashboard() { labels: powerDataObj.timestamp, datasets: [ { - label: "Voltage (v)", + label: 'Voltage (v)', data: powerDataObj.v, - borderColor: "lightgreen", + borderColor: 'lightgreen', borderWidth: 2, fill: false, - yAxisID: "vAxis", + yAxisID: 'vAxis', radius: 2, pointRadius: 2, }, { - label: "Current (µA)", + label: 'Current (µA)', data: powerDataObj.i, - borderColor: "purple", + borderColor: 'purple', borderWidth: 2, fill: false, - yAxisID: "cAxis", + yAxisID: 'cAxis', radius: 2, pointRadius: 2, }, @@ -144,9 +144,9 @@ function Dashboard() { labels: powerDataObj.timestamp, datasets: [ { - label: "Power (µV)", + label: 'Power (µV)', data: powerDataObj.p, - borderColor: "orange", + borderColor: 'orange', borderWidth: 2, fill: false, radius: 2, @@ -164,22 +164,22 @@ function Dashboard() { labels: terosDataObj.timestamp, datasets: [ { - label: "Volumetric Water Content (VWC)", + label: 'Volumetric Water Content (VWC)', data: terosDataObj.vwc, - borderColor: "blue", + borderColor: 'blue', borderWidth: 2, fill: false, - yAxisID: "vwcAxis", + yAxisID: 'vwcAxis', radius: 2, pointRadius: 2, }, { - label: "Electrical Conductivity (µS/cm)", + label: 'Electrical Conductivity (µS/cm)', data: terosDataObj.ec, - borderColor: "black", + borderColor: 'black', borderWidth: 2, fill: false, - yAxisID: "ecAxis", + yAxisID: 'ecAxis', radius: 2, pointRadius: 2, }, @@ -189,9 +189,9 @@ function Dashboard() { labels: terosDataObj.timestamp, datasets: [ { - label: "Temperature", + label: 'Temperature', data: terosDataObj.temp, - borderColor: "red", + borderColor: 'red', borderWidth: 2, fill: false, radius: 2, @@ -226,26 +226,26 @@ function Dashboard() { return ( } - justifyContent="spaced-evently" - sx={{ height: "100vh", boxSizing: "border-box" }} + direction='column' + divider={} + justifyContent='spaced-evently' + sx={{ height: '100vh', boxSizing: 'border-box' }} > } - alignItems="center" - justifyContent="space-evenly" + direction='row' + divider={} + alignItems='center' + justifyContent='space-evenly' sx={{ p: 2 }} flexItem > - Cell + Cell - + {/* - + - + - + - +