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.
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>
<div class="button-group" role="group" aria-label="Data Size">
<input type="radio" id="data-size-1k" name="data-size" value="1000" data-label="1K" checked="" v-on:change="setData($event)">
<label for="data-size-1k">1K</label>
<input type="radio" id="data-size-10k" name="data-size" value="10000" data-label="10K" v-on:change="setData($event)">
<label for="data-size-10k">10K</label>
<input type="radio" id="data-size-100k" name="data-size" value="100000" data-label="100K" v-on:change="setData($event)">
<label for="data-size-100k">100K</label>
<input type="radio" id="data-size-500k" name="data-size" value="500000" data-label="500K" v-on:change="setData($event)">
<label for="data-size-500k">500K</label>
<input type="radio" id="data-size-1m" name="data-size" value="1000000" data-label="1M" v-on:change="setData($event)">
<label for="data-size-1m">1M</label>
</div>
</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 = (event) => {
const optionsCopy = { ...options.value };
const input = event.target;
const points = Number(input.value);
const label = input.dataset.label;
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");
In the above example:
- Use the controls to select different series types and data sizes.
- Use the mouse, Navigator or zoom controls to zoom, scroll and pan the data.
Performance may vary based on your specific use case, environment and hardware.
How it works Copy Link
Behind the scenes, AG Charts applies advanced data aggregation techniques, such as 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.