You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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>

核心调整说明

  1. 外层图例专属显示
    通过legend.labels.generateLabels自定义图例生成逻辑,仅提取外层数据集的标签与颜色,过滤内层数据的图例项。

  2. 外层外部标签控制

    • 给outlabels添加filter回调,仅允许外层数据集(索引0)生成标签
    • 在内层数据集配置中直接禁用outlabels显示
  3. 基于内层数据的角度计算

    • 新增calculateOuterAngles方法,计算内层目标数据项的占比,转换为Chart.js所需的弧度单位
    • 在组件初始化时调用该方法,确保图表加载时外层角度已匹配内层数据范围

内容的提问来源于stack exchange,提问作者Vipin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:45:51