---
title: "Asynchronous Data"
enterprise: true
framework: vue
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/vue/zoom/) or the [Scrollbar](https://www.ag-grid.com/charts/vue/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 { createApp, defineComponent, ref } from "vue";
import { AgCharts } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import {
  AnimationModule,
  ContextMenuModule,
  CrosshairModule,
  DataSourceModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NavigatorModule,
  NumberAxisModule,
  TimeAxisModule,
  ZoomModule,
} from "ag-charts-enterprise";
import { Database } from "./data";
import { FakeServer } from "./fakeServer";
import clone from "clone";

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

const ChartExample = defineComponent({
  template: `
    <div class="example-controls">
      <div class="controls-row">
        <button v-on:click="reload()">Reload Data</button>
      </div>
    </div>
    <ag-charts
      ref="agCharts"
      :options="options"
    />
  `,
  components: {
    "ag-charts": AgCharts,
  },
  setup(props) {
    const options = ref<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 agCharts.value.chart requests a coarse, full-range overview; the main agCharts.value.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)),
          },
        },
      },
    });
    const agCharts = ref(null);

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

    return {
      options,
      agCharts,
      reload,
    };
  },
});

createApp(ChartExample).mount("#app");
```

[Live example: Async Data](https://www.ag-grid.com/charts/vue3/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/vue/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/vue/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/vue/overlays/#loading-data-overlay) automatically. The overlay can be customised through the `overlays.loading` option; see [Overlays](https://www.ag-grid.com/charts/vue/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 { createApp, defineComponent, ref } from "vue";
import { AgCharts } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import {
  AnimationModule,
  ContextMenuModule,
  CrosshairModule,
  DataSourceModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-enterprise";
import clone from "clone";

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 ChartExample = defineComponent({
  template: `
    <div class="example-controls">
      <div class="controls-row">
        Loading:
        <button v-on:click="setLoading(true)"><code>true</code></button>
        <button v-on:click="setLoading(false)"><code>false</code></button>
        <button v-on:click="setLoading(undefined)"><code>undefined</code></button>
      </div>
      <div class="controls-row">
        <button v-on:click="reload()">Reload</button>
      </div>
    </div>
    <ag-charts
      ref="agCharts"
      :options="options"
    />
  `,
  components: {
    "ag-charts": AgCharts,
  },
  setup(props) {
    const options = ref<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" } },
      },
    });
    const agCharts = ref(null);

    const setLoading = (value) => {
      agCharts.value.chart.updateDelta({ loading: value });
    };
    const reload = () => {
      agCharts.value.chart.updateDelta({});
    };

    return {
      options,
      agCharts,
      setLoading,
      reload,
    };
  },
});

createApp(ChartExample).mount("#app");
```

[Live example: Loading Overlay](https://www.ag-grid.com/charts/vue3/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. |
