We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

How to synchronize panning in multiple charts (SfCartesianChart) ?

Platform: Flutter |
Control: SfCartesianChart |
Published Date: May 15, 2020 |
Last Revised Date: April 8, 2021

In this article, we described how to do synchronized panning in multiple charts.

 

Flutter Cartesian Chart widget can be used to do synchronized panning in multiple charts using the callback events available in the chart and keys available in Flutter framework. Callback events are callback function or a method, which you pass as an argument into another function or method and can perform an action when you require it and a key is an identifier for widgets, elements, and semantics nodes. The callback used for the synchronized panning is the onZooming event available in the chart and the GlobalKey (subclass of Key class) is used as identifier.

The following steps explain how to do synchronized panning in multiple charts.

Step 1: First, create two GlobalKey identifiers for the first and second chart’s state classes, respectively.

final cartesianChartKey = GlobalKey<CartesianChartState>();
final chartKey = GlobalKey<ChartState>();

 

Step 2: Initialize a Cartesian chart (First chart) as an individual StatefulWidget, in which the zoomFactor and the zoomPosition values are got from the onZooming event and stored globally in the variables for the second chart to use for synchronized panning by calling the refresh method of the second chart to refresh the current state of it.

class Chart extends StatefulWidget {
late ZoomPanBehavior  _zoomPanBehavior;
late TooltipBehavior _tooltipBehavior;
 
 @override
  State<StatefulWidget> createState() {
    return ChartState();
  }
}
 
@override
Void initState(){
  _zoomPanBehavior = ZoomPanBehavior(
          enablePanning: true,
          enablePinching: true,
          enableDoubleTapZooming: true,
        );
  _tooltipBehavior = TooltipBehavior(enable: true);
  super.initState();
}
 
 
class ChartState extends State<Chart> {
  @override
  Widget build(BuildContext context) {
    return SfCartesianChart(
        zoomPanBehavior: _zoomPanBehavior,
        onZooming: (ZoomPanArgs args) {
          if (args.axis.name == 'primaryXAxis') {
            zoomP = args.currentZoomPosition; // Storing the zoomPosition and the zoomFactor
            zoomF = args.currentZoomFactor; // of the first chart.
            cartesianChartKey.currentState!.chartRefresh(); // To refresh the second chart current State
          }
        },
        primaryXAxis: CategoryAxis(
            zoomFactor: 0.2, zoomPosition: 0.5, name: 'primaryXAxis'),
        primaryYAxis: NumericAxis(name: 'primaryYAxis'),
        title: ChartTitle(text: 'Chart 1'),
        tooltipBehavior: _tooltipBehavior,
        series: <LineSeries<SalesData, String>>[
          LineSeries<SalesData, String>(
              dataSource: chartData,
              xValueMapper: (SalesData sales, _) => sales.year,
              yValueMapper: (SalesData sales, _) => sales.sales
          )
        ]);
  }
}

 

The method used for refreshing the first chart is defined in the first charts state class.

class ChartState extends State<Chart> {
    void refreshChart() {
       setState(() {});
    }
}

 

Step 3: Initialize another Cartesian chart (second chart) as an individual StatefulWidget, the synchronized panning is done with the zoomFactor and zoomPosition values obtained from the onZooming event, callback events are used to refresh the current state of first chart. Thus, simultaneously synchronized panning can be done in multiple charts.

class CartesianChart extends StatefulWidget {
  CartesianChart({Key? key}) : super(key: key);
  @override
  State<StatefulWidget> createState() {
    return CartesianChartState();
  }
}
 
class CartesianChartState extends State<CartesianChart> {
  CartesianChartState({Key key});
late ZoomPanBehavior  _zoomPanBehavior;
late TooltipBehavior _tooltipBehavior;
 
@override
Void initState(){
  _zoomPanBehavior = ZoomPanBehavior(
          enablePanning: true,
          enablePinching: true,
          enableDoubleTapZooming: true,
        );
  _tooltipBehavior = TooltipBehavior(enable: true);
  super.initState();
}
 
 
  @override
  Widget build(BuildContext context) {
    return SfCartesianChart(
        zoomPanBehavior: _zoomPanBehavior,
        onZooming: (ZoomPanArgs args) {
          if (args.axis.name == 'primaryXAxis') {
            zoomP = args.currentZoomPosition; // Storing the zoomPosition and the zoomFactor
            zoomF = args.currentZoomFactor; // of the first chart.
            chartKey.currentState.refreshChart();// To refresh the first chart current State
          }
        },
        primaryXAxis: CategoryAxis(zoomFactor: zoomF, zoomPosition: zoomP),
        title: ChartTitle(text: 'Chart 2'),
        tooltipBehavior:  _tooltipBehavior,
        series: <LineSeries<SalesData, String>>[
          LineSeries<SalesData, String>(
              dataSource: chartData,
              xValueMapper: (SalesData sales, _) => sales.year,
              yValueMapper: (SalesData sales, _) => sales.sales)
        ]);
  }
}

 

The method used for refreshing the second chart is defined in the second charts state class.

class CartesianChartState extends State<CartesianChart> {
  CartesianChartState({Key key});
  void chartRefresh() {
    setState(() {});
  }
}

 

Screenshots

 

Synchronized panning

 

Synchronized panning

View the sample in GitHub

 

 

 

ADD COMMENT
You must log in to leave a comment

Please sign in to access our KB

This page will automatically be redirected to the sign-in page in 10 seconds.

Up arrow icon

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

Live Chat Icon For mobile