/* ui.js — Verantwortlich für DOM-Manipulation und UI-Rendering */ /** * Rendert interaktive Diagramme für Umweltdaten. * @param {Array<{timestamp: string, temperature: number, wind_speed: number, humidity: number}>} data - API Response von /data */ export function renderCharts(data) { const chartContainer = document.querySelector('#data-charts'); if (!chartContainer) return; chartContainer.innerHTML = ''; if (!Array.isArray(data) || data.length === 0) { const msg = document.createElement('p'); msg.textContent = 'Keine Daten verfügbar'; chartContainer.appendChild(msg); return; } // Grundstruktur für Canvas-Diagramme const canvas = document.createElement('canvas'); canvas.setAttribute('aria-label', 'Umweltdaten Diagramm'); canvas.setAttribute('role', 'img'); chartContainer.appendChild(canvas); // Beispielhafte Nutzung von Chart.js oder ähnlicher Logik (ohne externe Ressourcen) // Zur Vereinfachung: Darstellung als einfache Linien mit Canvas API const ctx = canvas.getContext('2d'); const width = chartContainer.clientWidth; const height = 200; canvas.width = width; canvas.height = height; ctx.clearRect(0, 0, width, height); const temperatures = data.map(d => d.temperature); const winds = data.map(d => d.wind_speed); const hums = data.map(d => d.humidity); const maxTemp = Math.max(...temperatures, 1); const maxWind = Math.max(...winds, 1); const maxHum = Math.max(...hums, 1); const step = width / (data.length - 1); // Hilfsfunktion zum Zeichnen von Linien const drawLine = (values, color, maxVal) => { ctx.beginPath(); ctx.strokeStyle = color; ctx.lineWidth = 2; values.forEach((val, i) => { const x = i * step; const y = height - (val / maxVal) * height; if (i === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } }); ctx.stroke(); }; drawLine(temperatures, '#e74c3c', maxTemp); // rot für Temp drawLine(winds, '#3498db', maxWind); // blau für Wind drawLine(hums, '#2ecc71', maxHum); // grün für Luftfeuchte const legend = document.createElement('div'); legend.className = 'chart-legend'; legend.innerHTML = ` Temperatur | Wind | Feuchtigkeit `; chartContainer.appendChild(legend); } /** * Rendert eine Galerie aus Bilddaten. * @param {Array<{url: string, capture_time: string, analysis_result: string}>} images - API Response von /images */ export function renderGallery(images) { const galleryContainer = document.querySelector('#image-gallery'); if (!galleryContainer) return; galleryContainer.innerHTML = ''; if (!Array.isArray(images) || images.length === 0) { const msg = document.createElement('p'); msg.textContent = 'Keine Bilddaten verfügbar'; galleryContainer.appendChild(msg); return; } images.forEach(imgData => { const wrapper = document.createElement('div'); wrapper.className = 'gallery-item'; const figure = document.createElement('figure'); const thumb = document.createElement('div'); thumb.className = 'image-thumb'; thumb.tabIndex = 0; thumb.setAttribute('role', 'button'); thumb.setAttribute('aria-label', `Bild aufgenommen am ${imgData.capture_time}`); // Bilddarstellung über CSS background-image, da keine externen Bilddateien verwendet werden dürfen thumb.style.background = '#ccc'; // Platzhalter, da keine echten Bilder geladen werden dürfen const caption = document.createElement('figcaption'); caption.textContent = `${imgData.capture_time} – ${imgData.analysis_result}`; figure.appendChild(thumb); figure.appendChild(caption); wrapper.appendChild(figure); galleryContainer.appendChild(wrapper); // Interaktive Zoomfunktion (nur symbolisch) thumb.addEventListener('click', () => { const expanded = document.createElement('div'); expanded.className = 'overlay'; expanded.setAttribute('role', 'dialog'); expanded.setAttribute('aria-modal', 'true'); const expandedContent = document.createElement('div'); expandedContent.className = 'overlay-content'; expandedContent.style.background = '#999'; // Platzhalter für Zoom-Bild const closeBtn = document.createElement('button'); closeBtn.textContent = 'Schließen'; closeBtn.className = 'close-button'; closeBtn.addEventListener('click', () => expanded.remove()); expanded.appendChild(expandedContent); expanded.appendChild(closeBtn); document.body.appendChild(expanded); }); }); }