wlan_sternenhimmel_ilzstausee/data_visualization/js/visualization.js

82 lines
No EOL
2.8 KiB
JavaScript

/* eslint-env browser */
/**
* Modul: visualization.js
* Rolle: render_logic
* Beschreibung: Rendering der Heatmap und Statistikaktualisierung basierend auf WLAN-Messdaten.
*/
/**
* Aktualisiert die Statistik-Seitenleiste basierend auf den aktuellen Heatmap-Daten.
* @param {Array<{location: {lat: number, lng: number}, intensity: number, rssi?: number}>} heatmap_data - Messdaten
*/
export function updateStatsPanel(heatmap_data = []) {
const statsPanel = document.getElementById('stats-panel');
if (!statsPanel || heatmap_data.length === 0) return;
// Extrahiere Signalstärken (RSSI oder intensity)
const values = heatmap_data.map(p => p.rssi ?? p.intensity).filter(v => typeof v === 'number');
if (values.length === 0) return;
const sorted = [...values].sort((a, b) => a - b);
const min = sorted[0];
const max = sorted[sorted.length - 1];
const median = sorted[Math.floor(sorted.length / 2)];
statsPanel.innerHTML = `
<h2>Signalstatistik</h2>
<ul>
<li><strong>Messpunkte:</strong> ${values.length}</li>
<li><strong>Minimum RSSI:</strong> ${min.toFixed(1)} dBm</li>
<li><strong>Maximum RSSI:</strong> ${max.toFixed(1)} dBm</li>
<li><strong>Median RSSI:</strong> ${median.toFixed(1)} dBm</li>
</ul>
`;
}
/**
* Rendert die Heatmap über der Karte.
* @param {Array<{location: {lat: number, lng: number}, intensity: number}>} heatmap_data - WLAN-Daten
*/
export function render_heatmap(heatmap_data = []) {
// Defensive: Canvas- oder Map-Element prüfen
const canvas = document.getElementById('heatmap-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
ctx.clearRect(0, 0, width, height);
// Einfache farbliche Darstellung basierend auf Intensität
heatmap_data.forEach(point => {
const { lat, lng } = point.location || {};
if (typeof lat !== 'number' || typeof lng !== 'number') return;
// Beispielkonversion: fiktives Mapping lat/lng -> Canvas-Koordinaten
const x = ((lng + 180) / 360) * width;
const y = ((90 - lat) / 180) * height;
const intensity = Math.max(0, Math.min(1, point.intensity ?? 0));
const radius = 20 + intensity * 30;
const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, `rgba(255, 0, 0, ${0.4 * intensity})`);
gradient.addColorStop(1, 'rgba(255, 0, 0, 0)');
ctx.beginPath();
ctx.fillStyle = gradient;
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fill();
});
// Statistiken nach Rendering aktualisieren
updateStatsPanel(heatmap_data);
// Accessibility-Update, z. B. für Screenreader
const liveRegion = document.getElementById('heatmap-live');
if (liveRegion) {
liveRegion.textContent = `Heatmap aktualisiert: ${heatmap_data.length} Punkte.`;
}
}
// Hinweis: Dieses Modul wird von app.refreshData aufgerufen.