wlan_sternenhimmel_ilzstausee/data_visualization/js/app.js

122 lines
No EOL
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
/**
* Haupt-Einstiegspunkt der Anwendung zur Echtzeit-Visualisierung der WLAN-Daten.
* Initialisiert DOM, Heatmap und Event-Listener.
*/
/**
* Globale Referenzen auf DOM-Elemente und State-Objekte.
* @type {{ heatmapContainer: HTMLElement|null, refreshButton: HTMLElement|null, statsContainer: HTMLElement|null, heatmapInstance: any|null }}
*/
const appState = {
heatmapContainer: null,
refreshButton: null,
statsContainer: null,
heatmapInstance: null
};
/**
* Initialisiert UI und Listener.
*/
export async function initApp() {
appState.heatmapContainer = document.getElementById('heatmap');
appState.refreshButton = document.getElementById('refresh-btn');
appState.statsContainer = document.getElementById('stats');
if (!appState.heatmapContainer) {
console.error('Heatmap-Container nicht gefunden.');
return;
}
// Dummy Heatmap-Struktur initialisieren (z. B. Leaflet oder einfache Canvas-basierte Heatmap)
appState.heatmapInstance = createHeatmap(appState.heatmapContainer);
// Events
if (appState.refreshButton) {
appState.refreshButton.addEventListener('click', refreshData);
}
// Periodische Datenaktualisierung starten
setInterval(refreshData, 15000);
// Initial einmal rendern
await refreshData();
}
/**
* Lädt neue Daten und aktualisiert die Heatmap.
*/
export async function refreshData() {
try {
// Beispiel: lokale Datenquelle; später durch echte API ersetzt
const response = await fetch('data/heatmap_data.json');
if (!response.ok) throw new Error('Fehler beim Laden der Heatmap-Daten');
/** @type {{ points: Array<{lat: number, lng: number, rssi: number}>, stats: {min: number, max: number, avg: number} }} */
const data = await response.json();
if (appState.heatmapInstance && data?.points) {
updateHeatmap(appState.heatmapInstance, data.points);
renderStats(data.stats);
}
} catch (error) {
console.error('refreshData Fehler:', error);
}
}
/**
* Erstellt eine einfache Heatmap-Instanz.
* @param {HTMLElement} container
* @returns {object}
*/
function createHeatmap(container) {
// Platzhalter für echtes Heatmap-Rendering-Objekt
const layer = document.createElement('div');
layer.className = 'heatmap__layer';
container.appendChild(layer);
return {
container: layer,
data: [],
render(points) {
// Primitive Darstellung: Größe oder Farbe anhand RSSI simulieren
layer.innerHTML = '';
points.forEach(p => {
const point = document.createElement('div');
point.className = 'heatmap__point';
const intensity = Math.max(0, Math.min(1, (100 + p.rssi) / 100));
point.style.opacity = intensity.toFixed(2);
point.style.left = `${(p.lng % 1) * 100}%`;
point.style.top = `${(p.lat % 1) * 100}%`;
layer.appendChild(point);
});
}
};
}
/**
* Aktualisiert die Heatmap-Daten und rendert neu.
* @param {object} heatmapInstance
* @param {Array<{lat: number, lng: number, rssi: number}>} points
*/
function updateHeatmap(heatmapInstance, points) {
heatmapInstance.data = points;
heatmapInstance.render(points);
}
/**
* Rendert einfache Statistik-Anzeige.
* @param {{min: number, max: number, avg: number}} stats
*/
function renderStats(stats) {
if (!appState.statsContainer) return;
appState.statsContainer.innerHTML = `
<p><strong>Min:</strong> ${stats.min?.toFixed(1) ?? ''} dBm</p>
<p><strong>Max:</strong> ${stats.max?.toFixed(1) ?? ''} dBm</p>
<p><strong>Ø:</strong> ${stats.avg?.toFixed(1) ?? ''} dBm</p>
`;
}
// Einstiegspunkt beim Laden
window.addEventListener('load', initApp);