SUPPORT-8932: 1) Added grouped labels support for doughnut with inner rings 2) Update tooltip callbacks for Chart.js v3+

This commit is contained in:
Artyom Hackimullin 2025-04-11 17:38:15 +03:00
parent 8ae67de5d2
commit 4c1332d53a

View file

@ -227,25 +227,6 @@ export class ErvuChartV2 extends Control implements Filterable {
chartOptions.plugins = chartOptions.plugins ? chartOptions.plugins : {};
chartOptions.plugins.legend = this.legend ? this.legend : {};
chartOptions.plugins.tooltip = {
enabled: false, //Disables default tooltip from charjs (we'll use a custom tooltip)
external: (context) => {
if (this.showTooltip) {
if (!context || !this.chartTooltip) {
return;
}
const positionX = this.chart.canvas.offsetLeft;
const positionY = this.chart.canvas.offsetTop;
this.tooltipModel = context.tooltip;
this.tooltipPosition = {
'left': positionX + context.tooltip.caretX,
'top': positionY + context.tooltip.caretY
}
this.cd.markForCheck();
}
}
};
if (this.title && this.title.text) {
chartOptions.plugins.title = this.title;
@ -316,14 +297,43 @@ export class ErvuChartV2 extends Control implements Filterable {
Object.assign(chartOptions, this.options);
}
chartConfig.tooltips = {
let labelGroups: string[][];
if (chartConfig.type == 'doughnut' && datasets.length > 1) { //Group labels only for the doughnut with inner rings
labelGroups = this.splitLabels(chartConfig.data.labels, datasets);
}
chartOptions.plugins.tooltip = {
enabled: false, //Disables default tooltip from charjs (we'll use a custom tooltip)
external: (context) => {
if (this.showTooltip) {
if (!context || !this.chartTooltip) {
return;
}
const positionX = this.chart.canvas.offsetLeft;
const positionY = this.chart.canvas.offsetTop;
this.tooltipModel = context.tooltip;
this.tooltipPosition = {
'left': positionX + context.tooltip.caretX,
'top': positionY + context.tooltip.caretY
}
this.cd.markForCheck();
}
},
callbacks: {
title: function (tooltipItem, data) {
return data.labels[tooltipItem[0].index]
title: function (tooltipItems) {
const item = tooltipItems[0];
if (!labelGroups) {
return item.label || '';
}
return labelGroups[item.datasetIndex][item.dataIndex] || '';
},
label: function (tooltipItem, data) {
let dataset = data.datasets[tooltipItem.datasetIndex];
return dataset.label + ": " + dataset.data[tooltipItem.index];
label: function (tooltipItem) {
const dataset = tooltipItem.dataset;
if (dataset.type == 'bar') {
return dataset.data[tooltipItem.dataIndex].y;
}
return dataset.data[tooltipItem.dataIndex];
}
}
};
@ -355,6 +365,19 @@ export class ErvuChartV2 extends Control implements Filterable {
.map(val => val.y = '');
}
private splitLabels(labels: string[], datasets: { data: number[] }[]) {
let result: string[][] = [];
let startIndex = 0;
datasets.forEach((dataset) => {
const count = dataset.data.length;
const endIndex = startIndex + count;
result.push(labels.slice(startIndex, endIndex));
startIndex = endIndex;
})
return result;
}
clear() { //todo SUPPORT-4909
throw new UnsupportedOperationError("Unsupported operation");
}