imaNNeo / imaNNeo/fl_chart

When using LineChart with implicit animations (duration and curve parameters)

Open
#2,030 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
7.6k
Forks
2k
Avg merge
9d 1h
Merged PRs (30d)
2

Description

When using LineChart with implicit animations (duration and curve parameters), switching between datasets with significantly different Y-axis ranges causes vertical lines/glitches to appear during the animation transition. This happens because the chart tries to animate between data points with very different values (e.g., from ~200 range to ~460 range).
The issue is particularly noticeable when:
Switching between different assets/stocks with different price ranges
The Y-axis min/max values change dramatically
Using cutOffY and applyCutOffY for baseline-based gradients

To Reproduce
Complete reproducible code in main.dart:
```
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FL Chart Animation Issue',
theme: ThemeData.dark(),
home: const ChartAnimationIssue(),
);
}
}

class ChartAnimationIssue extends StatefulWidget {
const ChartAnimationIssue({super.key});

@override
State createState() => _ChartAnimationIssueState();
}

class _ChartAnimationIssueState extends State {
bool showFirstDataset = true;

// Dataset 1: Price range ~200-250
List get dataset1 => [
const FlSpot(0, 202.81),
const FlSpot(1, 205.20),
const FlSpot(2, 203.50),
const FlSpot(3, 207.83),
const FlSpot(4, 206.10),
const FlSpot(5, 208.50),
const FlSpot(6, 207.20),
];

// Dataset 2: Price range ~440-465 (very different range)
List get dataset2 => [
const FlSpot(0, 454.14),
const FlSpot(1, 448.20),
const FlSpot(2, 451.80),
const FlSpot(3, 462.07),
const FlSpot(4, 458.50),
const FlSpot(5, 465.89),
const FlSpot(6, 463.20),
];

@override
Widget build(BuildContext context) {
final currentData = showFirstDataset ? dataset1 : dataset2;
final minY = currentData.map((e) => e.y).reduce((a, b) => a < b ? a : b);
final maxY = currentData.map((e) => e.y).reduce((a, b) => a > b ? a : b);
final startPrice = currentData.first.y;

return Scaffold(
appBar: AppBar(
title: const Text('FL Chart Animation Issue'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: ElevatedButton(
onPressed: () {
setState(() {
showFirstDataset = !showFirstDataset;
});
},
child: Text(
showFirstDataset
? 'Switch to Dataset 2 (465 range)'
: 'Switch to Dataset 1 (202 range)',
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: LineChart(
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
LineChartData(
gridData: FlGridData(
show: true,
drawVerticalLine: false,
getDrawingHorizontalLine: (value) {
// Baseline at start price
if ((value - startPrice).abs() < (maxY - minY) * 0.02) {
return FlLine(
color: Colors.white.withValues(alpha: 0.5),
strokeWidth: 1,
dashArray: [4, 4],
);
}
return FlLine(
color: Colors.white.withValues(alpha: 0.1),
strokeWidth: 0.5,
);
},
),
titlesData: const FlTitlesData(
show: false,
),
borderData: FlBorderData(show: false),
lineBarsData: [
LineChartBarData(
spots: currentData,
isCurved: true,
color: Colors.green,
barWidth: 1.5,
isStrokeCapRound: true,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: true,
cutOffY: startPrice,
applyCutOffY: true,
gradient: LinearGradient(
colors: [
Colors.green.withValues(alpha: 0.3),
Colors.green.withValues(alpha: 0.05),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
),
],
minX: 0,
maxX: 6,
minY: minY - (maxY - minY) * 0.1,
maxY: maxY + (maxY - minY) * 0.1,
),
),
),
),
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
'Issue: When switching between datasets with very different Y-axis ranges,\n'
'vertical lines/glitches appear during the animation transition.',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red),
),
),
],
),
);
}
}
```

Steps to reproduce:
Run the code above
Tap the button to switch between datasets
Observe vertical lines/glitches appearing during the animation transition
Expected behavior
The chart should smoothly animate between different datasets without showing vertical line artifacts, similar to how financial apps like Yahoo Finance handle chart transitions.

Screenshots
Image

Versions
Flutter version: 3.35.4 (channel stable)
Dart version: 3.9.2
fl_chart version: 1.0.0

Contributor guide

Open the contributing guide

Research direction

Start by running the reproducible example in main.dart with fl_chart 1.0.0 and switching between the two datasets to observe the reported animation artifacts. Trace the LineChart animation path, then verify completion by repeating the transition and confirming that no vertical lines or glitches appear.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
frontend, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.