如何在Flutter中创建嵌套式多层径向条形图?
实现无授权限制的嵌套多层径向条形图
不需要依赖需要授权的Syncfusion包,以下两种免费方案可以实现你要的嵌套径向条形图效果:
方案1:用flutter_circular_chart叠加实现
这个开源免费包可以通过叠加多个径向环形图来模拟嵌套效果,步骤如下:
- 添加依赖到
pubspec.yaml:
dependencies: flutter_circular_chart: ^0.1.0
- 编写叠加代码:
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
相关产品推荐
相关产品推荐

