Fl_chart: After upgrading to flutter 2.0, pie chart is not displayed

Created on 5 Mar 2021  路  15Comments  路  Source: imaNNeoFighT/fl_chart

After upgrading to flutter 2.0, pie chart is not displayed

It was working previously with this code. (with some computation in abstraction)

           PieChart(
                  PieChartData(
                    borderData: FlBorderData(show: false),
                    sections: FlChartUtils.getPieChartData(
                        activityDistribution, "KM"),
                    centerSpaceRadius: 0,
                    sectionsSpace: 2,
                  ),
                )

flutter: 2.0 stable
fl_chart: ^0.12.2

Is there anything that I am missing or it has to do with some changes in flutter?

Pie Chart bug

All 15 comments

I came here to report the same bug. It does render in the web version, it doesn't in Android.

class PercentagePie extends StatelessWidget {
  final double total;
  final double value;
  final double size;

  PercentagePie({@required double total, @required double value, double size = 96})
      : this.total = total < 1.0 ? 1.0 : total,
        this.value = value,
        this.size = size;

  @override
  Widget build(BuildContext context) {
    Color idlecolor = Colors.blueGrey[100];
    Color activecolor = Colors.green;
    double idlevalue;
    double activevalue;

    if (value > total) {
      /* overflow */
      activevalue = value % total;
      idlevalue = total - activevalue;
      if (value < total * 2) {
        activecolor = Colors.red;
        idlecolor = Colors.green;
      } else {
        activecolor = Colors.purple;
        idlecolor = Colors.red;
      }
    } else {
      /* okay */
      idlevalue = total - value;
      activevalue = value;
    }

   print('value ${value} total ${total}');

    return SizedBox(
      height: size,
      width: size,
      child: Container(
        child: Stack(
          children: <Widget>[
            Center(
              child: Text(
                '${(value / total * 100).toInt()}%',
              ),
            ),

            Center(
              child: PieChart(
                PieChartData(
                  startDegreeOffset: 270,
                  sectionsSpace: .5,
                  centerSpaceRadius: size / 2 - 12,
                  borderData: FlBorderData(
                    show: true,
                  ),
                  sections: [
                    PieChartSectionData(
                      color: activecolor,
                      value: activevalue,
                      showTitle: false,
                      radius: 12,
                    ),
                    PieChartSectionData(
                      color: idlecolor,
                      value: idlevalue,
                      showTitle: false,
                      radius: 12,
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

My pie charts are rendered after upgrading to Flutter 2.0, but now they're on top of each other. This happens on both iOS and Android.
Screenshot 2021-03-07 at 12 57 09

Guys if you don't provide me a reproducible code (As I mentioned in the issues guideline) I cannot test it.
I need a full reproducible code that contains a main() function and other stuff to run.

Thanks!

Reproduceable code appended at the end:
image

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _scrollViewController = ScrollController(initialScrollOffset: 0.0);

  @override
  void dispose() {
    _scrollViewController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> _buildAppBar(BuildContext context, bool isScrolled) {
      return <Widget>[SliverAppBar(title: Text('Test'), floating: true, pinned: false, snap: false)];
    }

    Widget buildBody() {
      return SingleChildScrollView(
        child: Padding(
          padding: EdgeInsetsDirectional.only(start: 5, end: 5, top: 5, bottom: 5),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [SizedBox(child: DonutChartAllTime(), height: 250)],
          ),
        ),
      );
    }

    return NestedScrollView(
      controller: _scrollViewController,
      floatHeaderSlivers: true,
      headerSliverBuilder: _buildAppBar,
      body: buildBody(),
    );
  }
}

class DonutChartAllTime extends StatefulWidget {
  @override
  _DonutChartAllTimeState createState() => _DonutChartAllTimeState();
}

class _DonutChartAllTimeState extends State<DonutChartAllTime> {
  List<DonutPieChartData> chartData;
  double _pieRadius = 40.0;
  double _chartHeight = 80;
  double _centerRadius = 0.0;
  double centerRadius = 50;
  double _totalAmount = 0.0;
  int _touchedIndex;

  @override
  void initState() {
    super.initState();
    chartData = _generateData();

    if (chartData.isNotEmpty) {
      chartData.forEach((element) {
        _totalAmount += element.value ?? 0.0;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: EdgeInsets.all(10),
        child: LayoutBuilder(builder: (context, constraints) {
          _chartHeight = constraints.maxHeight == double.infinity ? 200.0 : constraints.maxHeight;
          _centerRadius = (_chartHeight / 2) * centerRadius / 100;
          _pieRadius = (_chartHeight / 2) - _centerRadius;

          return SizedBox(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.end,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Flexible(
                    child: PieChart(
                      PieChartData(
                        pieTouchData: PieTouchData(touchCallback: (pieTouchResponse) {
                          setState(() {
                            if (pieTouchResponse.touchInput is FlLongPressEnd || pieTouchResponse.touchInput is FlPanEnd) {
                              _touchedIndex = -1;
                            } else {
                              _touchedIndex = pieTouchResponse.touchedSectionIndex;
                            }
                          });
                        }),
                        borderData: FlBorderData(show: false),
                        centerSpaceRadius: _centerRadius,
                        startDegreeOffset: 270,
                        sections: _buildPieSlices(),
                      ),
                    ),
                    flex: 2),
                SizedBox(width: 10),
                //Flexible(child: _buildLegend(), flex: 1),
              ],
            ),
          );
        }),
      ),
    );
  }

  List<PieChartSectionData> _buildPieSlices() {
    return chartData
        .asMap()
        .map(
          (index, it) {
            final isTouched = index == _touchedIndex;
            final _titleStyle = isTouched
                ? Theme.of(context).textTheme.headline6.copyWith(fontSize: 13)
                : Theme.of(context).textTheme.headline6;
            final radius = isTouched ? _pieRadius * 1.2 : _pieRadius;

            return MapEntry(
              index,
              PieChartSectionData(
                color: it.color,
                value: it.value / _totalAmount * 100,
                title: it.value.toString(),
                showTitle: true,
                radius: radius,
                titleStyle: _titleStyle,
              ),
            );
          },
        )
        .values
        .toList(growable: false);
  }

  List<DonutPieChartData> _generateData() {
    var _pieData = <DonutPieChartData>[
      DonutPieChartData(value: 10, legendText: 'A', color: Colors.green),
      DonutPieChartData(value: 30, legendText: 'B', color: Colors.blue),
      DonutPieChartData(value: 50, legendText: 'C', color: Colors.orange),
    ];

    return _pieData;
  }
}

class DonutPieChartData {
  final double value;
  final String legendText;
  Color color;

  DonutPieChartData({
    @required double value,
    @required String legendText,
    @required Color color,
  })  : value = value ?? 0.0,
        legendText = legendText ?? '',
        color = color ?? Colors.white;
}

I have the same issue, my piechart is gone! As you can see, the titles still render. I'm on Flutter stable 2.0.1.

PieChart(
      PieChartData(

        borderData: FlBorderData(
          show: false,
        ),
        sectionsSpace: 4,
        centerSpaceRadius: 40,
        sections: showingSections(),
      ),
      swapAnimationDuration: Duration(milliseconds: 600),
    ),


List<PieChartSectionData> showingSections() {
    return List.generate(
      4,
      (i) {
        final isTouched = i == touchedIndex;
        final double opacity = isTouched ? 1 : 1; // 0.6;
        switch (i) {
          case 0:
            // sub rev
            return PieChartSectionData(
              color: const Color(0xff6486ff).withOpacity(opacity),
              value: totalRev > 0 ? subRev : 25,
              showTitle: subRev > 0, //isTouched,
              title: "\$${subRev.toStringAsFixed(2)}",
              radius: 40,
              titleStyle: GoogleFonts.poppins(
                textStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w300, color: Theme.of(context).textTheme.bodyText1.color),
              ),
              titlePositionPercentageOffset: 0.5,
            );
          case 1:
            // locked message
            return PieChartSectionData(
              color: Theme.of(context).accentColor.withOpacity(opacity),
              value: totalRev > 0 ? lockMsgRev : 25,
              showTitle: lockMsgRev > 0, //isTouched,
              title: "\$${lockMsgRev.toStringAsFixed(2)}",
              radius: 40,
              titleStyle: GoogleFonts.poppins(
                textStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w300, color: Theme.of(context).textTheme.bodyText1.color),
              ),
              titlePositionPercentageOffset: 0.5,
            );
          case 2:
            // chat tips
            return PieChartSectionData(
              color: const Color(0xff845bef).withOpacity(opacity),
              value: totalRev > 0 ? chatTipRev : 25,
              showTitle: chatTipRev > 0, //isTouched,
              title: "\$${chatTipRev.toStringAsFixed(2)}",
              radius: 40,
              titleStyle: GoogleFonts.poppins(
                textStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w300, color: Theme.of(context).textTheme.bodyText1.color),
              ),
              titlePositionPercentageOffset: 0.5,
            );
          case 3:
            // post tips
            return PieChartSectionData(
              color: const Color(0xFFff944d).withOpacity(opacity),
              value: totalRev > 0 ? postTipRev : 25,
              showTitle: postTipRev > 0, // isTouched,
              title: "\$${postTipRev.toStringAsFixed(2)}",
              radius: 40,
              titleStyle: GoogleFonts.poppins(
                textStyle: TextStyle(fontSize: 12, fontWeight: FontWeight.w300, color: Theme.of(context).textTheme.bodyText1.color),
              ),
              titlePositionPercentageOffset: 0.5,
            );
          default:
            return null;
        }
      },
    );
  } 

image

Yes it could be a lot of trouble. After this new release(0.20.0) for fl_chart, the pie chart is not getting loaded for the earlier versions up to 0.12.1. I tried it is working again with the old version 0.12.1. Could you please check this team asap.

Reproduceable code appended at the end:
image

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

...
    @required Color color,
  })  : value = value ?? 0.0,
        legendText = legendText ?? '',
        color = color ?? Colors.white;
}

Here is my result wit fl_chart 0.20.1:

image

image

As I wrote, it does render in the web. It doesn't on Android.

You are right. I'm on it

I think something is changed in the Flutter SDK.

Pie chart has become unstable after v0.12.1, looks like an exception was fixed in PR #535 but it introduced new bugs. Don't think there is any issue with Flutter 2 since it works just fine with Flutter 2.0.1 and fl_chart: 0.12.0

Please checkout this stackoverflow question/answer:
https://stackoverflow.com/questions/65970061/flutter-web-unsupported-operation-nan-error-for-canvas-in-card-widget

To sum it up, the pie chart doesn't work by default in web due to a error Unsupported operation: NaN or in my case, Unsupported operation: NaN.ceil(). It causes a complete web app crash causing a reload of the page.

The fix (for web at least) is to build using --web-renderer canvaskit then the issue is resolved, although this build method comes with a larger build and slower loading times. I am using Flutter 2.0 and the Pie chart is working well for me in production (now, after using canvaskit). It also works on iOS and android.

Somebody please @ me if there is a solution better than a canvaskit build.

Here is my working chart code if anybody is curious as it seems it won't work at all for some people:

flChart.PieChart(flChart.PieChartData(
            borderData: flChart.FlBorderData(show: false),
            sections: (dataUsed).map<flChart.PieChartSectionData>((tag) {
              return flChart.PieChartSectionData(
                value: tag.size,
                color: tag.pointColor.withOpacity(0.7),
                radius: 80,
                showTitle: true,
                title: (SharedFunctions().moneyOverflow(SharedFunctions().formatMoney(tag.text))),
                titleStyle: TextStyle(
                  fontFamily: 'Metropolis-Regular',
                  color: Colors.black,
                  fontSize: 10
                )
              );
            }).toList(),
            )

Hi, at the moment, we have changed our draw approach. Now we use RenderObjects for drawing, sizing, and touches. (previously, we used CustomPainter).
RenderObjects is more stable and error-prone. Please check this issue with our new release 0.30.0. Let me know whether it has been fixed or not.

It's working for me in 0.30.0

Thank you

Great!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kw2019ltd picture kw2019ltd  路  6Comments

satrio1256 picture satrio1256  路  6Comments

S1nPur1ty picture S1nPur1ty  路  4Comments

davidmarinangeli picture davidmarinangeli  路  6Comments

jitenders859 picture jitenders859  路  5Comments