Chart.js 4.4.1双层环形图Tooltip与悬停位置不匹配问题求助
问题
我使用Chart.js 4.4.1实现了一个双层环形图(doughnut chart),包含两个数据集(dataset),分别对应外层环形和内层环形。预期每个数据集的提示框(tooltip)仅在鼠标悬停于对应数据集区域时显示,但实际出现异常:鼠标悬停在某一数据集上时,tooltip会在两个数据集间切换;甚至鼠标悬停在数据集外区域时,也会错误显示tooltip。实现代码如下:
chart_pie_sistemas = new Chart(ctx_chart_pie_sistemas, { type: "doughnut", data: { labels: ['Cherwell Service Management - Atendentes', 'SZ.Chat - Omni Channel', 'Google Chat'], datasets: [ { label: "Sistema", data: [10953, 6332, 0], backgroundColor: ['#F16A6A', '#2196F3', '#0F9D58'], }, { label: "UI", data: [0, 0, 17285], backgroundColor: ['#F16A6A', '#2196F3', '#0F9D58'], }, ] }, options: { locale: 'pt-BR', responsive: true, interaction: { intersect: false, mode: 'dataset', }, plugins: { legend: { display: true, position: 'top', }, title: { display: true, text: 'Notificações por sistema e UI', font: { size: 24, } }, tooltip: { filter: function(context) { var valor = context.dataset.data[context.dataIndex]; return valor > 0; }, callbacks: { footer: function(context) { let sum = 0; var contador = 0; context.forEach(function(tooltipItem) { contador++; sum += tooltipItem.parsed; }); var total_texto = (contador > 1 ? 'Total: ' + formatLocale(sum) : ""); return total_texto; } } }, } } });
解决方案
可以通过调整交互配置和数据集的视觉边界来解决这个问题,具体修改如下:
1. 修正交互模式配置
将interaction选项中的mode改为'nearest',并设置intersect: true:
mode: 'nearest'会让tooltip只响应离鼠标最近的单个元素,而非整个数据集intersect: true确保只有鼠标真正悬停在图表元素上时才触发tooltip,避免空白区域误触发
2. 区分内外层环形的可交互区域
给两个数据集分别设置不同的radius,明确内外层的边界,避免悬停区域重叠导致的判断混乱。
修改后的完整代码
chart_pie_sistemas = new Chart(ctx_chart_pie_sistemas, { type: "doughnut", data: { labels: ['Cherwell Service Management - Atendentes', 'SZ.Chat - Omni Channel', 'Google Chat'], datasets: [ { label: "Sistema", data: [10953, 6332, 0], backgroundColor: ['#F16A6A', '#2196F3', '#0F9D58'], radius: '70%', // 外层环形半径 borderWidth: 0 }, { label: "UI", data: [0, 0, 17285], backgroundColor: ['#F16A6A', '#2196F3', '#0F9D58'], radius: '50%', // 内层环形半径,与外层明确区分 borderWidth: 0 }, ] }, options: { locale: 'pt-BR', responsive: true, interaction: { intersect: true, mode: 'nearest', }, plugins: { legend: { display: true, position: 'top', }, title: { display: true, text: 'Notificações por sistema e UI', font: { size: 24, } }, tooltip: { filter: function(context) { var valor = context.dataset.data[context.dataIndex]; return valor > 0; }, callbacks: { footer: function(context) { let sum = 0; var contador = 0; context.forEach(function(tooltipItem) { contador++; sum += tooltipItem.parsed; }); var total_texto = (contador > 1 ? 'Total: ' + formatLocale(sum) : ""); return total_texto; } } }, } } });
补充说明
- 保留原有的
filter函数,确保只显示数据大于0的tooltip项 radius的数值可以根据需求调整,只要内外层有明显的间距即可- 修改后tooltip会精准匹配鼠标悬停的数据集区域,不会出现跨数据集切换或空白区域误触发的情况
内容的提问来源于stack exchange,提问作者ddias
相关产品推荐
相关产品推荐

