如何使用Chart.js实现饼图嵌套环形图的绘制?
实现Chart.js嵌套饼图+环形图的方案
嘿,我正好做过类似的需求!你要的这种内外层嵌套的饼图+环形图效果,其实不用分开画两个独立的图表,咱们可以在同一个Canvas元素上叠加两个Chart实例,轻松实现,而且完全保留各自数据的独立性,完美匹配你的需求。
核心实现思路
- 复用同一个
<canvas>容器,先后创建两个Chart实例:一个作为内部核心饼图,一个作为外层环形图。 - 给外层环形图设置合适的
cutoutPercentage参数,让它的空心区域刚好能容纳内部饼图。 - 调整图例、布局等配置,避免两个图表的元素互相重叠干扰。
完整实现代码
首先确保HTML里有一个用于承载嵌套图表的Canvas:
<canvas id="nested_chart"></canvas>
然后是JavaScript逻辑,我们把两个图表的绘制逻辑整合,让它们共用同一个画布:
function drawNestedPieDoughnut(innerLabels, innerData, innerColors, outerLabels, outerData, outerColors, title) { const ctx = document.getElementById('nested_chart').getContext('2d'); // 绘制内部饼图 const innerPieChart = new Chart(ctx, { type: 'pie', data: { labels: innerLabels, datasets: [{ backgroundColor: innerColors, data: innerData }] }, options: { responsive: true, maintainAspectRatio: true, legend: { display: false, // 隐藏内部饼图图例,避免和外层重叠 }, tooltips: { callbacks: { label: function (tooltipItem, data) { // 保留你原有的时间格式化逻辑 return secondsToHHMMSS(data['datasets'][0]['data'][tooltipItem['index']]); } } }, layout: { padding: 20 // 给图表留边,避免内容溢出 } } }); // 绘制外层环形图,复用同一个画布上下文 const outerDoughnutChart = new Chart(ctx, { type: 'doughnut', data: { labels: outerLabels, datasets: [{ backgroundColor: outerColors, data: outerData }] }, options: { responsive: true, maintainAspectRatio: true, cutoutPercentage: 60, // 控制环形空心大小,60表示空心占60%,可根据显示效果调整 legend: { position: 'top', }, title: { display: true, text: title }, animation: { animateScale: true, animateRotate: true }, layout: { padding: 20 // 和内部饼图保持一致的边距 } } }); // 返回两个实例,方便后续更新数据或调整配置 return { innerPieChart, outerDoughnutChart }; } // 保留你原有的时间格式化函数 function secondsToHHMMSS(seconds) { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; }
使用示例
你可以像这样调用函数,传入内外层各自的标签、数据和颜色:
// 内部饼图数据 const innerLabels = ['空闲', '忙碌']; const innerData = [1200, 2400]; const innerColors = ['#FF6384', '#36A2EB']; // 外部环形图数据 const outerLabels = ['处理中', '等待分配', '已完成']; const outerData = [1800, 900, 900]; const outerColors = ['#FFCE56', '#4BC0C0', '#9966FF']; // 绘制嵌套图表 drawNestedPieDoughnut(innerLabels, innerData, innerColors, outerLabels, outerData, outerColors, '运营状态统计');
关键参数说明
cutoutPercentage:环形图的核心参数,值越大空心区域越大。我这里设为60,你可以根据实际显示效果微调,直到内部饼图刚好填满空心区域。legend.display:建议隐藏内部饼图的图例,避免和外层图例重叠;如果需要显示内部图例,可以调整图例的position到bottom等位置。maintainAspectRatio:保持为true,确保图表始终是圆形,不会被容器拉伸变形。
这样实现的嵌套图表,内外层数据完全独立,各自的提示框、动画都能正常工作,完全满足你的需求~
内容的提问来源于stack exchange,提问作者Den B
相关产品推荐
相关产品推荐

