You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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);
              },
            ),
          ),
        ],
      ),
    );
  }
}

关键说明

  1. 永久水平现价线:通过getDrawingHorizontalLine拦截网格线绘制,匹配目标Y值时渲染高亮水平线,原生支持贯穿整个图表宽度。
  2. 永久点标记:在getDotPainter中判断点索引,仅对目标点应用自定义样式,其他点可隐藏或保留默认样式。
  3. 动态更新:若需要随数据变化更新现价线,只需修改_targetPriceY和_targetSpotIndex并调用setState即可。

内容的提问来源于stack exchange,提问作者Isaac Oyewole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 05:27:02