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

Issue when using PanAndZoomBehavior if we add the charts inside ScrollView. #36

Open
npatil-augsys opened this issue Dec 27, 2024 · 0 comments

Comments

@npatil-augsys
Copy link

We are currently using a Time Series chart with multiple charts displayed on the same screen. When these charts are added inside a SingleChildScrollView, the PanAndZoomBehavior stops functioning correctly. However, if we set the physics of the SingleChildScrollView to NeverScrollableScrollPhysics, the PanAndZoomBehavior works perfectly.

It seems that both the SingleChildScrollView and the charts are unable to correctly interpret the user input when attempting to pan or zoom the charts.

Has anyone else encountered a similar issue? If so, how did you resolve it?

Below is the sample code for the chart implementation and the class where we combine the charts together.

SimpleTimeSeriesChart.dart -

class SimpleTimeSeriesChart extends StatelessWidget {
  final List<charts.Series<TimeSeriesSales, DateTime>> seriesList;
  final bool animate;

  const SimpleTimeSeriesChart(this.seriesList, {super.key, this.animate = false});

  /// Creates a [TimeSeriesChart] with sample data and no transition.
  factory SimpleTimeSeriesChart.withSampleData() {
    return SimpleTimeSeriesChart(
      _createSampleData(),
      // Disable animations for image tests.
      animate: false,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      height: 200,
      child: charts.TimeSeriesChart(
        seriesList,
        animate: animate,
        primaryMeasureAxis: charts.NumericAxisSpec(
          renderSpec: charts.GridlineRendererSpec(
            lineStyle: charts.LineStyleSpec(
              color: charts.MaterialPalette.gray.shadeDefault,
              dashPattern: const [1, 1],
              thickness: 1,
            ),
            labelStyle: const charts.TextStyleSpec(
              fontSize: 12,
              color: charts.MaterialPalette.black,
            ),
          ),
        ),
        behaviors: [
          charts.PanAndZoomBehavior(),
          charts.SeriesLegend(),
        ],
      ),
    );
  }

  /// Create one series with sample hard coded data.
  static List<charts.Series<TimeSeriesSales, DateTime>> _createSampleData() {
    final data = [
      TimeSeriesSales(DateTime(2017, 9, 3), 5),
      TimeSeriesSales(DateTime(2017, 9, 7), 25),
      TimeSeriesSales(DateTime(2017, 9, 12), 30),
      TimeSeriesSales(DateTime(2017, 9, 16), 72),
      TimeSeriesSales(DateTime(2017, 9, 20), 50),
      TimeSeriesSales(DateTime(2017, 9, 25), 54),
      TimeSeriesSales(DateTime(2017, 9, 30), 60),
      TimeSeriesSales(DateTime(2017, 10, 1), 75),
      TimeSeriesSales(DateTime(2017, 10, 3), 77),
      TimeSeriesSales(DateTime(2017, 10, 8), 80),
      TimeSeriesSales(DateTime(2017, 10, 12), 100),
      TimeSeriesSales(DateTime(2017, 10, 17), 82),
      TimeSeriesSales(DateTime(2017, 10, 22), 51),
      TimeSeriesSales(DateTime(2017, 10, 28), 41),
      TimeSeriesSales(DateTime(2017, 11, 5), 43),
      TimeSeriesSales(DateTime(2017, 11, 8), 32),
    ];

    return [
      charts.Series<TimeSeriesSales, DateTime>(
        id: 'Sales',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
        domainFn: (TimeSeriesSales sales, _) => sales.time,
        measureFn: (TimeSeriesSales sales, _) => sales.sales,
        data: data,
      ),
    ];
  }
}

/// Sample time series data type.
class TimeSeriesSales {
  final DateTime time;
  final int sales;

  TimeSeriesSales(this.time, this.sales);
}

ChartScreen.dart -

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

  @override
  State<ChartScreen> createState() => _ChartScreenState();
}

class _ChartScreenState extends State<ChartScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Chart"),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsetsDirectional.only(bottom: 20),
        child: Column(
          children: [
            SimpleTimeSeriesChart.withSampleData(),
            const SizedBox(
              height: 4,
            ),
            SimpleTimeSeriesChart.withSampleData(),
            const SizedBox(
              height: 4,
            ),
            SimpleTimeSeriesChart.withSampleData(),
            const SizedBox(
              height: 4,
            ),
            SimpleTimeSeriesChart.withSampleData(),
            const SizedBox(
              height: 4,
            ),
            SimpleTimeSeriesChart.withSampleData(),
            const SizedBox(
              height: 4,
            ),
            SimpleTimeSeriesChart.withSampleData(),
            const SizedBox(
              height: 4,
            ),
            SimpleTimeSeriesChart.withSampleData(),
          ],
        ),
      ),
    );
  }
}

Video ref -

  1. With Scrollable Physics
scrollclip.mov
  1. Without Never Scrollable Scroll Physics
noscrollclip.mov
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant