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

Flutter折线图渐变绘制异常求助:无法实现预期渐变效果

问题分析与解决方案

你当前的折线渐变效果不符合预期,核心问题出在渐变类型选择错误和渐变作用范围设置不当:

  1. 使用了径向渐变(RadialGradient),但预期是沿折线走向的线性渐变,两者的色彩扩散逻辑完全不匹配;
  2. 渐变的作用区域(Rect)未匹配图表实际绘制范围,导致渐变错位。

修改后的完整代码

@override
void paint(Canvas canvas, Size size) {
  List<Offset> offsets = getCoordinates(points, size);
  drawText(canvas, offsets); 
  drawLines(canvas, size,  offsets);
  drawPoints(canvas, size, offsets); 
}

void drawLines(Canvas canvas, Size size, List<Offset> offsets) {
  // 计算折线的包围盒,确保渐变精准覆盖折线区域
  double minX = offsets.reduce((a, b) => a.dx < b.dx ? a : b).dx;
  double maxX = offsets.reduce((a, b) => a.dx > b.dx ? a : b).dx;
  double minY = offsets.reduce((a, b) => a.dy < b.dy ? a : b).dy;
  double maxY = offsets.reduce((a, b) => a.dy > b.dy ? a : b).dy;
  Rect gradientRect = Rect.fromLTRB(minX, minY, maxX, maxY);

  // 使用线性渐变匹配预期效果,方向沿折线横向扩散
  final Gradient gradient = LinearGradient(
    colors: <Color>[
      Colors.redAccent,
      Colors.blue,
      Colors.green,
      Colors.blueGrey,
      Colors.orange,
    ],
    stops: [0.0, 0.25, 0.5, 0.75, 1.0],
    begin: Alignment.centerLeft,
    end: Alignment.centerRight,
  );

  Paint paint = Paint()
    ..strokeWidth = lineWidth
    ..style = PaintingStyle.stroke
    ..strokeCap = StrokeCap.round
    ..shader = gradient.createShader(gradientRect);

  Path path = Path();
  path.moveTo(offsets[0].dx, offsets[0].dy);
  // 直接遍历构建路径,避免不必要的List转换
  for (var offset in offsets.skip(1)) {
    path.lineTo(offset.dx, offset.dy);
  }

  canvas.drawPath(path, paint);
}

void drawPoints(Canvas canvas, Size size, List<Offset> offsets) {
  Paint paint = Paint()
    ..color = pointColor
    ..strokeCap = StrokeCap.round
    ..strokeWidth = pointSize;

  canvas.drawPoints(PointMode.points, offsets, paint);
}

关键调整说明

  • 替换渐变类型:将RadialGradient改为LinearGradient,通过begin和end控制渐变方向(这里用左右对齐适配横向折线);
  • 修正渐变范围:通过计算所有折线点的最小/最大坐标,生成刚好包裹折线的Rect,确保渐变效果精准覆盖目标区域;
  • 适配斜向折线(可选):如果折线是斜向的,可通过计算折线起点与终点的角度,给渐变添加旋转变换,让渐变完全贴合折线走向:
    Offset start = offsets.first;
    Offset end = offsets.last;
    double angle = atan2(end.dy - start.dy, end.dx - start.dx);
    
    final Gradient gradient = LinearGradient(
      colors: [...],
      stops: [...],
      transform: GradientRotation(angle),
    );
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:51:10