Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When pressing the LineChart, and change the data of the chart, will throw a RangeError #1187

Closed
taichushouwang opened this issue Nov 22, 2022 · 2 comments · Fixed by #1205
Closed
Labels
bug Something isn't working Line Chart

Comments

@taichushouwang
Copy link

taichushouwang commented Nov 22, 2022

Describe the bug
Hello, we encountered a problem in the process of developing requirements. We use the LineChart to show some data, but the length of the data is not sure. If user press the chart, it will show a bubble. But if the user switch the data source while pressing the chart, it will throw a RangeError, if the new data shorter than the old data.

Just like the samle2. If I add a Spot, just like FlSpot(12, 3.44), to the avgData. And set avgData to lineTouchData: LineTouchData(enabled: true).Then I switch avg to main while I pressing the last spot of avgData. Then it will has a RangeError.

The following RangeError was thrown during paint():
RangeError (index): Invalid value: Not in inclusive range 0..6: 7

The relevant error-causing widget was: 
  LineChartLeaf LineChartLeaf:file:///fl_chart/lib/src/chart/line_chart/line_chart.dart:55:14
When the exception was thrown, this was the stack: 
#0      _Array.[] (dart:core-patch/array.dart:10:36)
#1      LineChartPainter.paint (package:fl_chart/src/chart/line_chart/line_chart_painter.dart:128:35)
#2      RenderLineChart.paint (package:fl_chart/src/chart/line_chart/line_chart_renderer.dart:94:13)
#3      RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#4      PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#5      RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:84:15)
#6      RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#7      PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#8      RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:144:15)
#9      RenderDecoratedBox.paint (package:flutter/src/rendering/proxy_box.dart:2371:11)
#10     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#11     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#12     RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:84:15)
#13     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#14     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#15     RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2900:15)
#16     RenderStack.paintStack (package:flutter/src/rendering/stack.dart:654:5)
#17     RenderStack.paint (package:flutter/src/rendering/stack.dart:670:7)
#18     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#19     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#20     _RenderLayoutBuilder.paint (package:flutter/src/widgets/layout_builder.dart:341:15)
#21     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#22     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#23     RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:84:15)
#24     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#25     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#26     RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:144:15)
#27     RenderDecoratedBox.paint (package:flutter/src/rendering/proxy_box.dart:2371:11)
#28     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#29     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#30     RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:144:15)
#31     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#32     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#33     RenderBoxContainerDefaultsMixin.defaultPaint (package:flutter/src/rendering/box.dart:2900:15)
#34     RenderStack.paintStack (package:flutter/src/rendering/stack.dart:654:5)
#35     RenderStack.paint (package:flutter/src/rendering/stack.dart:670:7)
#36     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#37     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#38     RenderShiftedBox.paint (package:flutter/src/rendering/shifted_box.dart:84:15)
#39     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#40     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:239:13)
#41     RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:144:15)
#42     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2796:7)
#43     PaintingContext._repaintCompositedChild (package:flutter/src/rendering/object.dart:155:11)
#44     PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:98:5)
#45     PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1116:31)
#46     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:515:19)
#47     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:884:13)
#48     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:378:5)
#49     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15)
#50     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1104:9)
#51     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5)
#52     _invoke (dart:ui/hooks.dart:148:13)
#53     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#54     _drawFrame (dart:ui/hooks.dart:115:31)
The following RenderObject was being processed when the exception was fired: RenderLineChart#9624f relayoutBoundary=up4
...  parentData: offset=Offset(1.0, 1.0) (can use size)
...  constraints: BoxConstraints(0.0<=w<=262.7, 0.0<=h<=130.1)
...  size: Size(262.7, 130.1)
RenderObject: RenderLineChart#9624f relayoutBoundary=up4
  parentData: offset=Offset(1.0, 1.0) (can use size)
  constraints: BoxConstraints(0.0<=w<=262.7, 0.0<=h<=130.1)
  size: Size(262.7, 130.1)

To Reproduce

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

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

  @override
  State<LineChartSample2> createState() => _LineChartSample2State();
}

class _LineChartSample2State extends State<LineChartSample2> {
  List<Color> gradientColors = [
    const Color(0xff23b6e6),
    const Color(0xff02d39a),
  ];

  bool showAvg = false;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        AspectRatio(
          aspectRatio: 1.70,
          child: DecoratedBox(
            decoration: const BoxDecoration(
              borderRadius: BorderRadius.all(
                Radius.circular(18),
              ),
              color: Color(0xff232d37),
            ),
            child: Padding(
              padding: const EdgeInsets.only(
                right: 18,
                left: 12,
                top: 24,
                bottom: 12,
              ),
              child: LineChart(
                showAvg ? avgData() : mainData(),
              ),
            ),
          ),
        ),
        SizedBox(
          width: 60,
          height: 34,
          child: TextButton(
            onPressed: () {
              setState(() {
                showAvg = !showAvg;
              });
            },
            child: Text(
              'avg',
              style: TextStyle(
                fontSize: 12,
                color: showAvg ? Colors.white.withOpacity(0.5) : Colors.white,
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget bottomTitleWidgets(double value, TitleMeta meta) {
    const style = TextStyle(
      color: Color(0xff68737d),
      fontWeight: FontWeight.bold,
      fontSize: 16,
    );
    Widget text;
    switch (value.toInt()) {
      case 2:
        text = const Text('MAR', style: style);
        break;
      case 5:
        text = const Text('JUN', style: style);
        break;
      case 8:
        text = const Text('SEP', style: style);
        break;
      case 11:
        text = const Text('DEC', style: style);
        break;
      default:
        text = const Text('', style: style);
        break;
    }

    return SideTitleWidget(
      axisSide: meta.axisSide,
      child: text,
    );
  }

  Widget leftTitleWidgets(double value, TitleMeta meta) {
    const style = TextStyle(
      color: Color(0xff67727d),
      fontWeight: FontWeight.bold,
      fontSize: 15,
    );
    String text;
    switch (value.toInt()) {
      case 1:
        text = '10K';
        break;
      case 3:
        text = '30k';
        break;
      case 5:
        text = '50k';
        break;
      default:
        return Container();
    }

    return Text(text, style: style, textAlign: TextAlign.left);
  }

  LineChartData mainData() {
    return LineChartData(
      gridData: FlGridData(
        show: true,
        drawVerticalLine: true,
        horizontalInterval: 1,
        verticalInterval: 1,
        getDrawingHorizontalLine: (value) {
          return FlLine(
            color: const Color(0xff37434d),
            strokeWidth: 1,
          );
        },
        getDrawingVerticalLine: (value) {
          return FlLine(
            color: const Color(0xff37434d),
            strokeWidth: 1,
          );
        },
      ),
      titlesData: FlTitlesData(
        show: true,
        rightTitles: AxisTitles(
          sideTitles: SideTitles(showTitles: false),
        ),
        topTitles: AxisTitles(
          sideTitles: SideTitles(showTitles: false),
        ),
        bottomTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            reservedSize: 30,
            interval: 1,
            getTitlesWidget: bottomTitleWidgets,
          ),
        ),
        leftTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            interval: 1,
            getTitlesWidget: leftTitleWidgets,
            reservedSize: 42,
          ),
        ),
      ),
      borderData: FlBorderData(
        show: true,
        border: Border.all(color: const Color(0xff37434d)),
      ),
      minX: 0,
      maxX: 11,
      minY: 0,
      maxY: 6,
      lineBarsData: [
        LineChartBarData(
          spots: const [
            FlSpot(0, 3),
            FlSpot(2.6, 2),
            FlSpot(4.9, 5),
            FlSpot(6.8, 3.1),
            FlSpot(8, 4),
            FlSpot(9.5, 3),
            FlSpot(11, 4),
          ],
          isCurved: true,
          gradient: LinearGradient(
            colors: gradientColors,
          ),
          barWidth: 5,
          isStrokeCapRound: true,
          dotData: FlDotData(
            show: false,
          ),
          belowBarData: BarAreaData(
            show: true,
            gradient: LinearGradient(
              colors: gradientColors
                  .map((color) => color.withOpacity(0.3))
                  .toList(),
            ),
          ),
        ),
      ],
    );
  }

  LineChartData avgData() {
    return LineChartData(
      lineTouchData: LineTouchData(enabled: true),
      gridData: FlGridData(
        show: true,
        drawHorizontalLine: true,
        verticalInterval: 1,
        horizontalInterval: 1,
        getDrawingVerticalLine: (value) {
          return FlLine(
            color: const Color(0xff37434d),
            strokeWidth: 1,
          );
        },
        getDrawingHorizontalLine: (value) {
          return FlLine(
            color: const Color(0xff37434d),
            strokeWidth: 1,
          );
        },
      ),
      titlesData: FlTitlesData(
        show: true,
        bottomTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            reservedSize: 30,
            getTitlesWidget: bottomTitleWidgets,
            interval: 1,
          ),
        ),
        leftTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            getTitlesWidget: leftTitleWidgets,
            reservedSize: 42,
            interval: 1,
          ),
        ),
        topTitles: AxisTitles(
          sideTitles: SideTitles(showTitles: false),
        ),
        rightTitles: AxisTitles(
          sideTitles: SideTitles(showTitles: false),
        ),
      ),
      borderData: FlBorderData(
        show: true,
        border: Border.all(color: const Color(0xff37434d)),
      ),
      minX: 0,
      maxX: 12,
      minY: 0,
      maxY: 6,
      lineBarsData: [
        LineChartBarData(
          spots: const [
            FlSpot(0, 3.44),
            FlSpot(2.6, 3.44),
            FlSpot(4.9, 3.44),
            FlSpot(6.8, 3.44),
            FlSpot(8, 3.44),
            FlSpot(9.5, 3.44),
            FlSpot(11, 3.44),
            FlSpot(12, 3.44),
          ],
          isCurved: true,
          gradient: LinearGradient(
            colors: [
              ColorTween(begin: gradientColors[0], end: gradientColors[1])
                  .lerp(0.2)!,
              ColorTween(begin: gradientColors[0], end: gradientColors[1])
                  .lerp(0.2)!,
            ],
          ),
          barWidth: 5,
          isStrokeCapRound: true,
          dotData: FlDotData(
            show: false,
          ),
          belowBarData: BarAreaData(
            show: true,
            gradient: LinearGradient(
              colors: [
                ColorTween(begin: gradientColors[0], end: gradientColors[1])
                    .lerp(0.2)!
                    .withOpacity(0.1),
                ColorTween(begin: gradientColors[0], end: gradientColors[1])
                    .lerp(0.2)!
                    .withOpacity(0.1),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

Versions
I'm in FlChart 0.55.2.

Looking forward to your reply。

imaNNeo added a commit that referenced this issue Jan 15, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@imaNNeo imaNNeo added bug Something isn't working Line Chart labels Jan 15, 2023
imaNNeo added a commit that referenced this issue Jan 15, 2023

Verified

This commit was signed with the committer’s verified signature.
crazy-max CrazyMax
@imaNNeo imaNNeo reopened this Jan 15, 2023
@imaNNeo
Copy link
Owner

imaNNeo commented Jan 26, 2023

Fixed in 0.60.0. Please check it out.

@imaNNeo imaNNeo closed this as completed Jan 26, 2023
@lgorkostrow
Copy link

lgorkostrow commented Dec 19, 2024

Hello @imaNNeo
I am getting the same error in the scenario that was described here but for the pie chart with badges in the pie_chart_renderer.dart on this line if (data.sections[counter].value > 0) {. It happens every time I add a new item in a parent widget that triggers the pie chart to render again in the case when sections have a badge and an animation. This piece of code runs a couple of times and it fails for the first attempt. The solution with removing the animation helped me too and it looks like the data.sections variable isn't updated before the animation is finished.

  void badgeWidgetPaint(PaintingContext context, Offset offset) {
    RenderObject? child = firstChild;
    var counter = 0;
    while (child != null) {
      final childParentData = child.parentData! as MultiChildLayoutParentData;
      if (data.sections[counter].value > 0) {
        context.paintChild(child, childParentData.offset + offset);
      }
      child = childParentData.nextSibling;
      counter++;
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Line Chart
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants