google / charts

https://pub.dev/packages/charts_flutter
Apache License 2.0
2.81k stars 1.23k forks source link

Slow performance on scroll #476

Open xolott opened 4 years ago

xolott commented 4 years ago

I have a DraggableScrollableSheet with a ListView, and inside that some flutter charts. When the draggable scrollable sheet go from minChildSize to maxChildSize the charts are constantly rebuilt, so it's laggy and with poor performance.

In this video, you can see what I mean. This is from the android emulator but is the same on my Huawei P30 Pro

This is the code:

class SummaryPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      // alignment: Alignment.topCenter,
      children: <Widget>[
        Column(
          children: <Widget>[
            const SizedBox(
              height: 120.0,
            ),
            const SizedBox(height: 24.0),
            CountrySelector(),
            const SizedBox(height: 24.0),
            ConfirmedCases(),
            const SizedBox(height: 24.0),
            DiseaseSummary(),
          ],
        ),
        DraggableScrollableSheet(
          maxChildSize: 1.0,
          initialChildSize: 0.4,
          minChildSize: 0.4,
          expand: true,
          builder: (ctx, scrollController) =>
              NotificationListener<OverscrollIndicatorNotification>(
            onNotification: (overscroll) {
              overscroll.disallowGlow();
              return null;
            },
            child: ListView(
              controller: scrollController,
              children: [
                SummaryCharts(),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

class SummaryCharts extends StatelessWidget {
  const SummaryCharts({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Container(width: double.infinity, height: 200, color: Colors.red),
        Container(
          padding: const EdgeInsets.all(16.0),
          decoration: BoxDecoration(
            color: Colors.white,
          ),
          child: Column(
            children: <Widget>[
              ProgressChart(),
              SizedBox(
                height: 16.0,
              ),
              ProgressChart(),
              SizedBox(
                height: 16,
              ),
              ProgressChart(),
            ],
          ),
        ),
      ],
    );
  }
}

class ProgressChart extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return PhysicalShape(
      elevation: 5,
      clipBehavior: Clip.antiAliasWithSaveLayer,
      color: Colors.transparent,
      clipper: ShapeBorderClipper(
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(32.0))),
      child: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          color: Colors.white,
        ),
        padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 18.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Text(
                  'DATA HISTORY',
                  style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                    fontSize: 12.0,
                  ),
                ),
                Row(
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        Container(
                          width: 16.0,
                          height: 16.0,
                          decoration: BoxDecoration(
                            color: Theme.of(context).primaryColor,
                            borderRadius: BorderRadius.circular(8.0),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(left: 4.0),
                          child: Text(
                            'Confirmed',
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: 9.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        )
                      ],
                    ),
                    SizedBox(
                      width: 12.0,
                    ),
                    Row(
                      children: <Widget>[
                        Container(
                          width: 16.0,
                          height: 16.0,
                          decoration: BoxDecoration(
                            color: Color(0xFF69FF98),
                            borderRadius: BorderRadius.circular(8.0),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.only(left: 4.0),
                          child: Text(
                            'Recovered',
                            style: TextStyle(
                              color: Colors.black,
                              fontSize: 9.0,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        )
                      ],
                    )
                  ],
                )
              ],
            ),
            Container(
              height: 250,
              padding: const EdgeInsets.only(top: 12.0),
              child: BlocBuilder<CovidStatisticsBloc, CovidStatisticsState>(
                builder: (ctx, state) => charts.TimeSeriesChart(
                  _createSeries(
                    ctx,
                    state.stats.historicalConfirmed,
                    state.stats.historicalRecovered,
                  ),
                  animate: false,
                  customSeriesRenderers: [
                    charts.LineRendererConfig(
                      customRendererId: 'cases_series',
                      includeArea: true,
                      includePoints: true,
                      radiusPx: 4.0,
                      areaOpacity: 0.4,
                    ),
                    charts.LineRendererConfig(
                      customRendererId: 'recovered_series',
                      includeArea: true,
                      includePoints: true,
                      radiusPx: 4.0,
                      areaOpacity: 0.4,
                    )
                  ],
                  domainAxis: charts.DateTimeAxisSpec(
                    renderSpec: charts.SmallTickRendererSpec(
                      labelStyle: charts.TextStyleSpec(
                        fontFamily: 'Mali',
                        fontSize: 12,
                        lineHeight: 2,
                        color: charts.Color(
                          a: 0xFF,
                          r: 0x68,
                          g: 0x81,
                          b: 0x8F,
                        ),
                      ),
                      lineStyle: charts.LineStyleSpec(
                        thickness: 5,
                        color: charts.Color(
                          a: 0xFF,
                          r: 0xCD,
                          g: 0xD5,
                          b: 0xDA,
                        ),
                      ),
                    ),
                  ),
                  primaryMeasureAxis: charts.NumericAxisSpec(
                    tickFormatterSpec: charts.BasicNumericTickFormatterSpec(
                        (value) => NumberFormat.compact().format(value)),
                    renderSpec: charts.SmallTickRendererSpec(
                      labelStyle: charts.TextStyleSpec(
                        fontFamily: 'Mali',
                        fontSize: 12,
                        lineHeight: 2,
                        color: charts.Color(
                          a: 0xFF,
                          r: 0x68,
                          g: 0x81,
                          b: 0x8F,
                        ),
                      ),
                      lineStyle: charts.LineStyleSpec(
                        thickness: 5,
                        color: charts.Color(
                          a: 0xFF,
                          r: 0xCD,
                          g: 0xD5,
                          b: 0xDA,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}
zhuwei commented 4 years ago

me too! my head hurts!