diff --git a/src/components/CompareView.jsx b/src/components/CompareView.jsx index 049a98d..01dd09e 100644 --- a/src/components/CompareView.jsx +++ b/src/components/CompareView.jsx @@ -6,7 +6,7 @@ import pjson from '../../package.json'; import NetworkApi from "../NetworkApi"; import parse from "../decoder/parser"; import { ruuviTheme } from "../themes"; -import { Box, useColorMode } from "@chakra-ui/react"; +import { Box, Spinner, useColorMode } from "@chakra-ui/react"; import { t } from "i18next"; import { getUnitHelper } from "../UnitHelper"; import UplotTouchZoomPlugin from "./uplotPlugins/UplotTouchZoomPlugin"; @@ -29,6 +29,12 @@ function getGraphColor(idx, fill) { } return color } +const graphLoadingOverlay = { + position: "absolute", + width: "100%", + height: "450px", + zIndex: 1, +} var gdata = [] function CompareView(props) { @@ -47,6 +53,7 @@ function CompareView(props) { } const getGraphData = () => { + if (!sensorData) return []; gdata = [] let pd = [[], []]; const timestampIndexMap = {} @@ -58,6 +65,7 @@ function CompareView(props) { if (pd.length < sensors.length + 2) pd.push([]); for (let j = 0; j < d.measurements.length; j++) { + if (!d.measurements[j].parsed) continue; const timestamp = d.measurements[j].timestamp; if (timestamp in timestampIndexMap) { @@ -106,61 +114,70 @@ function CompareView(props) { setSensorData([]) gdata = [] let pd = [[], []]; - let until = props.to - const fetchDataPromises = sensors.map(async (sensor) => { - let since = props.from - let allData = null + for (const sensor of sensors) { + let until = props.to + let since = props.from; + let allData = null; for (; ;) { - if (since >= until) break + if (since >= until) break; let data = await new NetworkApi().getAsync(sensor, since, until, { limit: pjson.settings.dataFetchPaginationSize }); if (data.result === "success") { - if (!allData) allData = data - else allData.data.measurements = allData.data.measurements.concat(data.data.measurements) - - let returndDataLength = data.data.measurements.length - if (data.data.nextUp) until = data.data.nextUp - else if (data.data.fromCache) until = data.data.measurements[data.data.measurements.length - 1].timestamp - else if (returndDataLength >= pjson.settings.dataFetchPaginationSize) until = data.data.measurements[data.data.measurements.length - 1].timestamp - else break - } else { - allData = data - break - } - } - // filter out data that is not in the time range - if (allData) { - allData.data.measurements = allData.data.measurements.filter(x => x.timestamp >= props.from && x.timestamp <= props.to) - } - return { sensor, data: allData }; - }); + if (!allData) allData = data; + else allData.data.measurements = allData.data.measurements.concat(data.data.measurements); + + let returndDataLength = data.data.measurements.length; + if (data.data.nextUp) until = data.data.nextUp; + else if (data.data.fromCache) until = data.data.measurements[data.data.measurements.length - 1].timestamp; + else if (returndDataLength >= pjson.settings.dataFetchPaginationSize) until = data.data.measurements[data.data.measurements.length - 1].timestamp; + else break; + + let d = parse(allData.data); + setSensorData((s) => { + if (!s) s = []; + let updated = false; + const newData = s.map(item => { + if (item.sensor === sensor) { + updated = true; + return d; // Replace the existing data for the sensor + } + return item; + }); - // Use Promise.all to wait for all promises to resolve - const results = await Promise.all(fetchDataPromises); + if (!updated) { + newData.push(d); // Add new data if the sensor was not found + } - results.forEach(({ sensor, data }) => { - if (data?.result === "success" && data.data.measurements.length) { - let d = parse(data.data); - setSensorData((s) => [...s, d]); + return newData; + }); + } } - }); + } - props.setData(results) setLoading(false); props.isLoading(false); })(); - }, [sensors, props.from, props.reloadIndex]); + }, [sensors, props.to, props.from, props.reloadIndex]); + + useEffect(() => { + props.setData(sensorData); + }, [sensorData]); function getXRange() { - return [props.from, new Date().getTime() / 1000] + return [props.from, props.to || new Date().getTime() / 1000] } const { width } = useContainerDimensions(ref) const colorMode = useColorMode().colorMode; - if (loading) return + //if (loading) return let graphData = getGraphData(); return (
+ {loading && +
+
+
+ } {!graphData.length ?
@@ -196,6 +213,8 @@ function CompareView(props) { toY += 0.5 return [fromY, toY] } + }, x: { + range: loading ? getXRange() : undefined, } }, axes: [ diff --git a/src/states/SensorCompare.jsx b/src/states/SensorCompare.jsx index d0af45b..2dd87c9 100644 --- a/src/states/SensorCompare.jsx +++ b/src/states/SensorCompare.jsx @@ -10,7 +10,7 @@ import { EmailBox } from "../components/EmailBox"; import ZoomInfo from "../components/ZoomInfo"; import ExportMenu from "../components/ExportMenu"; import { uppercaseFirst } from "../TextHelper"; -import { exportMuliSensorCSV } from "../utils/export"; +import { exportMuliSensorCSV, exportMuliSensorXLSX } from "../utils/export"; import ScreenSizeWrapper from "../components/ScreenSizeWrapper"; import { getUnitHelper } from "../UnitHelper"; @@ -61,16 +61,13 @@ function SensorCompare(props) { return <> { - exportMuliSensorCSV(data, i18next.t, dataKey) - /* switch (val) { case "XLSX": - this.export_XLSX() + exportMuliSensorXLSX(data, i18next.t, dataKey) break default: - this.export() + exportMuliSensorCSV(data, i18next.t, dataKey) } - */ }} /> } @@ -93,7 +90,11 @@ function SensorCompare(props) { setDataKey(v)} /> - const loadButton = + const loadButton = const load = (newFrom, newTo) => { reloadIndex++ diff --git a/src/utils/export.js b/src/utils/export.js index 4f6537e..229085f 100644 --- a/src/utils/export.js +++ b/src/utils/export.js @@ -79,12 +79,12 @@ function processMultiSensorReportData(data, t, sensorType) { let unit = uHelpV.unit var csvHeader = [t('date')]; for (let i = 0; i < data.length; i++) { - csvHeader.push(data[i].data.data.name + " (" + unit + ")"); + csvHeader.push(data[i].name + " (" + unit + ")"); } let timestampsWithData = [] for (let i = 0; i < data.length; i++) { - let d = data[i].data.data.measurements + let d = data[i].measurements for (let j = 0; j < d.length; j++) { if (d[j].parsed) { timestampsWithData.push(d[j].timestamp) @@ -101,7 +101,7 @@ function processMultiSensorReportData(data, t, sensorType) { for (let i = 0; i < timestampsWithData.length; i++) { let row = [toISOString(new Date(timestampsWithData[i] * 1000))] for (let j = 0; j < data.length; j++) { - let d = data[j].data.data.measurements + let d = data[j].measurements let val = "" for (let k = 0; k < d.length; k++) { if (d[k].timestamp === timestampsWithData[i]) {