fl_chart icon indicating copy to clipboard operation
fl_chart copied to clipboard

not responding application when changing values

Open hamzaj9 opened this issue 3 years ago • 3 comments

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

image


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

hamzaj9 avatar Feb 14 '22 06:02 hamzaj9

Hi. Please put your reproducible code.

imaNNeo avatar Feb 14 '22 18:02 imaNNeo

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 !!!

hamzaj9 avatar Feb 15 '22 12:02 hamzaj9

to reproduce the bug. write 222222 in the textField. then select all the text and type 1 dont delete number by number

hamzaj9 avatar Feb 16 '22 14:02 hamzaj9

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?

imaNNeo avatar Jan 30 '23 21:01 imaNNeo