---
title: "Asynchronous Data"
enterprise: true
framework: javascript
version: "14.1.0"
---

# Asynchronous Data

Asynchronous Data allows charts to load data on demand, supporting progressive detail loading and server-side paging when used with [Zoom](https://www.ag-grid.com/charts/javascript/zoom/) or the [Scrollbar](https://www.ag-grid.com/charts/javascript/scrollbar/).

## Data Source

Use the `dataSource` option to provide an asynchronous `getData` callback. The chart calls this function on initial load and then whenever the visible window changes, and displays a loading overlay until the returned promise resolves.

#### Async Data

```ts
import {
  AgCartesianChartOptions,
  AgCharts,
  AnimationModule,
  ContextMenuModule,
  CrosshairModule,
  DataSourceModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NavigatorModule,
  NumberAxisModule,
  TimeAxisModule,
  ZoomModule,
} from "ag-charts-enterprise";
import { Database } from "./data";
import { FakeServer } from "./fakeServer";

ModuleRegistry.registerModules([
  AnimationModule,
  CrosshairModule,
  DataSourceModule,
  LegendModule,
  LineSeriesModule,
  NavigatorModule,
  NumberAxisModule,
  TimeAxisModule,
  ZoomModule,
  ContextMenuModule,
]);

const options: AgCartesianChartOptions = {
  dataSource: {
    getData: ({ windowStart, windowEnd, source }) => {
      // Request the data from the server, this is an asynchronous call which may take up to 2500ms. In your
      // application, replace this with a call to your server api.
      // The navigator mini chart requests a coarse, full-range overview; the main chart requests the visible
      // window, and the server returns higher-resolution data as the window narrows.
      return source === "mini-chart"
        ? FakeServer.get({})
        : FakeServer.get({ windowStart, windowEnd });
    },
  },
  navigator: {
    enabled: true,
    miniChart: {},
  },
  zoom: {
    enabled: true,
  },
  initialState: {
    zoom: {
      ratioX: { start: 0.7, end: 1 },
    },
  },
  series: [
    {
      type: "line",
      xKey: "time",
      yKey: "price",
      yName: "Price",
    },
  ],
  axes: {
    y: {
      type: "number",
      min: 400,
      max: 1600,
    },
    x: {
      type: "time",
      min: new Date("2019-01-01 00:00:00"),
      max: new Date("2024-12-30 23:59:59"),
      interval: {
        minSpacing: 100,
        maxSpacing: 200,
      },
      label: {
        formatter: ({ value }) =>
          Intl.DateTimeFormat("en-GB", {
            day: "2-digit",
            month: "short",
            year: "2-digit",
          }).format(new Date(value)),
      },
    },
  },
};

options.container = document.getElementById("myChart");

const chart = AgCharts.create(options);

// Refresh the underlying server data, then call updateDelta({}) to re-trigger getData for the
// current window. The chart shows its loading overlay while the new data is fetched.
function reload() {
  Database.refresh();
  chart.updateDelta({});
}

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).reload = reload;
}
```

[Live example: Async Data](https://www.ag-grid.com/charts/typescript/async-data/examples/async-data)

```js
{
    dataSource: {
        getData: ({ windowStart, windowEnd }) => {
            return FakeServer.get({ windowStart, windowEnd });
        },
    },
}
```

In this example:

- The fake server returns coarse data covering the full date range alongside finer-grained data for the visible window.
- As the user zooms in, `getData` is re-invoked with updated `windowStart` and `windowEnd` values and the server returns higher-resolution data for that range.

The `getData` callback receives an `AgDataSourceCallbackParams` object with:

- `windowStart`: the start of the visible window.
- `windowEnd`: the end of the visible window.
- `source`: what triggered the request, such as `'mini-chart'`, `'user-interaction'` or `'chart-update'`.
- `context`: the [chart context object](https://www.ag-grid.com/charts/javascript/context/), if one has been provided.

> **Note**
>
> The returned data must include the first and last data points so the chart can establish the axis domain, unless the axis has explicit `min` and `max` values.

When the [Navigator Mini Chart](https://www.ag-grid.com/charts/javascript/navigator#mini-chart) is enabled, it issues its own `getData` call with `source: 'mini-chart'` to load a full-range overview, independent of the main chart's windowed fetches. This is only done on initial load or options update.

### Triggering a Reload

Calling `updateDelta({})` with an empty object triggers `getData` to be called again, which is useful for refreshing data on demand. The **Reload Data** button in the example above does exactly this; the loading overlay is shown while the request is in progress, and the chart updates with the freshly fetched data once it resolves.

```js
chart.updateDelta({});
```

## Loading Overlay

While `getData` is in progress, the chart displays a [Loading Overlay](https://www.ag-grid.com/charts/javascript/overlays/#loading-data-overlay) automatically. The overlay can be customised through the `overlays.loading` option; see [Overlays](https://www.ag-grid.com/charts/javascript/overlays/) for text customisation and custom renderers.

### Manual Control

Set `loading` on the chart options to control the overlay independently of `dataSource`.

#### Loading Overlay

```ts
import {
  AgChartOptions,
  AgCharts,
  AnimationModule,
  ContextMenuModule,
  CrosshairModule,
  DataSourceModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-enterprise";

const datasets = [
  [120, 145, 98, 160, 135],
  [200, 175, 220, 190, 210],
  [80, 95, 70, 110, 85],
  [155, 130, 180, 145, 165],
];
let loadIndex = 0;
function getData() {
  const values = datasets[loadIndex % datasets.length];
  loadIndex++;
  return values.map((spending, i) => ({ year: 2020 + i, spending }));
}
ModuleRegistry.registerModules([
  AnimationModule,
  CrosshairModule,
  DataSourceModule,
  LegendModule,
  LineSeriesModule,
  NumberAxisModule,
  ContextMenuModule,
]);

const options: AgChartOptions = {
  dataSource: {
    getData: () =>
      new Promise((resolve) => setTimeout(() => resolve(getData()), 2000)),
  },
  series: [
    {
      type: "line",
      xKey: "year",
      yKey: "spending",
    },
  ],
  axes: {
    x: { type: "number", title: { text: "Year" } },
    y: { type: "number", title: { text: "Spending" } },
  },
};

options.container = document.getElementById("myChart");

const chart = AgCharts.create(options);

function setLoading(value: boolean | undefined) {
  chart.updateDelta({ loading: value });
}

function reload() {
  chart.updateDelta({});
}

if (typeof window !== "undefined") {
  // Attach external event handlers to window so they can be called from index.html
  (<any>window).setLoading = setLoading;
  (<any>window).reload = reload;
}
```

[Live example: Loading Overlay](https://www.ag-grid.com/charts/typescript/async-data/examples/loading)

Use the buttons to override the loading state.

```js
{
    loading: true,
}
```

- `true` - force the overlay on.
- `false` - force the overlay off.
- `undefined` - automatic, shown while `getData` is pending and hidden when it resolves.

## API Reference

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| getData (required) | Function |  | Asynchronous callback to load data into the chart. |
