Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Visualisierung
    4. neue Visualisierung "webui" (alternative zu vis & vis-2)

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    neue Visualisierung "webui" (alternative zu vis & vis-2)

    This topic has been deleted. Only users with topic management privileges can see it.
    • Smilie108
      Smilie108 @jogibear9988 last edited by

      @jogibear9988
      mal ne frage bei den bindables / locals kannst du da auch eine remove funktion hinzufügen ? um variabeln wiedr zu entfernen oder eventuell auch etwas zum umbenennen ? 😉

      gruß tom

      jogibear9988 1 Reply Last reply Reply Quote 0
      • jogibear9988
        jogibear9988 @Smilie108 last edited by

        @smilie108

        Wo was entfernen? Locale variablen sind weg wenn du den browser neu lädst und die nirgends verwendet sind

        1 Reply Last reply Reply Quote 0
        • K
          Kamikaze last edited by

          Jetzt ist es wieder an der Zeit, die Experten zu fragen:
          Ich habe mit chart.js mir ein Klasse geschrieben, die mir meine notwendigen Daten in Grafiken umsetzt. Das Ganze habe ich mit rein Javascript gemacht.
          Hierzu eine Index.html erstellt:

          <!DOCTYPE html>
          <html lang="de">
          
          <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Energieverbrauchs-Diagramm</title>
            <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
            <script src="js/chartBuilder.js"></script>
            <link rel="stylesheet" href="index.css">
          </head>
          
          <body>
            <div id="chartContainer">
              <div>
                <canvas id="houseYearlyChart"></canvas>
                <div class="legend" id="houseYearlyChartLegend"></div> <!-- Container für die Legende -->
              </div>
              <div>
                <canvas id="roomYearlyChart"></canvas>
                <div class="legend" id="roomYearlyChartLegend"></div> <!-- Container für die Legende -->
              </div>
              <div>
                <canvas id="roomMonthlyChart"></canvas>
                <div class="legend" id="roomMonthlyChartLegend"></div> <!-- Container für die Legende -->
              </div>
              <div>
                <canvas id="grossesDiagramm"></canvas>
                <div class="grossesDiagrammLegend" id="grossesDiagrammLegend"></div> <!-- Container für die Legende -->
              </div>
              <div>
                <canvas id="grossesDiagrammX"></canvas>
                <div class="grossesDiagrammLegend" id="grossesDiagrammXLegend"></div> <!-- Container für die Legende -->
              </div>
          
            </div>
          
            <script src="index.js"> </script>
             
          </body>
          
          </html>
          

          Chart.js als Script-Tag eingebaut, <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
          Meine Klasse hinzugefügt und ein kleines index.js zur Konfiguration der Grafik.

          const diagrammBasiswerte = {
              titlecolor: '#ffffff',
              fontsize: 12, // Schriftgröße: 12px
              fontfamily: 'Arial', // Schriftart: Arial
              fontstyle: 'italic', // Schriftstil: kursiv
              fontweight: 'bold', // Schriftgewicht: fett
              fontcolor: '#ffffff',
              maxRotation: 0,
              minRotation: 0,
          }
          
          
          const diagramConfigs = {
              houseYearlyChart: {
                  chartjs_typ: 'bar', // bar oder line
                  chartType: 'yearlyChart', // yearlyChart oder dailyChart
                  datatype: 'absoluteValue', // 'absoluteValue' oder 'Counter' 
                  year: '2025', // Jahr aus der Konfiguration
                  month: '', // Nicht erforderlich für yearlyChart
                  threshold: 30,
                  showLegend: true, // Tabelle mit Legende 
                  showPoints: false, // Punkte ausblenden
                  devices: JSON.stringify([   // Geräte
                      { id: '7', name: 'Isttemperatur', type: 'absoluteValue', unit: '°C', normalizationFactor: 1, color: '#0000FF' },
                  ]),
                  options: {
                      datumsformat: { month: 'short' }, // --> 01.Jan.2024 { day: '2-digit', month: 'short', year: 'numeric' }
                      threshold: { label: 'Threshold', type: 'line', borderColor: '#FF0000', borderWidth: 4, fill: false, pointRadius: 0 },
                      durchschnitt: { label: 'Durchschnitt', type: 'line', borderColor: '#FFFFFF', borderWidth: 2, fill: false, pointRadius: 0 },
                      scales: {
                          x: {
                              title: { display: true, text: `Zeitraum 2024`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  maxRotation: diagrammBasiswerte.maxRotation,
                                  minRotation: diagrammBasiswerte.minRotation,
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                          y: {
                              title: { display: true, text: `Temperatur (°C)`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                      },
                  },
              },
              roomYearlyChart: {
                  chartjs_typ: 'bar',
                  chartType: 'yearlyChart',
                  datatype: 'Counter', // 'absoluteValue' oder 'Counter' 
                  year: '2024', // Jahr aus der Konfiguration
                  month: '', // Nicht erforderlich für yearlyChart
                  threshold: 300,
                  showLegend: true,
                  showPoints: true, // Punkte einblenden
                  devices: JSON.stringify([
                      { id: '36', name: 'ac_energie', type: 'Counter', unit: 'kWh', normalizationFactor: 1000, color: '#00FF00' },
                      { id: '41', name: 'ac_energie_gesamt', type: 'Counter', unit: 'kWh', normalizationFactor: 1000, color: '#FFA500' },
                  ]),
                  options: {
                      datumsformat: { month: 'short' }, // --> 01.Jan.2024 { day: '2-digit', month: 'short', year: 'numeric' }
                      threshold: { label: 'Threshold', type: 'line', borderColor: '#FF0000', borderWidth: 4, fill: false, pointRadius: 0 },
                      durchschnitt: { label: 'Durchschnitt', type: 'line', borderColor: '#FFFFFF', borderWidth: 2, fill: false, pointRadius: 0 },
                      scales: {
                          x: {
                              title: { display: true, text: `Zeitraum 2024`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  maxRotation: diagrammBasiswerte.maxRotation,
                                  minRotation: diagrammBasiswerte.minRotation,
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                          y: {
                              title: { display: true, text: `Energie (kWh)`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                      },
                  },
              },
              roomMonthlyChart: {
                  chartjs_typ: 'bar',
                  chartType: 'dailyChart',
                  datatype: 'Counter', // 'absoluteValue' oder 'Counter' 
                  year: '2025', // Jahr aus der Konfiguration
                  month: '3', // Monat für dailyChart
                  threshold: 10,
                  showLegend: true,
                  showPoints: true, // Punkte einblenden
                  devices: JSON.stringify([
                      { id: '41', name: 'ac_energie_gesamt', type: 'Counter', unit: 'kWh', normalizationFactor: 1000, color: '#FFFF00' },
                      { id: '36', name: 'ac_energie', type: 'Counter', unit: 'kWh', normalizationFactor: 1000, color: '#FF00FF' },
                  ]),
                  options: {
                      datumsformat: { day: '2-digit', month: 'short' }, // --> 01.Apr
                      threshold: { label: 'Threshold', type: 'line', borderColor: '#FF0000', borderWidth: 4, fill: false, pointRadius: 0 },
                      durchschnitt: { label: 'Durchschnitt', type: 'line', borderColor: '#FFFFFF', borderWidth: 2, fill: false, pointRadius: 0 },
                      scales: {
                          x: {
                              title: { display: true, text: `Zeitraum 2025`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  maxRotation: diagrammBasiswerte.maxRotation,
                                  minRotation: diagrammBasiswerte.minRotation,
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                          y: {
                              title: { display: true, text: `Energie (kWh)`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                      },
                  },
              },
              grossesDiagramm: {
                  chartjs_typ: 'line', // bar oder line
                  chartType: 'yearlyChart', // yearlyChart oder dailyChart
                  datatype: 'Counter', // 'absoluteValue' oder 'Counter' 
                  year: '2025', // Jahr aus der Konfiguration
                  month: '', // Nicht erforderlich für yearlyChart
                  threshold: 25,
                  showLegend: true, // Tabelle mit Legende 
                  showPoints: true, // Punkte ausblenden
                  devices: JSON.stringify([   // Geräte
                      { id: '41', name: 'ac_energie_gesamt', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#0000FF' },
                      { id: '21', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FF0000' },
                      { id: '22', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FFFF00' },
                      { id: '23', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#000000' },
                      { id: '24', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FF00FF' },
                      { id: '25', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FFFFFF' },
          
          
                  ]),
                  options: {
                      datumsformat: { month: 'short' }, // --> 01.Jan.2024 { day: '2-digit', month: 'short', year: 'numeric' }
                      threshold: { label: 'Threshold', type: 'line', borderColor: '#FF0000', borderWidth: 4, fill: false, pointRadius: 0 },
                      durchschnitt: { label: 'Durchschnitt', type: 'line', borderColor: '#FFFFFF', borderWidth: 2, fill: false, pointRadius: 0 },
                      scales: {
                          x: {
                              title: { display: true, text: `Zeitraum 2024`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  maxRotation: diagrammBasiswerte.maxRotation,
                                  minRotation: diagrammBasiswerte.minRotation,
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                          y: {
                              title: { display: true, text: `Temperatur (°C)`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                      },
                  },
              },
              grossesDiagrammX: {
                  chartjs_typ: 'line', // bar oder line
                  chartType: 'yearlyChart', // yearlyChart oder dailyChart
                  datatype: 'Counter', // 'absoluteValue' oder 'Counter' 
                  year: '2024', // Jahr aus der Konfiguration
                  month: '', // Nicht erforderlich für yearlyChart
                  threshold: 25,
                  showLegend: true, // Tabelle mit Legende 
                  showPoints: true, // Punkte ausblenden
                  devices: JSON.stringify([   // Geräte
                      { id: '26', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#0000FF' },
                      { id: '27', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FF0000' },
                      { id: '28', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FFFF00' },
                      { id: '29', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#000000' },
                      { id: '30', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FF00FF' },
                      { id: '31', name: 'ac_energie', type: 'Counter', unit: '°C', normalizationFactor: 1, color: '#FFFFFF' },
                  ]),
                  options: {
                      datumsformat: { month: 'short' }, // --> 01.Jan.2024 { day: '2-digit', month: 'short', year: 'numeric' }
                      threshold: { label: 'Threshold', type: 'line', borderColor: '#FF0000', borderWidth: 4, fill: false, pointRadius: 0 },
                      durchschnitt: { label: 'Durchschnitt', type: 'line', borderColor: '#FFFFFF', borderWidth: 2, fill: false, pointRadius: 0 },
                      scales: {
                          x: {
                              title: { display: true, text: `Zeitraum 2024`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  maxRotation: diagrammBasiswerte.maxRotation,
                                  minRotation: diagrammBasiswerte.minRotation,
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                          y: {
                              title: { display: true, text: `Temperatur (°C)`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                      },
                  },
              },
          };
          
          // Diagramme erstellen und Daten laden
          Object.keys(diagramConfigs).forEach((chartId) => {
              const config = diagramConfigs[chartId];
              const apiUrl = `/api/sqlData?devices=${encodeURIComponent(config.devices)}&year=${config.year}&chartType=${config.chartType}${config.chartType === 'dailyChart' ? `&month=${config.month}` : ''}`;
          
              fetch(apiUrl)
                  .then((response) => {
                      if (!response.ok) throw new Error(`Fehler: ${response.statusText}`);
                      return response.json();
                  })
                  .then((data) => {
                      const chartBuilder = new ChartBuilder(chartId, `${chartId}Legend`);
                      chartBuilder.create(config.chartjs_typ, config.datatype, data, config.showLegend, config.threshold, config.showPoints, config.year, config.options);
                  })
                  .catch((error) => console.error(`Fehler beim Laden des Diagramms ${chartId}:`, error));
          });
          

          Jetzt die Frage an die Experten:
          Wo und wie binde ich die externen Elemente in webui ein.
          <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
          <script src="js/chartBuilder.js"></script>

          Meine Klasse habe ich als Beispiel einfach im Javascript-Teil des Controls mit eingebunden. Das geht auch bestimmt anders.
          Aber wie ich das mit chart.js mache erschließt sich mir nicht. Ich erhalte immer die Meldung, dass Chart nicht existiert.

          <script src="http://192.168.110.10:8082/webui.0.data/config/additionalfiles/chart.js"></script>
          <div id="chartContainer" style="position:absolute;left:97px;top:26px;width:476px;height:170px;">
              <div>
                  <canvas id="YearlyChart"></canvas>
                  <div class="legend" id="YearlyChartLegend"></div>
              </div>
              <script src="http://192.168.110.10:8082/webui.0.widgets/importmap.js"></script>
          </div>
          

          Hier noch das javascript-Modul

          /**
          * @param {BaseScreenViewerAndControl} instance
          */
          
          const diagrammBasiswerte = {
              titlecolor: '#ffffff',
              fontsize: 12, // Schriftgröße: 12px
              fontfamily: 'Arial', // Schriftart: Arial
              fontstyle: 'italic', // Schriftstil: kursiv
              fontweight: 'bold', // Schriftgewicht: fett
              fontcolor: '#ffffff',
              maxRotation: 0,
              minRotation: 0,
          }
          
          const diagramConfigs = {
              YearlyChart: {
                  chartjs_typ: 'bar', // bar oder line
                  chartType: 'yearlyChart', // yearlyChart oder dailyChart
                  datatype: 'absoluteValue', // 'absoluteValue' oder 'Counter' 
                  year: '2025', // Jahr aus der Konfiguration
                  month: '', // Nicht erforderlich für yearlyChart
                  threshold: 30,
                  showLegend: true, // Tabelle mit Legende 
                  showPoints: false, // Punkte ausblenden
                  devices: JSON.stringify([   // Geräte
                      { id: '7', name: 'Isttemperatur', type: 'absoluteValue', unit: '°C', normalizationFactor: 1, color: '#0000FF' },
                  ]),
                  options: {
                      datumsformat: { month: 'short' }, // --> 01.Jan.2024 { day: '2-digit', month: 'short', year: 'numeric' }
                      threshold: { label: 'Threshold', type: 'line', borderColor: '#FF0000', borderWidth: 4, fill: false, pointRadius: 0 },
                      durchschnitt: { label: 'Durchschnitt', type: 'line', borderColor: '#FFFFFF', borderWidth: 2, fill: false, pointRadius: 0 },
                      scales: {
                          x: {
                              title: { display: true, text: `Zeitraum 2024`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  maxRotation: diagrammBasiswerte.maxRotation,
                                  minRotation: diagrammBasiswerte.minRotation,
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                          y: {
                              title: { display: true, text: `Temperatur (°C)`, color: diagrammBasiswerte.titlecolor },
                              ticks: {
                                  font: {
                                      size: diagrammBasiswerte.fontsize,
                                      family: diagrammBasiswerte.fontfamily,
                                      style: diagrammBasiswerte.fontstyle,
                                      weight: diagrammBasiswerte.fontweight,
                                  },
                                  color: diagrammBasiswerte.fontcolor,
                              },
                          },
                      },
                  },
              },
          };
          
          export function init(instance,shadowRoot) {
              console.log(instance);
              console.log(shadowRoot);
              console.log(instance.query);
              const cssid = instance._getDomElement('chartContainer');
              console.log(cssid);
              instance.query = "Ich bin blöd";
              console.log(instance.query);
              IOB.setState('0_userdata.0.Funktionen.DatabaseQuery',instance.query);
              const result2 = instance.result;
              console.log(result2);
              const result = IOB.getState('0_userdata.0.Funktionen.DatabaseResult');
              console.log(JSON.stringify(instance,null,2));
              Object.keys(diagramConfigs).forEach((chartId) => {
                 const config = diagramConfigs[chartId];
                 const data=instance.result
                 const chartBuilder = new ChartBuilder(chartId, `${chartId}Legend`,instance);
                 chartBuilder.create(instance,config.chartjs_typ, config.datatype, data, config.showLegend, config.threshold, config.showPoints, config.year, config.options);
              });
          }
          
          class ChartBuilder {
              constructor(canvasId, legendId,instance) {
                  this.ctx = instance._getDomElement(canvasId).getContext('2d');
                  // this.ctx = document.getElementById(canvasId).getContext('2d');
                  this.chartInstance = null;
                  this.legendId = legendId;
              }
          
              create(instance,chartjs_typ, datatype, data, showLegend, threshold, showPoints, year, options = {}) {
                  this.renderChart(instance,chartjs_typ,datatype, data, showLegend, threshold, showPoints, year, options);
              }
          
              renderChart(instance,chartjs_typ, datatype, data, showLegend, threshold, showPoints, year, options) {
                  if (this.chartInstance) this.chartInstance.destroy();
          
                  const legendContainer = instance._getDomElement(this.legendId);
                  // const legendContainer = document.getElementById(this.legendId);
                  if (!legendContainer) {
                      console.error(`Legenden-Element mit ID "${this.legendId}" nicht gefunden.`);
                      return;
                  }
                  legendContainer.style.display = showLegend ? 'block' : 'none';
                  legendContainer.innerHTML = ''; // Reset legend
          
                  const labels = [...new Set(data.map((entry) => {
                      const formattedDate = new Date(entry.period).toLocaleDateString('de-DE', options.datumsformat);
                      if (isNaN(new Date(entry.period).getTime())) {
                          console.error(`Invalid Date: ${entry.period}`); // Debugging für fehlerhafte Werte
                      }
                      return formattedDate;
                  }))];
          
                  // Daten nach Geräten gruppieren
                  const deviceData = {};
                  const statistics = {};
          
                  data.forEach((entry) => {
                      if (!deviceData[entry.device_id]) {
                          deviceData[entry.device_id] = {
                              label: entry.device_name || 'Unbekanntes Gerät',
                              unit: entry.unit || 'Einheit unbekannt',
                              color: entry.color || '#000000',
                              data: Array(labels.length).fill(0),
                              backgroundColor: entry.color,
                              borderColor: entry.color,
                              fill: false,
                              pointRadius: showPoints ? 5 : 0,
                          };
          
                          // Statistikinitialisierung
                          statistics[entry.device_id] = {
                              total: 0,
                              count: 0,
                              max: -Infinity,
                              min: Infinity,
                          };
                      }
          
                      // Datenwerte für das Dataset hinzufügen
                      const index = labels.indexOf(new Date(entry.period).toLocaleDateString('de-DE', options.datumsformat));
                      if (index >= 0) {
                          const normalizedValue = datatype === 'absoluteValue' ? entry.average_value / entry.normalizationFactor : entry.total_value / entry.normalizationFactor; // Differenziere Werte basierend auf Diagrammtyp
                          deviceData[entry.device_id].data[index] = normalizedValue;
          
                          // Statistik berechnen
                          statistics[entry.device_id].total += normalizedValue;
                          statistics[entry.device_id].count += 1;
                          statistics[entry.device_id].max = Math.max(statistics[entry.device_id].max, normalizedValue);
                          statistics[entry.device_id].min = Math.min(statistics[entry.device_id].min, normalizedValue);
                      }
                  });
          
                  // Durchschnittslinien und Threshold als Linien-Datensätze
                  const averageData = Array(labels.length).fill(
                      Object.keys(statistics).reduce((avg, deviceId) => avg + (statistics[deviceId].total / statistics[deviceId].count || 0), 0) / Object.keys(statistics).length
                  );
                  const thresholdData = Array(labels.length).fill(threshold);
          
                  // Wenn es sich um ein Balkendiagramm handelt, werden Durchschnitt und Threshold als Linien dargestellt
                  const additionalDatasets = (chartjs_typ === 'bar' || chartjs_typ === 'line')
                      ? [
                          {
                              label: options.threshold?.label  ||  'Threshold',
                              data: thresholdData,
                              type: options.threshold?.type  ||  'line', // Linie für Threshold im Balkendiagramm
                              borderColor: options.threshold?.borderColor  ||  '#FF0000',
                              borderWidth: options.threshold?.borderWidth  ||  2,
                              fill: options.threshold?.fill  ||  false,
                              pointRadius: options.threshold?.pointRadius  ||  0,
                          },
                          {
                              label: options.durchschnitt?.label || 'Durchschnitt',
                              data: averageData,
                              type: options.durchschnitt?.type || 'line', // Linie für Durchschnitt im Balkendiagramm
                              borderColor: options.durchschnitt?.borderColor || '#0000FF',
                              borderWidth: options.durchschnitt?.borderWidth || 2,
                              fill: options.durchschnitt?.label || false,
                              pointRadius: options.durchschnitt?.pointRadius || 0,
                          },
                      ]
                      : [];
          
                  const datasets = [
                      ...Object.values(deviceData),
                      ...additionalDatasets, // Linien für Balkendiagramme hinzufügen
                  ];
          
                  this.chartInstance = new Chart(this.ctx, {
                      type: chartjs_typ,
                      data: { labels, datasets },
                      options: {
                          ...options,
                          responsive: true,
                          plugins: {
                              legend: { display: false }, // Deaktiviere interne Diagrammlegende vollständig
                          },
                          scales: {
                              x: {
                                  
                                  ticks: {
                                      callback: function(value, index, ticks) {
                                          // Verwende die `labels`-Variable direkt in der Callback-Funktion
                                          const date = labels[index];
                                          return date || 'Invalid Date'; // Fallback für fehlerhafte Werte
                                      },
                                  },
                                  ...options.scales?.x, // Nutze die angepassten X-Achsenoptionen aus der index.html
                              },
                              y: options.scales?.y || {
                                  title: { display: true, text: `Werte (${deviceData[Object.keys(deviceData)[0]].unit})` },
                                  ticks: {
                                      font: {
                                          size: 24,
                                          family: 'Arial, sans-serif',
                                          weight: 'normal',
                                      },
                                      color: '#ffffff',
                                  },
                              },
                          },
                      },
                  });
          
                  // Tabellarische Legende
                  legendContainer.innerHTML = `
                  <table style="width:100%; border-collapse:collapse;">
                    <tr style="background-color:#f4f4f4; text-align:left;">
                      <th>Gerät</th>
                      <th>Farbe</th>
                      <th>Durchschnitt</th>
                      <th>Maximum</th>
                      <th>Minimum</th>
                    </tr>
                    ${Object.keys(deviceData).map(deviceId => `
                      <tr>
                        <td>${deviceData[deviceId].label}</td>
                        <td style="background-color:${deviceData[deviceId].color};"></td>
                        <td>${(statistics[deviceId].total / statistics[deviceId].count).toFixed(2)} ${deviceData[deviceId].unit}</td>
                        <td>${statistics[deviceId].max.toFixed(2)} ${deviceData[deviceId].unit}</td>
                        <td>${statistics[deviceId].min.toFixed(2)} ${deviceData[deviceId].unit}</td>
                      </tr>
                    `).join('')}
                  </table>
                `;
              }
          }
          

          In der Zeile 193 (this.chartInstance = new Chart(this.ctx, {) steigt das Programm aus, mit der Meldung: Chart existiert nicht.

          1 Reply Last reply Reply Quote 0
          • jogibear9988
            jogibear9988 last edited by jogibear9988

            Willst du chartjs von jsdeliver einbinden? Dann wird immer aufs internet zugeriffen wenn du deine Seite öffnest.

            Füg am besten meine chartjs webcomponente hinzu, die ist auch im Beispiuel server:
            http://129.159.205.3:8082/webui/index.html

            Dann solltest du chartjs direkt via: "await importShim("chart.js")" nutzen können.
            Aber du kannst natürlich auch direkt meine Komponente nutzen

            1 Reply Last reply Reply Quote 0
            • jogibear9988
              jogibear9988 last edited by

              32f60abc-2c50-467f-9078-b0ebf39112d6-image.png

              (wenn meine Webcomponente hinzugefügt wurde)

              1 Reply Last reply Reply Quote 0
              • jogibear9988
                jogibear9988 last edited by

                Bspw so:

                8c366f59-dbdd-4944-b482-7e9136271c15-image.png

                1 Reply Last reply Reply Quote 0
                • jogibear9988
                  jogibear9988 last edited by

                  Kann sein, das auch "import" statt "importShim" funktioniert. Kann gerade nur in den dev tools testen. Dort geht nur import, da das script nicht über es-module-shims ausgeführt werden.

                  Warum importShim? Weil die browser im Moment noch keine dynamischen importmaps supporten, und auch weil sie noch keine importmaps in extra files erlauben: https://github.com/guybedford/es-module-shims

                  K 1 Reply Last reply Reply Quote 0
                  • K
                    Kamikaze @jogibear9988 last edited by

                    @jogibear9988 Hallo Jogibear,
                    ich musste tatsächlich schmunzeln.

                    1. Vielen Dank für deine Lösung. Das hat gut funktioniert.
                    2. Du hast aber meine Frage nicht beantwortet.
                      Wie würde ich solchen Dinge einbinden, wenn es kein npm-Modul gibt? Insbesondere meine eigenen Klasse?
                      <script src="js/chartBuilder.js"></script>
                    jogibear9988 1 Reply Last reply Reply Quote 0
                    • jogibear9988
                      jogibear9988 @Kamikaze last edited by

                      @kamikaze

                      hochladen der scripte bspw in additional files.

                      und in der webui unter global/settings:

                      1dd3d63d-d2bd-4f94-9050-34914cdcdc5b-image.png

                      1 Reply Last reply Reply Quote 0
                      • jogibear9988
                        jogibear9988 last edited by

                        Alles was dort einfügst wird im head hinzugefügt

                        K 1 Reply Last reply Reply Quote 0
                        • K
                          Kamikaze @jogibear9988 last edited by

                          @jogibear9988 Danke schön. Jetzt habe ich alles, was ich brauche.
                          Deine Lösung mit dem npm-Modul ist natürlich eleganter, was ich auch nutzen werde.
                          Die Einbindung meiner Klasse hilft mir bei der zentralen Pflege.

                          Grüße

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post

                          Support us

                          ioBroker
                          Community Adapters
                          Donate

                          1.2k
                          Online

                          31.7k
                          Users

                          79.7k
                          Topics

                          1.3m
                          Posts

                          20
                          1074
                          266979
                          Loading More Posts
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes
                          Reply
                          • Reply as topic
                          Log in to reply
                          Community
                          Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                          The ioBroker Community 2014-2023
                          logo