122 lines
No EOL
3.6 KiB
JavaScript
122 lines
No EOL
3.6 KiB
JavaScript
'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); |