Articles in this section
Category / Section

How to lazily load more data to the chart (SfCartesianChart) ?

2 mins read

SfCartesianChart has support to lazily load and display the chart. You can be able to load a certain amount of data initially to the chart and then can load more data lazily. While the horizontal scrolling reaches the start or end of the chart, loadMoreIndicatorBuilder is called. Using this, you can return any widget which can be shown on the chart while loading more data. For more information, refer to this help document.

The following steps explain how to add data points dynamically to the chart while dragging the chart towards the end.

Step 1: Declare the series controller, data source, zoom pan behavior, global key, and other required variables as shown in the following code sample.

ChartSeriesController? seriesController;
late List<ChartSampleData> chartData
late List<ChartSampleData> chartData
late bool isLoadMoreView, isNeedToUpdateView, isDataUpdated;
double? oldAxisVisibleMin, oldAxisVisibleMax;
late ZoomPanBehavior _zoomPanBehavior;
late GlobalKey<State> globalKey;


Step 2: Define the _initializeVaraible method, which will be executed in the initState. Here, we have defined the initial data, Boolean variables, and zoom pan behavior of the chart.

void _initializeVariables() {
 // Initial data source of the chart
  chartData = <ChartSampleData>[
    ChartSampleData(xValue: 0, y: 326),
    ChartSampleData(xValue: 1, y: 416),
    ChartSampleData(xValue: 2, y: 290),
    ChartSampleData(xValue: 3, y: 70),
    ChartSampleData(xValue: 4, y: 500),
    ChartSampleData(xValue: 5, y: 416),
    ChartSampleData(xValue: 6, y: 290),
    ChartSampleData(xValue: 7, y: 120),
    ChartSampleData(xValue: 8, y: 500),
  isLoadMoreView = false;
  isNeedToUpdateView = false;
  isDataUpdated = true;
// Key which uses to access the chart state.
  globalKey = GlobalKey<State>();
// Enabling panning in the chart.
  _zoomPanBehavior = ZoomPanBehavior(
  enablePanning: true,


Step 3: In the onActualRangeChanged callback, set the visibleMinimum and visibleMaximum values with the old visible minimum and maximum values respectively to display the data with the old viewport even after the new data loaded to the chart until we swipe it manually.

 onActualRangeChanged: (ActualRangeChangedArgs args) {
   if (args.orientation == AxisOrientation.horizontal) {
   // Assigning the old visible min and max after loads the data.
     if (isLoadMoreView) {
       args.visibleMin = oldAxisVisibleMin;
       args.visibleMax = oldAxisVisibleMax;
    // Asigning current visible min and max to old visible min and max.
     oldAxisVisibleMin = args.visibleMin;
     oldAxisVisibleMax = args.visibleMax;
   isLoadMoreView = false;


Step 4: Assign the buildloadMoreIndicatorView method to the loadMoreIndicatorBuilder in the chart.

    (BuildContext context, ChartSwipeDirection direction) =>
        buildloadMoreIndicatorView (context, direction),


Step 5: Define the buildloadMoreIndicatorView method as shown in the following code sample.

 Widget buildloadMoreIndicatorView(
    BuildContext context, ChartSwipeDirection direction) {
  // To know whether reaches the end of the chart
  if (direction == ChartSwipeDirection.end) {
    isNeedToUpdateView = true;
    globalKey = GlobalKey<State>();
    return StatefulBuilder(
        key: globalKey,
        builder: (BuildContext context, StateSetter stateSetter) {
          Widget widget;
       // To add new data after reached the end and returns loading indicator until chart gets rendered
          if (isNeedToUpdateView) {
       // Assigning loading widget above the chart to display
            widget = getProgressIndicator();
       // Redrawing the chart
            isDataUpdated = true;
          } else {
            widget = Container();
        return widget;
  } else {
    return SizedBox.fromSize(size:;


In this method, you can return the stateful builder with the CircularProgressIndicator until the data gets loaded and update the loaded data to the chart.

Step 6: Define the _updateView method, which redraws the chart with refreshed data by calling the chart state and _updateData method, which updates the new data to the chart.

 //Adding new data to the chart.
 void _updateData() {
    for (int i = 0; i < 4; i++) {
        xValue: chartData[chartData.length - 1].xValue + 1,
        y: getRandomInt(0, 600)));
      isLoadMoreView = true;
      seriesController?.updateDataSource(addedDataIndexes: getIndexes(4));
   // Redrawing the chart with updated data by calling the chart state.
    Future<void> _updateView() async {
      await Future<void>.delayed(const Duration(seconds: 1), () {
        isNeedToUpdateView = false;
        if (isDataUpdated) {
          isDataUpdated = false;
        if (globalKey.currentState != null) {
          (globalKey.currentState as dynamic).setState(() {});


Thus, the infinite scrolling is achieved by dynamically adding the data while dragging the chart towards the end using the SfCartesianchart widget.


loading data while swiping chart towards end


View the sample in GitHub.


Did you find this information helpful?
Help us improve this page
Please provide feedback or comments
Please sign in to leave a comment