'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 = `
Min: ${stats.min?.toFixed(1) ?? '–'} dBm
Max: ${stats.max?.toFixed(1) ?? '–'} dBm
Ø: ${stats.avg?.toFixed(1) ?? '–'} dBm
`; } // Einstiegspunkt beim Laden window.addEventListener('load', initApp);