Add data_visualization/js/chartRenderer.js

This commit is contained in:
Mika 2026-01-18 16:37:00 +00:00
parent 3dfa8d1208
commit a36a0210db

View file

@ -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<Object>} 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<Object>} 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<Object>} 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 };
})();