tooltipLabel = function (context) { let label = context.dataset.label || ''; if (label) { label += ': '; } if (context.dataset.yAxisID == "y1") { label += Math.round(context.parsed.y * 10) / 10 + " " + "%"; } else { if (context.parsed.y !== null) { ret = scale(Math.round(context.parsed.y), false); label += ret[0] + " " + ret[1] + "Wh"; } } return label; }; tooltipFooter = function (tooltipItems){ let sum = 0; tooltipItems.forEach(function(tooltipItem) { if (tooltipItem.dataset.yAxisID != "y1") { sum += tooltipItem.parsed.y; } }); ret = scale(Math.round(sum), false); sum = ret[0] + " " + ret[1] + "Wh"; return 'Summe: ' + sum; } legendLabels = function(chart){ const datasets = chart.data.datasets; const { labels: { usePointStyle, pointStyle, textAlign, color } } = chart.legend.options; return chart._getSortedDatasetMetas().map((meta) => { const style = meta.controller.getStyle(usePointStyle ? 0 : undefined); const borderWidth = Chart.helpers.toPadding(style.borderWidth); ret = scale(Math.round(arraySum(datasets[meta.index].data)), false); ret2 = scale(Math.round(datasets[meta.index].data[datasets[meta.index].data.length-1]), false); return { text: datasets[meta.index].label + " Σ " + ret[0]+" "+ret[1]+"Wh",//+ " Last: " + ret2[0]+" "+ret2[1]+"W", fillStyle: style.backgroundColor, fontColor: color, hidden: !meta.visible, lineCap: style.borderCapStyle, lineDash: style.borderDash, lineDashOffset: style.borderDashOffset, lineJoin: style.borderJoinStyle, lineWidth: (borderWidth.width + borderWidth.height) / 4, strokeStyle: style.borderColor, pointStyle: pointStyle || style.pointStyle, rotation: style.rotation, textAlign: textAlign || style.textAlign, borderRadius: 0, // TODO: v4, default to style.borderRadius datasetIndex: meta.index }; }, this); } Chart.defaults.plugins.tooltip.callbacks.footer = tooltipFooter; Chart.defaults.plugins.tooltip.callbacks.label = tooltipLabel; Chart.defaults.plugins.legend.labels.generateLabels = legendLabels; var forecastChartSettings = { type: 'bar', options: { responsive: true, maintainAspectRatio: false, interaction: { intersect: false, mode: 'index', }, scales: { y: { stacked: true, display: true, min: 0, suggestedMax: 1000, ticks: { callback: value => `${value / 1000} kWh`, } }, } } }; var decadeChartSettings = { type: 'bar', options: { responsive: true, maintainAspectRatio: false, interaction: { intersect: false, mode: 'index', }, scales: { y: { stacked: true, display: true, min: 0, suggestedMax: 1000000, ticks: { callback: value => `${value / 1000000} MWh`, } }, } } }; var chartData = {}; const consChart = new Chart( document.querySelector('#consumption-chart'), Object.assign({}, forecastChartSettings) ); const prodChart = new Chart( document.querySelector('#production-chart'), Object.assign({}, forecastChartSettings) ); const consChartYear = new Chart( document.querySelector('#consumption-chart-year'), Object.assign({}, decadeChartSettings) ); const prodChartYear = new Chart( document.querySelector('#production-chart-year'), Object.assign({}, decadeChartSettings) ); const consChartDecade = new Chart( document.querySelector('#consumption-chart-decade'), Object.assign({}, decadeChartSettings) ); const prodChartDecade = new Chart( document.querySelector('#production-chart-decade'), Object.assign({}, decadeChartSettings) ); document.addEventListener('readystatechange', function () { if (event.target.readyState === "complete") { getData(prodChart, 'ajax/getProdData_month.php'); getData(consChart, 'ajax/getConsData_month.php'); getData(prodChartYear, 'ajax/getProdData_year.php'); getData(consChartYear, 'ajax/getConsData_year.php'); getData(prodChartDecade, 'ajax/getProdData_decade.php'); getData(consChartDecade, 'ajax/getConsData_decade.php'); //getData(prodChart, 'ajax/getProdData.php'); //getData(foreChart,'ajax/getForecastData.php', false); getStats("Stats-Year","ajax/getStats.php?type=ThisYear"); getStats("Stats-Lastyear","ajax/getStats.php?type=LastYear"); getStats("Stats-Prelastyear","ajax/getStats.php?type=PreLastYear"); } }); async function getData(chart, url, sunrise=true) { try { console.log("fetching"+chart); const response = await fetch(url); if (!response.ok) { console.log("err"); throw new Error(`Response status: ${response.status}`); } chart.data = await response.json(); chart.update(); //chart.options.scales.x.min = chart.data.labels[0]-(chart.data.labels[1]-chart.data.labels[0])/2; //chart.options.scales.x.max = chart.data.labels[chart.data.labels.length-1]+(chart.data.labels[1]-chart.data.labels[0])/2; chart.update(); } catch (error) { console.log(error.message); } setTimeout(function () { getData(chart, url, sunrise) }, 5 * 60 * 1000); //renew data every 5 min. } async function getStats(elem_id, url) { try { console.log("fetching"); const response = await fetch(url); if (!response.ok) { console.log("err"); throw new Error(`Response status: ${response.status}`); } document.getElementById(elem_id).innerHTML = await response.text(); } catch (error) { console.log(error.message); } setTimeout(function () { getData(chart, url, sunrise) }, 5 * 60 * 1000); //renew data every 5 min. } function powerToString(power) { if (Math.abs(power) > 999) { power = power / 1000 return power.toPrecision(3) + " kW" } else { return Math.round(power) + " W" } }