sensor-dashboard/base.js
2023-10-14 12:47:22 +02:00

206 lines
5.0 KiB
JavaScript

"use strict";
let dataX = [];
let dataY = [];
let dataY2 = [];
let dataY3 = [];
let xMin = Number.MAX_SAFE_INTEGER;
let xMax = 0;
let height = 600;
let isMobile = false;
function buttonsPlugin(opts) {
return {
hooks: {
ready: u => {
function zoomRange(seconds) {
u.setScale('x', {
min: xMax - seconds,
max: xMax
});
}
const day12 = document.getElementById("h12");
day12.addEventListener("click", e => {
zoomRange(60 * 60 * 12);
});
const day = document.getElementById("day");
day.addEventListener("click", e => {
zoomRange(60 * 60 * 24);
});
const week = document.getElementById("week");
week.addEventListener("click", e => {
zoomRange(60 * 60 * 24 * 7);
});
document.getElementById("all").addEventListener("click", e => {
u.setScale('x', {
min: xMin,
max: xMax
});
})
}
}
};
}
function getSize() {
return {
width: document.getElementById("plot").clientWidth,
height: height
};
}
function processCSV() {
let plotData = [dataX, dataY, dataY2];
let opts = {
title: "Temperature and humidity stats",
id: "chart1",
class: "my-chart",
...getSize(),
plugins: [
buttonsPlugin({})
],
scales: {
x: {
time: true,
range: (u, dataMin, dataMax) => {
if ((dataMax - dataMin) % (60 * 60 * 12) === 0) {
return [dataMin, dataMax];
} else {
return [dataMin, Math.ceil(dataMax / (24 * 60 * 60)) * 24 * 60 * 60];
}
}
},
y: {
auto: true,
// always show zero
// https://github.com/leeoniya/uPlot/issues/143#issuecomment-595251878
/*
range: (u, dataMin, dataMax) => {
let [min, max] = uPlot.rangeNum(dataMin, dataMax, 0.2, true);
return [
Math.min(0, min),
Math.max(0, max),
];
}
*/
},
"%": {
//range: [0, 100]
auto: true,
},
},
series: [
{
label: "t",
value: "{YYYY}-{MM}-{DD} {HH}:{mm}",
class: "monospace"
},
{
label: "temperature",
class: "monospace",
width: 1,
stroke: `rgba(230, 180, 0, 100%)`,
drawStyle: 0, // line
lineInterpolation: 0, // linear
spanGaps: true,
//paths
},
{
label: "relative humidity",
scale: "%",
class: "monospace",
width: 1,
stroke: `rgba(35, 50, 255, 100%)`,
drawStyle: 0, // line
lineInterpolation: 0, // linear
spanGaps: true,
//paths
},
/*
{
label: "absolute humidity",
scale: "grams/m³",
class: "monospace",
width: 2,
stroke: `rgb(85, 100, 255)`,
drawStyle: 0, // line
lineInterpolation: 0, // linear
spanGaps: true,
//paths
}
*/
],
axes: [
{
//label: "Zeit",
labelSize: 20,
values: [[3600 * 24, "{D}.{M}.{YY}\n{H}:{mm}", null, null ]]
},
{
space: 50,
scale: "%",
label: "RH",
},
{
space: 50,
side: 1,
label: "°C",
},
],
};
document.getElementById("plot").innerHTML = "";
let uplot = new uPlot(opts, plotData, document.getElementById("plot"));
uplot.setCursor({left: 10000, top: 0}); // show latest values instantly
uplot.cursor.lock = true;
let legendEl = document.querySelector(".u-legend");
legendEl.classList.remove("u-inline");
document.getElementById("buttons").style.display = "";
// mobile view: activate 24h initially
setTimeout(() => {
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
if (vh > vw) {
document.getElementById("day").click();
height = vh / 2;
uplot.setSize(getSize());
isMobile = true;
}
}, 500);
// automatically resize plot
window.addEventListener("resize", e => {
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
if (isMobile && vw > vh) {
height = vh;
} else if (isMobile && vh > vw) {
height = vh / 2;
}
uplot.setSize(getSize());
});
}
Papa.parse('./x.csv', {
delimiter: ",",
header: true,
download: true,
step: function(row) {
if (row.errors.length > 0) {
return;
}
const t = Number(row.data["time"]);
dataX.push(t);
if (t > xMax) {
xMax = t;
}
if (t < xMin) {
xMin = t;
}
dataY.push(Number(row.data["celsius"]) / 10.0);
dataY2.push(Number(row.data["humidity"]) / 10.0);
//dataY3.push(Number(row.data["abs_humidity"]));
},
complete: processCSV,
});