---
title: "Large Dataset Interactivity"
framework: vue
version: "14.1.0"
---

# Large Dataset Interactivity

AG Charts is optimised to handle **large datasets with over 1 million points**, while maintaining full, smooth interactivity. No additional configuration or modules required - it just works out of the box.

#### Ordered Data

```ts
import { createApp, defineComponent, ref } from "vue";
import { AgCharts } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import {
  AnimationModule,
  AreaSeriesModule,
  BarSeriesModule,
  BubbleSeriesModule,
  CandlestickSeriesModule,
  CategoryAxisModule,
  ContextMenuModule,
  CrosshairModule,
  HistogramSeriesModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NavigatorModule,
  NumberAxisModule,
  OhlcSeriesModule,
  OrdinalTimeAxisModule,
  RangeAreaSeriesModule,
  RangeBarSeriesModule,
  ScatterSeriesModule,
  TimeAxisModule,
  ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
import clone from "clone";

let dataLabel = "1K";

let seriesType = "Line";

let datapoints = 1e3;

const timeAxes = {
  x: { type: "ordinal-time", parentLevel: { enabled: true } },
};

const numberAxes = {
  x: { type: "number" },
};

const baseData = getData(1e6);

ModuleRegistry.registerModules([
  AnimationModule,
  AreaSeriesModule,
  BarSeriesModule,
  BubbleSeriesModule,
  CandlestickSeriesModule,
  CrosshairModule,
  HistogramSeriesModule,
  LegendModule,
  LineSeriesModule,
  NavigatorModule,
  NumberAxisModule,
  OhlcSeriesModule,
  OrdinalTimeAxisModule,
  RangeAreaSeriesModule,
  RangeBarSeriesModule,
  ScatterSeriesModule,
  TimeAxisModule,
  ZoomModule,
  CategoryAxisModule,
  ContextMenuModule,
]);

const ChartExample = defineComponent({
  template: `
    <div class="example-controls">
      <div class="controls-row">
        <span>Series Type:</span>
        <select v-on:change="setSeries($event.target.value, $event.target.selectedOptions[0].text)">
          <option value="line" selected="">Line</option>
          <option value="area">Area</option>
          <option value="bar">Bar</option>
          <hr />
          <option value="stacked-bar">Stacked Bar</option>
          <option value="stacked-area">Stacked Area</option>
          <hr />
          <option value="range-area">Range Area</option>
          <option value="range-bar">Range Bar</option>
          <hr />
          <option value="candlestick">Candlestick</option>
          <option value="ohlc">OHLC</option>
          <hr />
          <option value="scatter">Scatter</option>
          <option value="bubble">Bubble</option>
          <hr />
          <option value="histogram">Histogram</option>
        </select>
        <span class="gap-left">Data Size:</span>
        <button v-on:click="setData(1e3, '1K')">1K</button>
        <button v-on:click="setData(1e4, '10K')">10K</button>
        <button v-on:click="setData(1e5, '100K')">100K</button>
        <button v-on:click="setData(5e5, '500K')">500K</button>
        <button v-on:click="setData(1e6, '1M')">1M</button>
      </div>
    </div>
    <ag-charts
      :options="options"
    />
  `,
  components: {
    "ag-charts": AgCharts,
  },
  setup(props) {
    const options = ref<AgCartesianChartOptions>({
      data: baseData.slice(-datapoints),
      title: { text: `${seriesType} with ${dataLabel} datapoints` },
      animation: { enabled: false },
      zoom: {
        enabled: true,
        axes: "x",
        anchorPointX: "pointer",
        anchorPointY: "pointer",
        autoScaling: {
          enabled: true,
        },
      },
      navigator: {
        enabled: true,
        miniChart: {
          enabled: true,
        },
      },
      series: [
        {
          type: "line",
          xKey: "timestamp",
          yKey: "close",
        },
      ],
      axes: timeAxes,
    });

    const setSeries = (type, label) => {
      const optionsCopy = { ...options.value };

      seriesType = label;
      let series = [];
      switch (type) {
        case "bar":
        case "area":
        case "line":
          optionsCopy.series = [
            {
              type,
              xKey: "timestamp",
              yKey: "high",
            },
          ];
          break;
        case "stacked-bar":
        case "stacked-area":
          const stackedType = type === "stacked-bar" ? "bar" : "area";
          optionsCopy.series = [
            {
              type: stackedType,
              xKey: "timestamp",
              yKey: "open",
              stacked: true,
            },
            {
              type: stackedType,
              xKey: "timestamp",
              yKey: "close",
              stacked: true,
            },
          ];
          break;
        case "range-area":
        case "range-bar":
          optionsCopy.series = [
            {
              type,
              xKey: "timestamp",
              yLowKey: "low",
              yHighKey: "high",
            },
          ];
          break;
        case "candlestick":
        case "ohlc":
          optionsCopy.series = [
            {
              type,
              xKey: "timestamp",
              lowKey: "low",
              highKey: "high",
              openKey: "open",
              closeKey: "close",
            },
          ];
          break;
        case "scatter":
          optionsCopy.series = [
            {
              type,
              xKey: "x",
              yKey: "y",
              fillOpacity: 0.2,
              strokeOpacity: 0.2,
            },
          ];
          break;
        case "bubble":
          optionsCopy.series = [
            {
              type,
              xKey: "x",
              yKey: "y",
              sizeKey: "size",
              fillOpacity: 0.2,
              strokeOpacity: 0.2,
            },
          ];
          break;
        case "histogram":
          optionsCopy.series = [
            {
              type,
              xKey: "close",
            },
          ];
          break;
        default:
          return;
      }
      const newDatapoints = optionsCopy.series?.[0]?.stacked
        ? datapoints / 2
        : datapoints;
      if (optionsCopy.data?.length !== newDatapoints) {
        optionsCopy.data = baseData.slice(-newDatapoints);
      }
      if (type == "bubble" || type == "scatter" || type == "histogram") {
        optionsCopy.zoom.axes = "xy";
        optionsCopy.zoom.autoScaling.enabled = false;
        optionsCopy.navigator.enabled = false;
        optionsCopy.axes = numberAxes;
      } else {
        optionsCopy.zoom.axes = "xy";
        optionsCopy.zoom.autoScaling.enabled = true;
        optionsCopy.navigator.enabled = true;
        optionsCopy.axes = timeAxes;
      }
      optionsCopy.title.text = `${seriesType} with ${dataLabel} datapoints`;

      options.value = optionsCopy;
    };
    const setData = (points, label) => {
      const optionsCopy = { ...options.value };

      const newDatapoints = optionsCopy.series?.[0]?.stacked
        ? points / 2
        : points;
      if (optionsCopy.data?.length !== newDatapoints) {
        optionsCopy.data = baseData.slice(-newDatapoints);
      }
      dataLabel = label;
      datapoints = points;
      optionsCopy.title.text = `${seriesType} with ${dataLabel} datapoints`;

      options.value = optionsCopy;
    };

    return {
      options,
      setSeries,
      setData,
    };
  },
});

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

[Live example: Ordered Data](https://www.ag-grid.com/charts/vue3/large-dataset-interactivity/examples/ordered-data)

In the above example:

- Use the controls to select different series types and data sizes.
- Use the mouse, [Navigator](https://www.ag-grid.com/charts/vue/navigator/) or [zoom controls](https://www.ag-grid.com/charts/vue/zoom/#axis-zoom-controls) to [zoom](https://www.ag-grid.com/charts/vue/zoom/), [scroll](https://www.ag-grid.com/charts/vue/zoom/#scrolling) and [pan](https://www.ag-grid.com/charts/vue/zoom/#panning) the data.

> **Note**
>
> Performance may vary based on your specific use case, environment and hardware.

## How it works

Behind the scenes, AG Charts applies advanced data aggregation techniques, such as the [M4 algorithm](https://blog.ag-grid.com/optimizing-large-data-set-visualisations-with-the-m4-algorithm/), to ensure accurate representation across scales. As you zoom and pan, the chart dynamically adapts to the visible range, preserving both performance and clarity.
