Files
rpi-sensors/charts.html

162 lines
5.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ledda's Rooms Climate</title>
<script src="/climate/static/Chart.bundle.min.js"></script>
</head>
<body>
<div class="chart-container" style="position: relative; height:40vh; width:80vw; margin: auto">
<canvas id="myChart"></canvas>
</div>
<script type="application/javascript">
const ROOT_URL = "climate/";
const humidityColor = 'rgb(45,141,45)';
const tempColor = 'rgb(0,134,222)';
const co2Color = 'rgb(194,30,30)';
let minutesDisplayed = 60;
async function getData() {
let urlEndpoint = "/" + ROOT_URL + "data/";
const pathname = window.location.pathname;
if (pathname.includes("since")) {
minutesDisplayed = Number(pathname.slice(pathname.lastIndexOf("/") + 1));
urlEndpoint += "since/" + minutesDisplayed;
}
const data = await fetch(urlEndpoint);
return transformData(await data.json());
}
async function initChart() {
const ctx = document.getElementById('myChart').getContext('2d');
const {humidity, temp, co2} = await getData();
const myChart = Chart.Line(ctx, {
data: {
datasets: [{
label: 'Humidity',
data: humidity,
borderColor: humidityColor,
fill: false,
id: 'humidity',
yAxisID: 'y-axis-3',
}, {
label: 'Temperature',
data: temp,
borderColor: tempColor,
fill: false,
id: 'temp',
yAxisID: 'y-axis-2',
}, {
label: 'Co2 Concentration',
data: co2,
borderColor: co2Color,
fill: false,
id: 'co2',
yAxisID: 'y-axis-1',
}]
},
options: {
stacked: false,
title: {
display: true,
text: 'Ledda\'s Room Climate',
},
scales: {
xAxes: [{
type: 'time',
time: {
unit: 'second'
}
}],
yAxes: [{
type: 'linear',
display: true,
position: 'right',
id: 'y-axis-1',
ticks: {
fontColor: co2Color,
suggestedMin: 400,
suggestedMax: 1100,
},
}, {
type: 'linear',
display: true,
position: 'left',
id: 'y-axis-2',
ticks: {
fontColor: tempColor,
suggestedMin: 10,
suggestedMax: 35,
},
gridLines: {
drawOnChartArea: false,
},
}, {
type: 'linear',
display: true,
position: 'left',
id: 'y-axis-3',
ticks: {
fontColor: humidityColor,
suggestedMin: 15,
suggestedMax: 85,
},
gridLines: {
drawOnChartArea: false,
},
}],
}
},
});
startFetchTimeout(myChart);
}
function transformData(json) {
const humidity = [];
const co2 = [];
const temp = [];
for (let i = 0; i < json.snapshots.length; i++) {
const snapshot = json.snapshots[json.snapshots.length - i - 1];
co2.push({x: snapshot.time, y: snapshot.co2});
temp.push({x: snapshot.time, y: snapshot.temp});
humidity.push({x: snapshot.time, y: snapshot.humidity});
}
return {humidity, co2, temp};
}
function startFetchTimeout(chart) {
setInterval(async () => {
const newDatum = await fetch("/" + ROOT_URL + "data/last/");
const snapshot = (await newDatum.json()).snapshots[0];
if (snapshot.time !== chart.data.datasets[0].x) {
removeExpiredData(chart);
insertSnapshot(chart, snapshot);
}
}, 10 * 1000);
}
function insertSnapshot(chart, snapshot) {
chart.data.datasets[0].data.push({x: snapshot.time, y: snapshot.humidity});
chart.data.datasets[1].data.push({x: snapshot.time, y: snapshot.temp});
chart.data.datasets[2].data.push({x: snapshot.time, y: snapshot.co2});
chart.update(0);
}
function removeExpiredData(chart) {
for (let i = 0; i < chart.data.datasets[0].data.length; i++) {
console.log((Date.now() - Date.parse(chart.data.datasets[0].data[i].x)));
if ((Date.now() - Date.parse(chart.data.datasets[0].data[i].x)) > minutesDisplayed * 60000) {
chart.data.datasets[0].data.splice(i, 1);
chart.data.datasets[1].data.splice(i, 1);
chart.data.datasets[2].data.splice(i, 1);
}
}
}
initChart();
</script>
</body>
</html>