Flutter:为Syncfusion DoughnutSeries图表添加环形标签
环形旋转标签的Doughnut图表实现问题
我使用Syncfusion的SfCircularChart实现了一个环形图,想要让外侧的标签随环形弧度旋转排列(沿环形切线方向对齐),但当前的标签是水平显示的,没有旋转效果。如果有其他Flutter图表包能实现该效果,也欢迎推荐。
当前代码如下:
SfCircularChart( annotations: [ CircularChartAnnotation( height: '60%', width: '60%', widget: PhysicalModel( shape: BoxShape.circle, elevation: 10, color: Colors.white, child: Container(), )), CircularChartAnnotation( height: '60%', width: '60%', widget: PhysicalModel( shape: BoxShape.circle, elevation: 10, color: const Color.fromRGBO(230, 230, 230, 1), child: Container(), )), CircularChartAnnotation( widget: const Text( 'Out of season', ), ) ], series: <CircularSeries>[ DoughnutSeries<TestData, String>( radius: '100', innerRadius: '70', dataSource: data, xValueMapper: (TestData data, _) => data.title, yValueMapper: (TestData data, _) => data.value, strokeColor: Colors.white, strokeWidth: 2, groupMode: CircularChartGroupMode.value, enableTooltip: false, dataLabelSettings: const DataLabelSettings( isVisible: true, labelAlignment: ChartDataLabelAlignment.top, alignment: ChartAlignment.near, labelPosition: ChartDataLabelPosition.outside, labelIntersectAction: LabelIntersectAction.shift, connectorLineSettings: ConnectorLineSettings(width: 0, length: '0'), ), pointColorMapper: (TestData data, _) => Colors.grey, ) ], ); List<TestData> data = [ TestData('21.10', 1), TestData('22.10', 1), TestData('23.10', 1), TestData('24.10', 1), TestData('25.10', 1), ]; class TestData { TestData(this.title, this.value); final String title; final double value; }
解决方案
1. 基于Syncfusion实现旋转标签
Syncfusion默认的DataLabelSettings不支持自动旋转对齐环形,但可以通过builder自定义标签,计算每个数据点的角度来旋转文本:
修改DoughnutSeries中的dataLabelSettings:
dataLabelSettings: DataLabelSettings( isVisible: true, labelPosition: ChartDataLabelPosition.outside, connectorLineSettings: const ConnectorLineSettings(width: 1, length: '10%'), builder: (dynamic data, dynamic point, dynamic series, int pointIndex, int seriesIndex) { final circularPoint = point as CircularChartPoint; // 计算当前分段的中间角度 final midAngle = circularPoint.startAngle + (circularPoint.endAngle - circularPoint.startAngle) / 2; // 将角度转为弧度,旋转文本 return Transform.rotate( angle: midAngle * pi / 180, child: Text( data.title, style: const TextStyle(fontSize: 12, color: Colors.black), ), ); }, ),
原理:通过每个环形数据点的startAngle和endAngle计算出该段弧度的中间角度,将文本旋转对应角度,实现沿环形切线方向对齐的效果。
2. 推荐其他支持该效果的包
如果觉得Syncfusion的自定义方式繁琐,可以尝试fl_chart包,它的饼图/环形图原生支持更灵活的标签控制:
示例代码片段:
PieChart( PieChartData( sectionsSpace: 2, centerSpaceRadius: 70, // 对应环形图的内半径 sections: data.map((item) { // 计算每个分段的角度 final segmentAngle = 360 / data.length; final itemIndex = data.indexOf(item); // 计算当前分段的中间角度 final midAngle = (segmentAngle * itemIndex + segmentAngle / 2) * pi / 180; return PieChartSectionData( value: item.value, color: Colors.grey, radius: 100, // 对应环形图的外半径 titleWidget: Transform.rotate( angle: midAngle, child: Padding( padding: const EdgeInsets.only(top: 10), child: Text(item.title), ), ), titlePositionPercentageOffset: 1.3, // 控制标签距离环形的距离 ); }).toList(), ), )
内容的提问来源于stack exchange,提问作者Luis Fernando Scripcaru
相关产品推荐
相关产品推荐

