如何在fl_chart中使用showingTooltipIndicators自定义提示框内容?
解决Flutter LineChart自定义Tooltip显示实际数值的问题
我明白你想在LineChart的Tooltip里显示原始实际数值,而非计算后的y值,同时搞清楚showingTooltipIndicators的正确用法。下面一步步给你拆解实现方法:
1. 先存储原始数值
首先,你需要把每个点对应的原始数值单独存起来——因为你当前的spots用的是计算后的值,后续要在Tooltip里调用这些原始数据:
// 假设number是你已有的数据源,提取每个点对应的原始数值 final List<String> originalValues = [ number[21], number[13], number[5], ];
2. 配置showingTooltipIndicators控制Tooltip显示
showingTooltipIndicators是LineChartData的直接参数(不是LineChartBarData里的配置),你需要创建对应的ShowingTooltipIndicators实例,指定要显示Tooltip的线条索引(你的例子里只有1条线,所以是0)和对应点:
方式1:默认显示所有点的Tooltip
如果想一开始就展示所有点的Tooltip,可以这样写:
LineChart( LineChartData( lineBarsData: [ // 你原来的LineChartBarData代码 LineChartBarData( spots: [ FlSpot(1, (double.parse(number[21])-50)/25+1), FlSpot(5, (double.parse(number[13])-50)/25+1), FlSpot(9, (double.parse(number[5])-50)/25+1), ], isCurved: true, colors: gradientColors, barWidth: 4, isStrokeCapRound: true, dotData: FlDotData(show: false), ), ], // 关键:添加showingTooltipIndicators配置 showingTooltipIndicators: [ ShowingTooltipIndicators( 0, // 线条索引,这里只有一条线所以是0 // 生成对应的LineBarSpot列表 List.generate(3, (index) => LineBarSpot( LineChartBarData(spots: [ FlSpot(1, (double.parse(number[21])-50)/25+1), FlSpot(5, (double.parse(number[13])-50)/25+1), FlSpot(9, (double.parse(number[5])-50)/25+1), ]), index, FlSpot( [1,5,9][index], (double.parse(originalValues[index])-50)/25+1 ), )), ), ], // 配置自定义Tooltip内容 tooltipData: LineChartTooltipData( getTooltipItems: (List<LineBarSpot> touchedSpots) { return touchedSpots.map((spot) { // 通过spot的index获取对应的原始数值 final originalValue = originalValues[spot.spotIndex]; return LineChartTooltipItem( "实际数值: $originalValue", // 自定义显示内容 TextStyle(color: Colors.white), ); }).toList(); }, ), ), )
方式2:点击点时显示Tooltip(更常用)
如果想实现点击图表点才显示对应Tooltip,需要结合状态管理(比如StatefulWidget):
class MyChart extends StatefulWidget { @override _MyChartState createState() => _MyChartState(); } class _MyChartState extends State<MyChart> { List<ShowingTooltipIndicators>? _showingTooltipIndicators; final List<String> originalValues = [number[21], number[13], number[5]]; final List<FlSpot> spots = [ FlSpot(1, (double.parse(number[21])-50)/25+1), FlSpot(5, (double.parse(number[13])-50)/25+1), FlSpot(9, (double.parse(number[5])-50)/25+1), ]; @override Widget build(BuildContext context) { return LineChart( LineChartData( lineBarsData: [ LineChartBarData( spots: spots, isCurved: true, colors: gradientColors, barWidth: 4, isStrokeCapRound: true, dotData: FlDotData(show: true), // 要点击的话需要显示dot ), ], showingTooltipIndicators: _showingTooltipIndicators, tooltipData: LineChartTooltipData( getTooltipItems: (touchedSpots) { return touchedSpots.map((spot) { final originalValue = originalValues[spot.spotIndex]; return LineChartTooltipItem( "实际数值: $originalValue", TextStyle(color: Colors.white, fontSize: 14), ); }).toList(); }, ), // 配置点击事件 touchData: LineTouchData( touchTooltipData: LineTouchTooltipData( tooltipBgColor: Colors.blueGrey, ), handleBuiltInTouches: true, touchCallback: (FlTouchEvent event, LineTouchResponse? response) { if (response == null || response.lineBarSpots == null) { setState(() { _showingTooltipIndicators = null; }); return; } setState(() { _showingTooltipIndicators = [ ShowingTooltipIndicators( response.lineBarSpots![0].barIndex, response.lineBarSpots!, ), ]; }); }, ), ), ); } }
关键知识点说明
showingTooltipIndicators是LineChartData的参数,不是LineChartBarData的,所以要放在外层的LineChartData里配置。ShowingTooltipIndicators的showingSpots需要传入LineBarSpot实例,每个实例对应一个要显示Tooltip的点。- 通过
tooltipData.getTooltipItems可以完全自定义Tooltip的显示内容,只要通过spot.spotIndex关联到你预先存储的原始数值即可。
内容的提问来源于stack exchange,提问作者김은주




