Add data_visualization/js/visualization.js
This commit is contained in:
parent
556f2e22ff
commit
3b8fdf526b
1 changed files with 82 additions and 0 deletions
82
data_visualization/js/visualization.js
Normal file
82
data_visualization/js/visualization.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/* 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.
|
||||
Loading…
Reference in a new issue