From a36a0210dba4198c118b1642e83901a1707caea2 Mon Sep 17 00:00:00 2001 From: Mika Date: Sun, 18 Jan 2026 16:37:00 +0000 Subject: [PATCH] Add data_visualization/js/chartRenderer.js --- data_visualization/js/chartRenderer.js | 137 +++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 data_visualization/js/chartRenderer.js diff --git a/data_visualization/js/chartRenderer.js b/data_visualization/js/chartRenderer.js new file mode 100644 index 0000000..aca4ae6 --- /dev/null +++ b/data_visualization/js/chartRenderer.js @@ -0,0 +1,137 @@ +(() => { + /** + * chartRenderer.js + * Visualization layer rendering measurement data charts. + * Uses Chart.js (assumed pre-loaded in the environment) + * Handles rendering and updating of multiple measurement charts. + */ + + let charts = {}; + + /** + * Converts measurement data into Chart.js datasets + * @param {Array} data - filtered measurement records + * @returns {Object} datasets and labels for Chart.js + */ + const prepareDatasets = (data) => { + if (!Array.isArray(data)) return { labels: [], datasets: [] }; + const labels = data.map(d => new Date(d.timestamp).toLocaleTimeString()); + + const temperatureData = data.map(d => d.temperature); + const humidityData = data.map(d => d.humidity); + const brightnessData = data.map(d => d.brightness); + + return { + labels, + datasets: [ + { + label: 'Temperatur (°C)', + data: temperatureData, + borderColor: 'rgba(255, 99, 132, 1)', + backgroundColor: 'rgba(255, 99, 132, 0.2)', + tension: 0.3, + yAxisID: 'y', + }, + { + label: 'Luftfeuchte (%)', + data: humidityData, + borderColor: 'rgba(54, 162, 235, 1)', + backgroundColor: 'rgba(54, 162, 235, 0.2)', + tension: 0.3, + yAxisID: 'y1', + }, + { + label: 'Signalintensität', + data: brightnessData, + borderColor: 'rgba(75, 192, 192, 1)', + backgroundColor: 'rgba(75, 192, 192, 0.2)', + tension: 0.3, + yAxisID: 'y', + } + ] + }; + }; + + /** + * renderCharts + * Visualizes data in line charts and appends them into the .chart-panel. + * @param {Array} data - filtered measurement data + */ + const renderCharts = (data) => { + const chartPanel = document.querySelector('.chart-panel'); + if (!chartPanel) return; + + chartPanel.innerHTML = ''; + + const canvas = document.createElement('canvas'); + canvas.setAttribute('aria-label', 'Messdaten Diagramm'); + canvas.setAttribute('role', 'img'); + chartPanel.appendChild(canvas); + + const ctx = canvas.getContext('2d'); + const { labels, datasets } = prepareDatasets(data); + + const config = { + type: 'line', + data: { labels, datasets }, + options: { + responsive: true, + interaction: { mode: 'index', intersect: false }, + stacked: false, + plugins: { + tooltip: { + enabled: true, + callbacks: { + title: (items) => items[0]?.label || '', + label: (item) => `${item.dataset.label}: ${item.formattedValue}` + } + }, + legend: { labels: { color: '#eee' } }, + }, + scales: { + y: { + type: 'linear', + display: true, + position: 'left', + title: { display: true, text: 'Temperatur / Intensität' }, + ticks: { color: '#ccc' } + }, + y1: { + type: 'linear', + display: true, + position: 'right', + grid: { drawOnChartArea: false }, + title: { display: true, text: 'Luftfeuchte' }, + ticks: { color: '#ccc' } + }, + x: { + ticks: { color: '#ccc' } + } + } + } + }; + + charts.main = new Chart(ctx, config); + }; + + /** + * updateChart + * Updates existing chart data and re-renders with new dataset. + * @param {Array} newData - new or filtered measurement data + */ + const updateChart = (newData) => { + if (!charts.main) { + renderCharts(newData); + return; + } + + const { labels, datasets } = prepareDatasets(newData); + + charts.main.data.labels = labels; + charts.main.data.datasets = datasets; + charts.main.update('active'); + }; + + // Expose functions globally + window.chartRenderer = { renderCharts, updateChart }; +})(); \ No newline at end of file