如何让Flutter的FlChart实现永久可见的水平TouchedSpotIndicator?
解决Flutter FlChart中永久显示水平现价线的问题
核心思路
getTouchedSpotIndicator 依赖触摸事件触发,无法实现永久显示效果。我们换用两种原生API组合的方式实现需求:
- 利用
FlGridData绘制永久水平高亮线 - 通过自定义
FlDotData绘制目标点的标记
完整代码示例
class PermanentHorizontalPriceLine extends StatefulWidget { const PermanentHorizontalPriceLine({super.key}); @override State<PermanentHorizontalPriceLine> createState() => _PermanentHorizontalPriceLineState(); } class _PermanentHorizontalPriceLineState extends State<PermanentHorizontalPriceLine> { // 替换为你的实际图表数据 final List<FlSpot> _chartData = [ const FlSpot(0, 2.1), const FlSpot(1, 3.3), const FlSpot(2, 4.0), const FlSpot(3, 5.2), // 现价对应的目标点 const FlSpot(4, 4.7), const FlSpot(5, 3.5), const FlSpot(6, 2.8), ]; // 现价对应的Y值和点索引(可根据业务逻辑动态更新) double get _targetPriceY => _chartData[3].y; int get _targetSpotIndex => 3; @override Widget build(BuildContext context) { return LineChart( LineChartData( // 关闭触摸触发的指示器(若需要保留触摸交互可移除该行) lineTouchData: const LineTouchData(enabled: false), gridData: FlGridData( show: true, drawVerticalLine: true, drawHorizontalLine: true, // 自定义水平线绘制逻辑 getDrawingHorizontalLine: (value) { if (value == _targetPriceY) { // 现价线样式 return FlLine( color: const Color(0xFFFFAB56), strokeWidth: 2.5, dashArray: const [7], ); } // 普通网格线样式 return FlLine( color: Colors.grey.withOpacity(0.2), strokeWidth: 1, ); }, ), titlesData: const FlTitlesData(show: true), borderData: FlBorderData(show: true), lineBarsData: [ LineChartBarData( spots: _chartData, isCurved: true, color: Colors.blueAccent, barWidth: 2, // 自定义点标记逻辑 dotData: FlDotData( show: true, getDotPainter: (spot, percent, barData, index) { if (index == _targetSpotIndex) { // 目标点的高亮样式 return FlDotCirclePainter( color: const Color(0xFFFFAB56), radius: 7.5, strokeWidth: 3.5, strokeColor: Colors.white.withOpacity(0.5), ); } // 隐藏其他点(或设置为你需要的默认样式) return FlDotCirclePainter(color: Colors.transparent); }, ), ), ], ), ); } }
关键说明
- 永久水平现价线:通过
getDrawingHorizontalLine拦截网格线绘制,匹配目标Y值时渲染高亮水平线,原生支持贯穿整个图表宽度。 - 永久点标记:在
getDotPainter中判断点索引,仅对目标点应用自定义样式,其他点可隐藏或保留默认样式。 - 动态更新:若需要随数据变化更新现价线,只需修改
_targetPriceY和_targetSpotIndex并调用setState即可。
内容的提问来源于stack exchange,提问作者Isaac Oyewole
相关产品推荐
相关产品推荐

