Update public/scripts/trends.js
This commit is contained in:
parent
ab5f5d2dfc
commit
8348d1a3fa
@ -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));
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user