如何在Flutter charts_flutter折线图中添加单条平均参考线?
需求说明
已完成基础折线图开发,需要在折线图中添加一条白色平均参考线,要求通过StaticNumericTickProviderSpec实现。
原有业务代码如下:
import 'package:charts_flutter/flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:charts_flutter/flutter.dart' as charts; class WeightTracker_time_series_chart extends StatelessWidget { final List<charts.Series> seriesList; final bool animate; WeightTracker_time_series_chart(this.seriesList, {this.animate}); factory WeightTracker_time_series_chart.withSampleData() { return new WeightTracker_time_series_chart( _createSampleData(), animate: false, ); } List getdata =["1","2","3"]; @override Widget build(BuildContext context) { return new charts.LineChart(seriesList, animate: animate, defaultRenderer: new charts.LineRendererConfig( includeArea: true, includePoints: true, includeLine: true, stacked: true,), layoutConfig: charts.LayoutConfig( leftMarginSpec: charts.MarginSpec.fixedPixel(60), topMarginSpec: charts.MarginSpec.fixedPixel(10), rightMarginSpec: charts.MarginSpec.fixedPixel(0), bottomMarginSpec: charts.MarginSpec.fixedPixel(20) ), flipVerticalAxis: false, defaultInteractions: false, behaviors: [new charts.PanAndZoomBehavior()], domainAxis: new charts.NumericAxisSpec( viewport: new charts.NumericExtents(20, 120), renderSpec: charts.GridlineRendererSpec( lineStyle: charts.LineStyleSpec( color: charts.MaterialPalette.white, thickness: 1, ) ), tickProviderSpec: new charts.StaticNumericTickProviderSpec( // Create the ticks to be used the domain axis. _createTickSpec(), )), selectionModels: [ new charts.SelectionModelConfig( changedListener: (SelectionModel model) { print( model.selectedSeries[0].measureFn( model.selectedDatum[0].index)); } ) ], primaryMeasureAxis: new charts.NumericAxisSpec( renderSpec: charts.GridlineRendererSpec( labelOffsetFromAxisPx: 20, labelAnchor: charts.TickLabelAnchor.before, lineStyle: charts.LineStyleSpec( color: charts.MaterialPalette.white, thickness: 2, ) ), tickProviderSpec: new charts.StaticNumericTickProviderSpec( // Create the ticks to be used the domain axis. <charts.TickSpec<num>>[ new charts.TickSpec(50, label: '80 ', style: charts.TextStyleSpec(fontSize: 14)), ], ) ), } List<charts.TickSpec<num>> _createTickSpec() { List<charts.TickSpec<num>> _tickProvidSpecs = new List<charts.TickSpec<num>>(); double d = 0; double day= 0; for(int i = 0; i< getdata.length ; i++) { _tickProvidSpecs.add(new charts.TickSpec(d,label: '$day%', style: charts.TextStyleSpec(fontSize: 14))); d +=20; day+=1; } return _tickProvidSpecs; } static List<charts.Series<day_kg, int>> _createSampleData() { final myFakeDesktopData = [ new day_kg(0, 70), new day_kg(20, 85), new day_kg(40, 80), ]; return [ new charts.Series<day_kg, int>( id: 'weight', fillColorFn: (_, __) => charts.MaterialPalette.white, colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, domainFn: (day_kg data, _) => data.date, measureFn: (day_kg data, _) => data.kg, domainLowerBoundFn: (day_kg data, _) => data.domainLower, measureLowerBoundFn: (day_kg data, _) => data.measureLower, strokeWidthPxFn: (_, __) => 4, data: myFakeDesktopData, ), ]; } } class day_kg { final int date; final int kg; final int domainUpper = 100; final int domainLower = 0; final int measureUpper = 100; final int measureLower = 0; day_kg(this.date, this.kg); }
实现方案
以下提供两种符合需求的实现方式,优先匹配你要求的tickProviderSpec实现逻辑:
方案1:通过StaticNumericTickProviderSpec实现
实现逻辑
- 先遍历计算所有数据的体重平均值
- 将平均值作为自定义刻度加入纵轴的静态刻度列表,单独配置该刻度的网格线为白色,隐藏原有其他刻度的网格线即可仅展示一条平均参考线
修改步骤
- 在组件内新增平均值计算方法:
/// 计算体重平均值 num _calculateAverageValue() { if (seriesList.isEmpty || seriesList.first.data.isEmpty) return 0; int total = 0; for (var item in seriesList.first.data as List<day_kg>) { total += item.kg; } return total / seriesList.first.data.length; }
- 修改
primaryMeasureAxis配置,替换原有对应部分代码即可:
primaryMeasureAxis: new charts.NumericAxisSpec( renderSpec: charts.GridlineRendererSpec( labelOffsetFromAxisPx: 20, labelAnchor: charts.TickLabelAnchor.before, // 隐藏默认全局网格线 lineStyle: charts.LineStyleSpec( color: charts.MaterialPalette.transparent, thickness: 0, ) ), tickProviderSpec: new charts.StaticNumericTickProviderSpec( <charts.TickSpec<num>>[ // 保留原有业务刻度 new charts.TickSpec(50, label: '80 ', style: charts.TextStyleSpec(fontSize: 14)), // 新增平均值刻度,不需要显示标签可将label设为空字符串 new charts.TickSpec( _calculateAverageValue(), label: '平均体重', style: charts.TextStyleSpec(fontSize: 14, color: charts.MaterialPalette.white), // 单独配置平均值刻度线为白色 lineStyle: charts.LineStyleSpec( color: charts.MaterialPalette.white, thickness: 2, ), ), ], ) ),
方案2:通过RangeAnnotation实现(通用参考线方案)
如果不需要绑定刻度逻辑,直接添加参考线更推荐该方案,只需要在behaviors列表中新增注解配置即可:
behaviors: [ new charts.PanAndZoomBehavior(), // 新增平均参考线注解 new charts.RangeAnnotation( [ new charts.LineAnnotationSegment( _calculateAverageValue(), charts.RangeAnnotationAxisType.measure, color: charts.MaterialPalette.white, strokeWidthPx: 2, // 可选配置参考线标签 label: '平均体重', labelStyle: charts.TextStyleSpec( fontSize: 14, color: charts.MaterialPalette.white, ), ), ], ), ],
内容的提问来源于stack exchange,提问作者Meng Cheng teoh
相关产品推荐
相关产品推荐

