Add data_visualization/js/app.js
This commit is contained in:
parent
7d688a6480
commit
eb89a6d7b9
1 changed files with 173 additions and 0 deletions
173
data_visualization/js/app.js
Normal file
173
data_visualization/js/app.js
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
import { fetchSensorData } from './api.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} SensorData
|
||||
* @property {string} timestamp
|
||||
* @property {string} location_id
|
||||
* @property {number} temperature
|
||||
* @property {number} humidity
|
||||
* @property {number} light
|
||||
*/
|
||||
|
||||
let allData = [];
|
||||
let chartInstances = {};
|
||||
|
||||
/**
|
||||
* Initialisiert UI-Elemente, ruft Daten ab und rendert Diagramme.
|
||||
* Wird beim Laden des Fensters aufgerufen.
|
||||
*/
|
||||
export async function initApp() {
|
||||
try {
|
||||
const data = await fetchSensorData();
|
||||
if (!Array.isArray(data)) {
|
||||
console.error('Ungültige Datenstruktur von /data');
|
||||
return;
|
||||
}
|
||||
allData = data;
|
||||
initializeFilters();
|
||||
renderCharts(data);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Initialisieren der Anwendung:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisiert Datumsauswahl- und Filter-Events.
|
||||
*/
|
||||
function initializeFilters() {
|
||||
const startInput = document.getElementById('filter-start');
|
||||
const endInput = document.getElementById('filter-end');
|
||||
|
||||
[startInput, endInput].forEach((input) => {
|
||||
if (input) {
|
||||
input.addEventListener('change', () => {
|
||||
const startDate = new Date(startInput?.value);
|
||||
const endDate = new Date(endInput?.value);
|
||||
const filtered = filterDataByDate(allData, startDate, endDate);
|
||||
updateCharts(filtered);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtert Daten basierend auf Start- und Enddatum.
|
||||
* @param {SensorData[]} data
|
||||
* @param {Date} start
|
||||
* @param {Date} end
|
||||
* @returns {SensorData[]}
|
||||
*/
|
||||
function filterDataByDate(data, start, end) {
|
||||
if (!(start instanceof Date) || !(end instanceof Date)) return data;
|
||||
return data.filter(({ timestamp }) => {
|
||||
const t = new Date(timestamp);
|
||||
return t >= start && t <= end;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendert initiale Diagramme.
|
||||
* @param {SensorData[]} data
|
||||
*/
|
||||
function renderCharts(data) {
|
||||
const ctxTemp = document.getElementById('chart-temperature');
|
||||
const ctxHum = document.getElementById('chart-humidity');
|
||||
const ctxLight = document.getElementById('chart-light');
|
||||
|
||||
const timestamps = data.map(d => new Date(d.timestamp).toLocaleTimeString());
|
||||
|
||||
chartInstances.temperature = new Chart(ctxTemp, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timestamps,
|
||||
datasets: [{
|
||||
label: 'Temperatur (°C)',
|
||||
data: data.map(d => d.temperature),
|
||||
borderColor: '#FF5733',
|
||||
backgroundColor: 'rgba(255, 87, 51, 0.1)',
|
||||
tension: 0.3,
|
||||
}]
|
||||
},
|
||||
options: baseChartOptions('Temperaturverlauf')
|
||||
});
|
||||
|
||||
chartInstances.humidity = new Chart(ctxHum, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timestamps,
|
||||
datasets: [{
|
||||
label: 'Feuchtigkeit (%)',
|
||||
data: data.map(d => d.humidity),
|
||||
borderColor: '#33A1FF',
|
||||
backgroundColor: 'rgba(51, 161, 255, 0.1)',
|
||||
tension: 0.3,
|
||||
}]
|
||||
},
|
||||
options: baseChartOptions('Feuchtigkeitsverlauf')
|
||||
});
|
||||
|
||||
chartInstances.light = new Chart(ctxLight, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timestamps,
|
||||
datasets: [{
|
||||
label: 'Lichtintensität (lx)',
|
||||
data: data.map(d => d.light),
|
||||
borderColor: '#FFC300',
|
||||
backgroundColor: 'rgba(255, 195, 0, 0.1)',
|
||||
tension: 0.3,
|
||||
}]
|
||||
},
|
||||
options: baseChartOptions('Lichtintensität')
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Options-Vorlage für Diagramme.
|
||||
* @param {string} title
|
||||
* @returns {object}
|
||||
*/
|
||||
function baseChartOptions(title) {
|
||||
return {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
interaction: { mode: 'index', intersect: false },
|
||||
plugins: {
|
||||
title: { display: true, text: title },
|
||||
tooltip: { enabled: true },
|
||||
legend: { display: true }
|
||||
},
|
||||
scales: {
|
||||
x: { display: true, title: { display: true, text: 'Zeit' } },
|
||||
y: { display: true }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert Diagramme auf Basis neuer Filter oder Daten.
|
||||
* @param {SensorData[]} filteredData
|
||||
*/
|
||||
export function updateCharts(filteredData) {
|
||||
const timestamps = filteredData.map(d => new Date(d.timestamp).toLocaleTimeString());
|
||||
|
||||
if (chartInstances.temperature) {
|
||||
chartInstances.temperature.data.labels = timestamps;
|
||||
chartInstances.temperature.data.datasets[0].data = filteredData.map(d => d.temperature);
|
||||
chartInstances.temperature.update();
|
||||
}
|
||||
|
||||
if (chartInstances.humidity) {
|
||||
chartInstances.humidity.data.labels = timestamps;
|
||||
chartInstances.humidity.data.datasets[0].data = filteredData.map(d => d.humidity);
|
||||
chartInstances.humidity.update();
|
||||
}
|
||||
|
||||
if (chartInstances.light) {
|
||||
chartInstances.light.data.labels = timestamps;
|
||||
chartInstances.light.data.datasets[0].data = filteredData.map(d => d.light);
|
||||
chartInstances.light.update();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', initApp);
|
||||
Loading…
Reference in a new issue