if (!window.blazorChart) { window.blazorChart = {}; } window.blazorChart = { addDatasetData: (elementId, dataLabel, data) => { let chart = window.blazorChart.get(elementId); if (chart) { const chartData = chart.data; const chartDatasetData = data; if (!chartData.labels.includes(dataLabel)) chartData.labels.push(dataLabel); const chartDatasets = chartData.datasets; if (chartDatasets.length > 0) { let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); if (datasetIndex > -1) { chartDatasets[datasetIndex].data.push(chartDatasetData.data); chart.update(); } } } }, addDatasetsData: (elementId, dataLabel, data) => { let chart = window.blazorChart.get(elementId); if (chart && data) { const chartData = chart.data; if (!chartData.labels.includes(dataLabel)) { chartData.labels.push(dataLabel); if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { data.forEach(chartDatasetData => { let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); chartData.datasets[datasetIndex].data.push(chartDatasetData.data); }); chart.update(); } } } }, addDataset: (elementId, newDataset) => { let chart = window.blazorChart.get(elementId); if (chart) { chart.data.datasets.push(newDataset); chart.update(); } }, create: (elementId, type, data, options) => { let chartEl = document.getElementById(elementId); let _plugins = []; _plugins.push(ChartDataLabels); const config = { type: type, data: data, options: options, plugins: _plugins }; if (type === 'line') { const tooltipLine = { id: 'tooltipLine', beforeDraw: chart => { if (chart.tooltip?._active && chart.tooltip?._active.length) { const ctx = chart.ctx; ctx.save(); const activePoint = chart.tooltip._active[0]; ctx.beginPath(); ctx.setLineDash([5, 5]); ctx.moveTo(activePoint.element.x, chart.chartArea.top); ctx.lineTo(activePoint.element.x, activePoint.element.y); ctx.linewidth = 2; ctx.strokeStyle = 'grey'; ctx.stroke(); ctx.restore(); ctx.beginPath(); ctx.setLineDash([5, 5]); ctx.moveTo(activePoint.element.x, activePoint.element.y); ctx.lineTo(activePoint.element.x, chart.chartArea.bottom); ctx.linewidth = 2; ctx.strokeStyle = 'grey'; ctx.stroke(); ctx.restore(); } }, }; config.plugins.push(tooltipLine); } const chart = new Chart( chartEl, config ); }, get: (elementId) => { let chart; Chart.helpers.each(Chart.instances, function (instance) { if (instance.canvas.id === elementId) { chart = instance; } }); return chart; }, initialize: (elementId, type, data, options) => { let chart = window.blazorChart.get(elementId); if (chart) return; else window.blazorChart.create(elementId, type, data, options); }, resize: (elementId, width, height) => { let chart = window.blazorChart.get(elementId); if (chart) { chart.canvas.parentNode.style.height = height; chart.canvas.parentNode.style.width = width; } }, update: (elementId, data, options) => { let chart = window.blazorChart.get(elementId); if (chart) { chart.data = data; chart.options = options; chart.update(); } else { console.warn(`The chart is not initialized. Initialize it and then call update.`); } }, updateData: (elementId, data) => { let chart = window.blazorChart.get(elementId); if (chart) { window.blazorChart.mergeDatasets(chart.data.datasets, data.datasets); window.blazorChart.mergeLabels(chart.data, data); chart.update(); } }, mergeDatasets(oldDatasets, newDatasets) { for (let i = oldDatasets.length - 1; i >= 0; i--) { let sameDatasetInNewConfig = newDatasets.find(newD => newD.label === oldDatasets[i].label); if (sameDatasetInNewConfig === undefined) { oldDatasets.splice(i, 1); } else { oldDatasets[i].data = sameDatasetInNewConfig.data; } } let currentIds = oldDatasets.map(dataset => dataset.label); newDatasets.filter(newDataset => !currentIds.includes(newDataset.label)).forEach(newDataset => oldDatasets.push(newDataset)); }, mergeLabels(oldChartData, newChartData) { const innerFunc = (oldLabels, newLabels) => { if (newLabels == null || newLabels.length === 0) { if (oldLabels) { oldLabels.length = 0; } return oldLabels; } if (oldLabels == null) { return newLabels; } oldLabels.length = 0; for (var i = 0; i < newLabels.length; i++) { oldLabels.push(newLabels[i]); } return oldLabels; }; oldChartData.labels = innerFunc(oldChartData.labels, newChartData.labels); }, }