Skip to content

Commit

Permalink
show load progress in compare view, fixed compare xlsx export
Browse files Browse the repository at this point in the history
  • Loading branch information
io53 committed Oct 15, 2024
1 parent e757e70 commit 56230bf
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 46 deletions.
91 changes: 55 additions & 36 deletions src/components/CompareView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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) {
Expand All @@ -47,6 +53,7 @@ function CompareView(props) {
}

const getGraphData = () => {
if (!sensorData) return [];
gdata = []
let pd = [[], []];
const timestampIndexMap = {}
Expand All @@ -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) {
Expand Down Expand Up @@ -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 <Box height={450}><Progress isIndeterminate /></Box>
//if (loading) return <Box height={450}><Progress isIndeterminate /></Box>
let graphData = getGraphData();
return (
<div ref={ref}>
{loading &&
<div style={graphLoadingOverlay}>
<div style={{ fontFamily: "montserrat", fontSize: 16, fontWeight: "bold", height: "100%", textAlign: "center" }}><div style={{ position: "relative", top: "45%" }}><Spinner size="xl" /></div></div>
</div>
}
{!graphData.length ?
<Box height={450}>
<center style={{ paddingTop: 240, height: 450 }} className="nodatatext">
Expand Down Expand Up @@ -196,6 +213,8 @@ function CompareView(props) {
toY += 0.5
return [fromY, toY]
}
}, x: {
range: loading ? getXRange() : undefined,
}
},
axes: [
Expand Down
15 changes: 8 additions & 7 deletions src/states/SensorCompare.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -61,16 +61,13 @@ function SensorCompare(props) {
return <>
<ZoomInfo />
<ExportMenu buttonText={uppercaseFirst(t("export"))} noPdf onClick={val => {
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)
}
*/
}} />
</>
}
Expand All @@ -93,7 +90,11 @@ function SensorCompare(props) {
<SensorTypePicker value={dataKey} onChange={v => setDataKey(v)} />
</>

const loadButton = <Button isDisabled={!selectedSensors.length || loading} onClick={() => load()}>{i18next.t("load")}</Button>
const loadButton = <Button
isDisabled={!selectedSensors.length || loading}
onClick={() => load()}>
{i18next.t("load")}
</Button>

const load = (newFrom, newTo) => {
reloadIndex++
Expand Down
6 changes: 3 additions & 3 deletions src/utils/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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]) {
Expand Down

0 comments on commit 56230bf

Please sign in to comment.