// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0 'use strict'; /* globals Chart */ function initCharts() { if (!window.Chart) { if (window.console) { console.log('FreshRSS is waiting for Chart.js…'); } window.setTimeout(initCharts, 25); return; } const jsonData = document.getElementsByClassName('jsonData-stats'); let jsonDataParsed; let chartConfig; for (let i = 0; i < jsonData.length; i++) { jsonDataParsed = JSON.parse(jsonData[i].innerHTML); switch (jsonDataParsed.charttype) { case 'bar': chartConfig = jsonChartBar(jsonDataParsed.label, jsonDataParsed.data, jsonDataParsed.xAxisLabels); break; case 'doughnut': chartConfig = jsonChartDoughnut(jsonDataParsed.labels, jsonDataParsed.data); break; case 'barWithAverage': chartConfig = jsonChartBarWithAverage(jsonDataParsed.labelBarChart, jsonDataParsed.dataBarChart, jsonDataParsed.labelAverage, jsonDataParsed.dataAverage, jsonDataParsed.xAxisLabels); } /* eslint-disable no-new */ new Chart(document.getElementById(jsonDataParsed.canvasID), chartConfig); /* eslint-enable no-new */ } // Force resize after clicking enlarge button (needed since chart.js v4) for (const id in Chart.instances) { const instance = Chart.instances[id]; const boxTitle = instance.canvas.parentElement.previousElementSibling; const enlargeBtns = boxTitle.querySelectorAll('a.btn'); function forceResize() { function waitHash() { requestAnimationFrame(() => instance.resize()); window.removeEventListener('hashchange', waitHash); } instance.resize(); // try early resize window.addEventListener('hashchange', waitHash); } for (const btn of enlargeBtns) { btn.addEventListener('click', forceResize); } } window.addEventListener('resize', () => { for (const id in Chart.instances) { const instance = Chart.instances[id]; // Workaround for a chart.js bug which makes the canvas blurry if // page was loaded with very low zoom level and later zoomed in instance.update(); instance.resize(); } }); if (window.console) { console.log('Chart.js finished'); } } function jsonChartBar(label, data, xAxisLabels = '') { return { type: 'bar', data: { labels: xAxisLabels, datasets: [{ label, backgroundColor: '#0062BD', borderColor: '#0062BD', data, barPercentage: 1.0, categoryPercentage: 1.0, order: 2, }], }, options: { scales: { y: { beginAtZero: true, }, x: { grid: { display: false, }, }, }, plugins: { legend: { display: false, }, }, }, }; } function jsonChartDoughnut(labels, data) { return { type: 'doughnut', data: { labels, datasets: [{ backgroundColor: [ '#0b84a5', // petrol '#f6c85f', // sand '#6f4e7c', // purple '#9dd866', // green '#ca472f', // red '#ffa056', // orange '#8dddd0', // turkis '#f6c85f', // sand '#6f4e7c', // purple '#9dd866', // green '#ca472f', // red '#ffa056', // orange '#8dddd0', // turkis ], data, }], }, options: { layout: { padding: 20, }, plugins: { legend: { position: 'bottom', align: 'start', }, }, }, }; } function jsonChartBarWithAverage(labelBarChart, dataBarChart, labelAverage, dataAverage, xAxisLabels = '') { return { type: 'bar', data: { datasets: [ { // bar chart layout label: labelBarChart, backgroundColor: '#0062BD', borderColor: '#0062BD', data: dataBarChart, barPercentage: 1.0, categoryPercentage: 1.0, order: 2, }, { // average line chart type: 'line', label: labelAverage, // Todo: i18n borderColor: 'rgb(192,216,0)', data: { '-30': dataAverage, '-1': dataAverage, }, order: 1, }, ], }, options: { scales: { y: { beginAtZero: true, }, x: { ticks: { callback: function (val) { if (xAxisLabels.length > 0) { return xAxisLabels[val]; } else { return val; } }, }, grid: { display: false, }, }, }, elements: { point: { radius: 0, }, }, plugins: { tooltip: { callbacks: { title: function (tooltipitem) { if (xAxisLabels.length > 0) { return xAxisLabels[tooltipitem[0].dataIndex]; } else { return tooltipitem[0].label; } }, }, }, legend: { display: false, }, }, }, }; } initCharts(); // @license-end