fl_chart
fl_chart copied to clipboard
not responding application when changing values
Hello,
I found a bug where my application go to not responding when changing the values from big values to small values
I debugged it a little and I think its because of this infinite loop in your code:
while (verticalSeek <= data.maxY) {
in drawTitles (chart\line_chart\line_chart_painter.dart)
is there any workaround at the moment?
the values before: 0.0 222223.0 0.1 177778.6 0.2 133334.2 0.3 88889.8 0.4 44445.4 0.5 1.0 0.6 -44443.4 0.7 -88887.8 0.8 -133332.2 0.9 -177776.6 1.0 -222221.0
minY = -250000 maxY = 255000 minX = 0.0 maxX = 1.0
the values after change: 0.0 2.0 0.1 1.8 0.2 1.6 0.3 1.4 0.4 1.2 0.5 1.0 0.6 0.8 0.7 0.6 0.8 0.4 0.9 0.2 1.0 0.0
minY = 0.0 maxY = 2.04 minX = 0.0 maxX = 1.0
When I go to this values directly, the bug happen.
Versions Flutter 2.10.0 • channel stable fl_chart: ^0.45.0
Hi. Please put your reproducible code.
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'dart:math';
void main() {
runApp(const MyApp());
}
class NiceScale {
late double _niceMin, _niceMax;
late double _tickSpacing;
double get tickSpacing { return _tickSpacing; }
double get niceMin{ return _niceMin; }
double get niceMax{ return _niceMax; }
late double _minPoint, _maxPoint;
late double _maxTicks;
late double _range;
NiceScale(double minP, double maxP, double maxTicks){
_minPoint = minP;
_maxPoint = maxP;
_maxTicks = maxTicks;
_calculate();
}
void _calculate(){
_range = _niceNum(_maxPoint - _minPoint, false);
_tickSpacing = _niceNum(_range / (_maxTicks - 1), true);
_niceMin = _calcMin();
_niceMax = _calcMax();
}
double _calcMin() {
int floored = (_minPoint / _tickSpacing).floor();
return floored * _tickSpacing;
}
double _calcMax() {
int ceiled = (_maxPoint / _tickSpacing).ceil();
return ceiled * _tickSpacing;
}
double _niceNum(double range, bool round){
double exponent = (log(range)/ln10).floor().toDouble();
double fraction = range / pow(10, exponent);
double niceFraction; /** nice, rounded fraction */
if (round)
{
if (fraction < 1.5){
niceFraction = 1;
}
else if (fraction < 3){
niceFraction = 2;
}
else if (fraction < 7){
niceFraction = 5;
}
else {
niceFraction = 10;
}
}
else
{
if (fraction <= 1){
niceFraction = 1;
}
else if (fraction <= 2){
niceFraction = 2;
}
else if (fraction <= 5){
niceFraction = 5;
}
else {
niceFraction = 10;
}
}
return niceFraction * pow(10, exponent);
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double val = 0;
@override
Widget build(BuildContext context) {
List<FlSpot> primaryData = [];
for(int i = 0; i <= 10; i++){
primaryData.add(FlSpot(0.1 * i, val*i));
}
double minX = 0;
double maxX = 1;
double xInterval = 0.1;
double yInterval = 0.1;
double minY = 0;
double maxY = val*10;
if(minX == maxX){
maxX += 1;
}
NiceScale nsx = NiceScale(minX, maxX, 15);
xInterval = nsx.tickSpacing;
minX = nsx.niceMin;
maxX = nsx.niceMax;
if(minY == maxY){
maxY += 1;
}
NiceScale nsy = NiceScale(minY, maxY, 10);
yInterval = nsy.tickSpacing;
minY = nsy.niceMin;
maxY = nsy.niceMax+(0.02*nsy.niceMax);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(children: [
SizedBox(
width: 200,
height: 40,
child: TextField(
onChanged: (s){
setState(() {
val = double.parse(s);
});
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter a value',
),
),
),
SizedBox(
width: 500,
height: 500,
child: LineChart(
LineChartData(
gridData: FlGridData(
show: true,
drawHorizontalLine: true,
drawVerticalLine: true,
horizontalInterval: yInterval,
verticalInterval: xInterval,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.grey,
strokeWidth: 0.4,
);
},
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.grey,
strokeWidth: 0.4,
);
},
),
lineTouchData: LineTouchData(
enabled: false
),
titlesData: FlTitlesData(
rightTitles: SideTitles(showTitles: false),
topTitles: SideTitles(showTitles: false),
bottomTitles: SideTitles(showTitles: true,interval: xInterval),
leftTitles: SideTitles(showTitles: true,reservedSize: 40, interval: yInterval),
),
clipData: FlClipData(top: false, bottom: true, left: true, right: false),
axisTitleData: FlAxisTitleData(
leftTitle: AxisTitle(
titleText: "Y",
showTitle: true,
textStyle: const TextStyle(
fontSize: 20,
),
margin: -10
),
bottomTitle: AxisTitle(
titleText: "x/t",
textStyle: const TextStyle(
fontSize: 20,
),
showTitle: true
),
),
borderData: FlBorderData(show: true),
maxX: maxX,
maxY: maxY,
minX: minX,
minY: minY,
lineBarsData: [
LineChartBarData(
spots: primaryData,
isCurved: false,
dotData: FlDotData(show: false),
barWidth: 3,
colors: [
Colors.red,
],
),
LineChartBarData(
spots: const [FlSpot(0, 0), FlSpot(1, 1)],
isCurved: false,
show: false,
dotData: FlDotData(show: false),
barWidth: 3,
colors: [
Colors.red,
],
)
],
),
)
),
],),
)
);
}
}
what i found is when i remove interval: yInterval
, the problem is solved !!!
to reproduce the bug. write 222222 in the textField. then select all the text and type 1 dont delete number by number
to reproduce the bug. write 222222 in the textField. then select all the text and type 1 dont delete number by number
It worked well with the latest version of the fl_chart 0.60.0
. Can you please check it again and let me know whether it fixed or not?