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

如何在Flutter中创建嵌套式多层径向条形图?

实现无授权限制的嵌套多层径向条形图

不需要依赖需要授权的Syncfusion包,以下两种免费方案可以实现你要的嵌套径向条形图效果:

方案1:用flutter_circular_chart叠加实现

这个开源免费包可以通过叠加多个径向环形图来模拟嵌套效果,步骤如下:

  1. 添加依赖到pubspec.yaml:
dependencies:
  flutter_circular_chart: ^0.1.0
  1. 编写叠加代码:
import 'package:flutter/material.dart';
import 'package:flutter_circular_chart/flutter_circular_chart.dart';

class NestedRadialBar extends StatelessWidget {
  final outerRingData = [
    CircularStackEntry([CircularSegmentEntry(70, Colors.blue)], rankKey: 'outer')
  ];
  final middleRingData = [
    CircularStackEntry([CircularSegmentEntry(50, Colors.green)], rankKey: 'middle')
  ];
  final innerRingData = [
    CircularStackEntry([CircularSegmentEntry(30, Colors.orange)], rankKey: 'inner')
  ];

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Stack(
        alignment: Alignment.center,
        children: [
          AnimatedCircularChart(
            size: const Size(300, 300),
            initialChartData: outerRingData,
            chartType: CircularChartType.Radial,
            edgeStyle: SegmentEdgeStyle.round,
            holeRadius: 80,
            segmentStrokeWidth: 30,
          ),
          AnimatedCircularChart(
            size: const Size(240, 240),
            initialChartData: middleRingData,
            chartType: CircularChartType.Radial,
            edgeStyle: SegmentEdgeStyle.round,
            holeRadius: 60,
            segmentStrokeWidth: 30,
          ),
          AnimatedCircularChart(
            size: const Size(180, 180),
            initialChartData: innerRingData,
            chartType: CircularChartType.Radial,
            edgeStyle: SegmentEdgeStyle.round,
            holeRadius: 40,
            segmentStrokeWidth: 30,
          ),
        ],
      ),
    );
  }
}

通过Stack将三个尺寸递减的径向图叠加,就能得到嵌套的多层效果,每个环的数值、颜色、宽度都可以独立调整。

方案2:自定义Canvas绘制(无依赖)

如果需要更精细的样式控制,直接用Flutter的CustomPaint手写绘制,完全不需要第三方包:

import 'dart:math';
import 'package:flutter/material.dart';

class CustomNestedRadialBar extends StatelessWidget {
  // 每层的百分比数值(0-1)
  final List<double> layerValues = [0.7, 0.5, 0.3];
  // 每层对应的颜色
  final List<Color> layerColors = [Colors.blue, Colors.green, Colors.orange];
  // 每个径向条的宽度
  final double barWidth = 30;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: CustomPaint(
        size: const Size(300, 300),
        painter: _NestedRadialPainter(layerValues, layerColors, barWidth),
      ),
    );
  }
}

class _NestedRadialPainter extends CustomPainter {
  final List<double> values;
  final List<Color> colors;
  final double barWidth;

  _NestedRadialPainter(this.values, this.colors, this.barWidth);

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    double currentRadius = size.width / 2;

    for (int i = 0; i < values.length; i++) {
      final paint = Paint()
        ..color = colors[i]
        ..style = PaintingStyle.stroke
        ..strokeWidth = barWidth
        ..strokeCap = StrokeCap.round;

      // 计算弧形角度(从顶部开始绘制)
      final arcAngle = 2 * pi * values[i];
      canvas.drawArc(
        Rect.fromCircle(center: center, radius: currentRadius),
        -pi / 2,
        arcAngle,
        false,
        paint,
      );

      currentRadius -= barWidth;
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

这种方式可以完全自定义每个径向条的圆角、渐变、动画等细节,适配任何复杂样式需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 18:54:21