Articles in this section
Category / Section

How to synchronize panning in multiple charts (SfCartesianChart) ?

3 mins read

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. 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. The callback used for the synchronized panning is the onZooming event available in the chart and onRendererCreated event available in the axis.

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

Step 1: Initialize a Cartesian chart (First chart) as an individual StatefulWidget, in which the initialZoomFactor and the initialZoomPosition values are got from the onZooming event and stored globally in the variables for the second chart to use for synchronized panning by updating the axis controller's zoomFactor and zoomPosition.

class Chart extends StatefulWidget {
late ZoomPanBehavior  _zoomPanBehavior;
late TooltipBehavior _tooltipBehavior;
CategoryAxisController? axisController1; // create instance to axis controller for first chart
CategoryAxisController? axisController2; // create instance to axis controller for second chart    @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.
// Updating zoomFactor and zoomPosition for second chart by using axis controller.
axisController2!.zoomPosition = zoomP;             axisController2!.zoomFactor = zoomF;           }         },         primaryXAxis: CategoryAxis(
// To set value for first chart axis controller
onRenderCreated (CategoryAxisController controller) {
axisController1 = controller;
}             initialZoomFactor: 0.2,
initialZoomPosition: 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           )         ]);   } }


 

Step 2: 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 update the axis controller's zoomFactor and zoomPosition. 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.
// Updating the zoomFactor and zoomPosition for first chart by using axis controller.             axisController1!.zoomPosition = zoomP;
axisController1!.zoomFactor = zoomF;           }         },         primaryXAxis: CategoryAxis(
onRendererCreated (CategoryAxisController controller){
axisController2 = controller;
}
initialZoomFactor: zoomF,
initialZoomPosition: 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)         ]);   } }

 

 

Screenshots

 

Synchronized panning

 

Synchronized panning

View the sample in GitHub

 

 

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied