/** * MYP Platform Chart-Adapter * Verbindet bestehende API/Logik mit ApexCharts * Version: 1.0.0 */ /** * Überbrückt die bestehende renderChart Funktion mit der neuen ApexCharts Implementation * @param {HTMLElement} container - Der Diagramm-Container * @param {Object} data - Die Diagrammdaten vom API-Endpunkt */ function renderChart(container, data) { // Überprüfen, ob die Daten vorhanden sind if (!data || (Array.isArray(data) && data.length === 0) || Object.keys(data).length === 0) { showEmptyState(container, 'Keine Daten', 'Es sind keine Daten für dieses Diagramm verfügbar.'); return; } // Container-ID überprüfen und ggf. generieren if (!container.id) { container.id = 'chart-' + Math.random().toString(36).substr(2, 9); } // Chart-Typ basierend auf Container-ID oder Attributen bestimmen let chartType = container.getAttribute('data-chart-type'); if (!chartType) { if (container.id === 'job-status-chart') { chartType = 'pie'; container.setAttribute('data-chart-type', 'pie'); } else if (container.id === 'printer-usage-chart') { chartType = 'bar'; container.setAttribute('data-chart-type', 'bar'); } else if (container.id.includes('line')) { chartType = 'line'; container.setAttribute('data-chart-type', 'line'); } else if (container.id.includes('area')) { chartType = 'area'; container.setAttribute('data-chart-type', 'area'); } else if (container.id.includes('bar')) { chartType = 'bar'; container.setAttribute('data-chart-type', 'bar'); } else if (container.id.includes('pie')) { chartType = 'pie'; container.setAttribute('data-chart-type', 'pie'); } else if (container.id.includes('donut')) { chartType = 'donut'; container.setAttribute('data-chart-type', 'donut'); } else { // Standard-Typ chartType = 'line'; container.setAttribute('data-chart-type', 'line'); } } // Daten für das Diagramm vorbereiten let chartData = {}; // Daten-Transformation basierend auf Container-ID if (container.id === 'job-status-chart') { chartData = transformJobStatusData(data); } else if (container.id === 'printer-usage-chart') { chartData = transformPrinterUsageData(data); } else { // Generischer Ansatz für andere Diagrammtypen chartData = transformGenericData(data, chartType); } // Existierendes Chart zerstören, falls vorhanden if (activeCharts[container.id]) { destroyChart(container.id); } // Daten als Attribut am Container speichern container.setAttribute('data-chart-data', JSON.stringify(chartData)); // Neues Chart erstellen createChart(container, chartType, chartData); } /** * Transformiert Job-Status-Daten für Pie-Chart * @param {Object} data - Rohdaten vom API-Endpunkt * @returns {Object} - Formatierte Daten für ApexCharts */ function transformJobStatusData(data) { // Werte für Pie-Chart extrahieren const series = [ data.scheduled || 0, data.active || 0, data.completed || 0, data.cancelled || 0 ]; // Labels für die Diagramm-Segmente const labels = ['Geplant', 'Aktiv', 'Abgeschlossen', 'Abgebrochen']; // Benutzerdefinierte Farben const colors = [ MYP_CHART_COLORS.info, // Blau für geplant MYP_CHART_COLORS.primary, // Primär für aktiv MYP_CHART_COLORS.success, // Grün für abgeschlossen MYP_CHART_COLORS.warning // Gelb für abgebrochen ]; // Zusätzliche Optionen const options = { colors: colors, chart: { height: 320 }, plotOptions: { pie: { donut: { size: '0%' // Vollständiger Kreis (kein Donut) } } }, legend: { position: 'bottom' } }; return { series: series, labels: labels, options: options }; } /** * Transformiert Drucker-Nutzungsdaten für Bar-Chart * @param {Object} data - Rohdaten vom API-Endpunkt * @returns {Object} - Formatierte Daten für ApexCharts */ function transformPrinterUsageData(data) { // Prüfen, ob Daten ein Array sind if (!Array.isArray(data)) { console.error('Drucker-Nutzungsdaten müssen ein Array sein:', data); return { series: [], categories: [], options: {} }; } // Druckernamen für X-Achse extrahieren const categories = data.map(item => item.printer_name || 'Unbekannt'); // Datenreihen für Jobs und Stunden erstellen const jobsSeries = { name: 'Jobs', data: data.map(item => item.job_count || 0) }; const hoursSeries = { name: 'Stunden', data: data.map(item => Math.round((item.print_hours || 0) * 10) / 10) }; // Zusätzliche Optionen const options = { colors: [MYP_CHART_COLORS.primary, MYP_CHART_COLORS.success], chart: { height: 320 }, plotOptions: { bar: { horizontal: false, columnWidth: '60%', borderRadius: 4 } }, dataLabels: { enabled: false }, xaxis: { categories: categories } }; return { series: [jobsSeries, hoursSeries], categories: categories, options: options }; } /** * Transformiert generische Daten für verschiedene Diagrammtypen * @param {Object|Array} data - Rohdaten vom API-Endpunkt * @param {string} chartType - Art des Diagramms * @returns {Object} - Formatierte Daten für ApexCharts */ function transformGenericData(data, chartType) { // Standard-Ergebnisobjekt const result = { series: [], categories: [], labels: [], options: {} }; // Arrays verarbeiten if (Array.isArray(data)) { if (chartType === 'pie' || chartType === 'donut' || chartType === 'radial') { // Für Kreisdiagramme result.series = data.map(item => item.value || 0); result.labels = data.map(item => item.name || item.label || 'Unbekannt'); } else { // Für Linien-, Flächen- und Balkendiagramme // Annahme: Erste Datenreihe result.series = [{ name: 'Werte', data: data.map(item => item.value || 0) }]; result.categories = data.map(item => item.name || item.label || item.date || 'Unbekannt'); } } // Objekte mit Datenreihen verarbeiten else if (data.series && Array.isArray(data.series)) { result.series = data.series; if (data.categories) { result.categories = data.categories; } if (data.labels) { result.labels = data.labels; } if (data.options) { result.options = data.options; } } // Einfache Objekte verarbeiten else { // Für Kreisdiagramme: Alle Eigenschaften als Segmente verwenden if (chartType === 'pie' || chartType === 'donut' || chartType === 'radial') { const seriesData = []; const labelData = []; Object.keys(data).forEach(key => { if (typeof data[key] === 'number') { seriesData.push(data[key]); labelData.push(key); } }); result.series = seriesData; result.labels = labelData; } // Für andere Diagrammtypen: Versuchen, Zeit-/Wertepaare zu finden else { const timeKeys = []; const values = []; Object.keys(data).forEach(key => { if (typeof data[key] === 'number') { timeKeys.push(key); values.push(data[key]); } }); result.series = [{ name: 'Werte', data: values }]; result.categories = timeKeys; } } return result; } /** * Zeigt einen leeren Status-Container an * @param {HTMLElement} container - Der Diagramm-Container * @param {string} title - Titel der Meldung * @param {string} message - Meldungstext */ function showEmptyState(container, title, message) { container.innerHTML = `
${message}