如何用Chart.js实现多层环形图外层标签显示及角度配置
多层环形图需求实现方案(Chart.js 2.9.4)
需求背景
已完成多层环形图的基础实现,需调整以下两点:
- 仅展示外层环形图的图例与外部标签
- 基于内层环形图的数据,设置外层环形图的起始和结束角度
修改后的完整代码
TypeScript 代码
import { Component, OnInit } from '@angular/core'; import { ChartType, Label } from 'ng2-charts'; @Component({ selector: 'app-doughnut-chart', templateUrl: './doughnut-chart.component.html', styleUrls: ['./doughnut-chart.component.css'] }) export class DoughnutChartComponent implements OnInit { pieChartPlugins = []; doughnutChartType: ChartType = 'doughnut'; doughnutChartLabels: Label[] = []; // 替换为实际业务数据 doughnutChartData: any[] = [ { data: [25, 35, 20], // 外层环形图数据 labels: ['外层标签1', '外层标签2', '外层标签3'], backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], startAngle: 0, endAngle: 0 }, { data: [60, 40], // 内层数据:Applied(60), Policy Not Applied(40) labels: ['Applied', "Policy Not Applied"], backgroundColor: ['orange', 'blue'], // 禁用内层图例与外部标签 legend: { display: false }, plugins: { outlabels: { display: false } } }, ]; doughnutChartOption: any = { tooltips: { callbacks: { label: (tooltipItem, data) => { const dataset = data.datasets[tooltipItem.datasetIndex]; const index = tooltipItem.index; return `${dataset.labels[index]}: ${dataset.data[index]}`; }, }, }, layout: { padding: { left: 0, right: 0, top: 50, bottom: 50 }, }, plugins: { labels: { render: () => {} }, outlabels: { backgroundColor: 'transparent', text: '%v', color: 'black', stretch: 45, padding: 10, font: { resizable: true, minSize: 12, maxSize: 14 }, // 仅显示外层标签 filter: (context) => context.datasetIndex === 0 }, }, legend: { display: true, position: 'left', // 仅生成外层图例 labels: { generateLabels: (chart) => { const outerDataset = chart.data.datasets[0]; return outerDataset.labels.map((label, index) => ({ text: label, fillStyle: outerDataset.backgroundColor[index], strokeStyle: outerDataset.backgroundColor[index], lineWidth: 1 })); } } }, cutoutPercentage: 60, // 控制环形图的空心比例 }; ngOnInit(): void { this.calculateOuterAngles(); } // 根据内层数据计算外层环形图的角度范围 calculateOuterAngles(): void { const innerDataset = this.doughnutChartData[1]; const totalInner = innerDataset.data.reduce((sum, val) => sum + val, 0); // 匹配内层"Applied"项的角度范围(可根据需求调整目标项) const targetRatio = innerDataset.data[0] / totalInner; // Chart.js 使用弧度计算角度,0为顶部顺时针方向 const startAngle = 0; const endAngle = startAngle + targetRatio * 2 * Math.PI; // 更新外层数据集的角度配置 this.doughnutChartData[0].startAngle = startAngle; this.doughnutChartData[0].endAngle = endAngle; } }
HTML 代码
<div style="display: block; width: 400px; height: 400px;"> <canvas baseChart [chartType]="doughnutChartType" [datasets]="doughnutChartData" [options]="doughnutChartOption" [plugins]="pieChartPlugins"> </canvas> </div>
核心调整说明
外层图例专属显示
通过legend.labels.generateLabels自定义图例生成逻辑,仅提取外层数据集的标签与颜色,过滤内层数据的图例项。外层外部标签控制
- 给
outlabels添加filter回调,仅允许外层数据集(索引0)生成标签 - 在内层数据集配置中直接禁用
outlabels显示
- 给
基于内层数据的角度计算
- 新增
calculateOuterAngles方法,计算内层目标数据项的占比,转换为Chart.js所需的弧度单位 - 在组件初始化时调用该方法,确保图表加载时外层角度已匹配内层数据范围
- 新增
内容的提问来源于stack exchange,提问作者Vipin
相关产品推荐
相关产品推荐

