Update public/scripts/trends.js

This commit is contained in:
JoshBaneyCS 2025-04-23 02:08:19 +00:00
parent ab5f5d2dfc
commit 8348d1a3fa

View File

@ -3,9 +3,11 @@ function average(arr) {
return arr.reduce((a, b) => a + b, 0) / arr.length;
}
// period definitions
// interval mappings
const periodKeys = ['hourly','daily','weekly','monthly','yearly'];
const periodLabels = ['Hourly','Daily','Weekly','Monthly','Yearly'];
// bucket definitions
const periodConfig = {
hourly: { keyFn: r => r.timestamp.slice(0,13), labelFn: k => k.replace('T',' ') },
daily: { keyFn: r => r.timestamp.slice(0,10), labelFn: k => k },
@ -19,22 +21,62 @@ const periodConfig = {
};
// global Chart.js instance
let trendChart;
let trendChart, dataTable;
// fetch all readings
// fetch readings from server
async function fetchReadings() {
const res = await fetch('/api/readings');
return res.ok ? res.json() : [];
}
// build or update chart
// determine direction based on dock door #
function getDirection(dock) {
return ( (dock>=124 && dock<=138) || (dock>=202 && dock<=209) )
? 'Inbound'
: 'Outbound';
}
// render DataTable
function renderTable(allReadings) {
const tbody = $('#trendTable tbody').empty();
allReadings.forEach(r => {
const ts = new Date(r.timestamp).toLocaleString('en-US', { timeZone:'America/New_York' });
const dir = getDirection(r.dockDoor);
tbody.append(`
<tr>
<td>${ts}</td>
<td>${r.temperature.toFixed(1)}</td>
<td>${r.humidity.toFixed(1)}</td>
<td>${r.heatIndex.toFixed(1)}</td>
<td>${r.dockDoor}</td>
<td>${dir}</td>
</tr>
`);
});
// initialize or redraw DataTable
if ($.fn.DataTable.isDataTable('#trendTable')) {
dataTable.clear().rows.add($('#trendTable tbody tr')).draw();
} else {
dataTable = $('#trendTable').DataTable({
paging: true,
pageLength: 25,
ordering: true,
order: [[0,'desc']],
autoWidth: false,
scrollX: true
});
}
}
// draw or update chart
async function drawTrend() {
const all = await fetchReadings();
const slider = document.getElementById('periodSlider');
const periodKey = periodKeys[slider.value];
const cfg = periodConfig[periodKey];
// group and compute stats
// group & stats
const groups = {};
all.forEach(r => {
const key = cfg.keyFn(r);
@ -74,10 +116,13 @@ async function drawTrend() {
} else {
trendChart = new Chart(ctx, {
type: 'line',
data: { labels: labels.map(cfg.labelFn), datasets },
data: {
labels: labels.map(cfg.labelFn),
datasets
},
options: {
responsive: true,
maintainAspectRatio: false, // <<— ensure the canvas fills its container
maintainAspectRatio: false,
plugins: {
legend: { display: true },
tooltip: { mode:'index', intersect:false },
@ -93,17 +138,24 @@ async function drawTrend() {
}
});
}
// always update table below
renderTable(all);
}
// wire up controls
document.addEventListener('DOMContentLoaded', () => {
// initial draw
drawTrend();
// slider
document.getElementById('periodSlider')
.addEventListener('input', e => {
document.getElementById('periodLabel').textContent = periodLabels[e.target.value];
drawTrend();
});
.addEventListener('input', e => {
document.getElementById('periodLabel').textContent = periodLabels[e.target.value];
drawTrend();
});
// toggles
document.querySelectorAll('#metricToggles input')
.forEach(chk => chk.addEventListener('change', drawTrend));
.forEach(chk => chk.addEventListener('change', drawTrend));
});