Initial Load Copy Link
Switch between the different series types below to see their initial load animations. Toggling items in the legend will also animate the series in and out.
import {
AgCartesianChartOptions,
AgCartesianSeriesTooltipRendererParams,
AgChartOptions,
AgCharts,
AgPolarChartOptions,
AgTooltipRendererResult,
AnimationModule,
AreaSeriesModule,
BarSeriesModule,
CategoryAxisModule,
ContextMenuModule,
CrosshairModule,
DonutSeriesModule,
LegendModule,
LineSeriesModule,
ModuleRegistry,
NumberAxisModule,
PieSeriesModule,
} from "ag-charts-enterprise";
import { DataType, getData } from "./data";
const numFormatter = new Intl.NumberFormat("en-US");
const tooltip = {
renderer: ({
datum,
yKey,
yName,
}: AgCartesianSeriesTooltipRendererParams<DataType>): AgTooltipRendererResult => {
return {
data: [
{ label: yName!, value: numFormatter.format(Number(datum[yKey])) },
],
};
},
};
const barOptions: AgCartesianChartOptions<DataType> = {
series: [
{
type: "bar",
xKey: "station",
yKey: "early",
stacked: true,
yName: "Early",
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "morningPeak",
yName: "Morning peak",
stacked: true,
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "interPeak",
yName: "Between peak",
stacked: true,
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "afternoonPeak",
yName: "Afternoon peak",
stacked: true,
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "evening",
yName: "Evening",
stacked: true,
tooltip,
},
],
axes: {
x: {
type: "category",
label: {
wrapping: "on-space",
autoRotate: false,
},
},
y: {
type: "number",
label: {
formatter: (params) => {
return params.value / 1000 + "k";
},
},
},
},
};
const lineOptions: AgCartesianChartOptions<DataType> = {
series: [
{
type: "line",
xKey: "station",
yKey: "early",
yName: "Early",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "morningPeak",
yName: "Morning peak",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "interPeak",
yName: "Between peak",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "afternoonPeak",
yName: "Afternoon peak",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "evening",
yName: "Evening",
tooltip,
},
],
axes: {
x: {
type: "category",
label: {
wrapping: "on-space",
autoRotate: false,
},
},
y: {
type: "number",
label: {
formatter: (params) => {
return params.value / 1000 + "k";
},
},
},
},
};
const areaOptions: AgCartesianChartOptions<DataType> = {
series: [
{
type: "area",
xKey: "station",
yKey: "early",
stacked: true,
yName: "Early",
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "morningPeak",
yName: "Morning peak",
stacked: true,
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "interPeak",
yName: "Between peak",
stacked: true,
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "afternoonPeak",
yName: "Afternoon peak",
stacked: true,
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "evening",
yName: "Evening",
stacked: true,
tooltip,
},
],
axes: {
x: {
type: "category",
label: {
wrapping: "on-space",
autoRotate: false,
},
},
y: {
type: "number",
label: {
formatter: (params) => {
return params.value / 1000 + "k";
},
},
},
},
};
const donutOptions: AgPolarChartOptions<DataType> = {
series: [
{
type: "pie",
title: {
text: "Morning Peak",
},
calloutLabelKey: "station",
legendItemKey: "station",
angleKey: "morningPeak",
outerRadiusRatio: 0.6,
},
{
type: "donut",
title: {
text: "Afternoon Peak",
},
calloutLabelKey: "station",
legendItemKey: "station",
angleKey: "afternoonPeak",
showInLegend: false,
},
],
};
ModuleRegistry.registerModules([
AnimationModule,
AreaSeriesModule,
BarSeriesModule,
CategoryAxisModule,
CrosshairModule,
DonutSeriesModule,
LegendModule,
LineSeriesModule,
NumberAxisModule,
PieSeriesModule,
ContextMenuModule,
]);
const options:
| AgCartesianChartOptions<DataType>
| AgPolarChartOptions<DataType> = {
data: getData(),
animation: {
enabled: true,
},
...barOptions,
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function changeSeriesBar() {
options.series = barOptions.series;
options.axes = barOptions.axes;
chart.update(options);
}
function changeSeriesLine() {
options.series = lineOptions.series;
options.axes = lineOptions.axes;
chart.update(options);
}
function changeSeriesArea() {
options.series = areaOptions.series;
options.axes = areaOptions.axes;
chart.update(options);
}
function changeSeriesDonut() {
options.series = donutOptions.series;
options.axes = donutOptions.axes;
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).changeSeriesBar = changeSeriesBar;
(<any>window).changeSeriesLine = changeSeriesLine;
(<any>window).changeSeriesArea = changeSeriesArea;
(<any>window).changeSeriesDonut = changeSeriesDonut;
}
export interface DataType {
station: string;
early: number;
morningPeak: number;
interPeak: number;
afternoonPeak: number;
evening: number;
}
export function getData(): DataType[] {
return [
{
station: "Finsbury Park",
early: 2454,
morningPeak: 16644,
interPeak: 9338,
afternoonPeak: 6346,
evening: 3547,
},
{
station: "Seven Sisters",
early: 3927,
morningPeak: 7581,
interPeak: 5421,
afternoonPeak: 3245,
evening: 2036,
},
{
station: "Tottenham Hale",
early: 6836,
morningPeak: 12740,
interPeak: 14964,
afternoonPeak: 12790,
evening: 8428,
},
{
station: "Warren Street",
early: 9108,
morningPeak: 1210,
interPeak: 5902,
afternoonPeak: 10947,
evening: 5574,
},
{
station: "Oxford Circus",
early: 7170,
morningPeak: 1796,
interPeak: 26616,
afternoonPeak: 32269,
evening: 3665,
},
{
station: "Green Park",
early: 6252,
morningPeak: 1911,
interPeak: 11971,
afternoonPeak: 19749,
evening: 11582,
},
];
}
Data Updates Copy Link
A data update animation is split into three sequential phases — remove, update then add, which can be observed for different series types in this example:
import {
AgCartesianChartOptions,
AgChartOptions,
AgCharts,
AgPolarChartOptions,
AnimationModule,
AreaSeriesModule,
BarSeriesModule,
CategoryAxisModule,
ContextMenuModule,
CrosshairModule,
DonutSeriesModule,
LegendModule,
LineSeriesModule,
ModuleRegistry,
NumberAxisModule,
PieSeriesModule,
} from "ag-charts-enterprise";
import { getData, random } from "./data";
let start = [120, 150, 130, 140, 80];
let variance = 20;
let offset = 0;
let length = 8;
let seed = 1234;
const barOptions: AgCartesianChartOptions = {
series: [
{
type: "bar",
xKey: "year",
yKey: "one",
yName: "One",
stacked: true,
},
{
type: "bar",
xKey: "year",
yKey: "two",
yName: "Two",
stacked: true,
},
{
type: "bar",
xKey: "year",
yKey: "three",
yName: "Three",
stacked: true,
},
{
type: "bar",
xKey: "year",
yKey: "four",
yName: "Four",
stacked: true,
},
{
type: "bar",
xKey: "year",
yKey: "five",
yName: "Five",
stacked: true,
},
],
axes: {
x: {
type: "category",
label: {
autoRotate: false,
},
},
},
};
const lineOptions: AgCartesianChartOptions = {
series: [
{
type: "line",
xKey: "year",
yKey: "one",
yName: "One",
},
{
type: "line",
xKey: "year",
yKey: "two",
yName: "Two",
},
{
type: "line",
xKey: "year",
yKey: "three",
yName: "Three",
},
{
type: "line",
xKey: "year",
yKey: "four",
yName: "Four",
},
{
type: "line",
xKey: "year",
yKey: "five",
yName: "Five",
},
],
axes: {
x: {
type: "number",
nice: false,
label: {
autoRotate: false,
},
},
},
};
const areaOptions: AgCartesianChartOptions = {
series: [
{
type: "area",
xKey: "year",
yKey: "one",
yName: "One",
stacked: true,
},
{
type: "area",
xKey: "year",
yKey: "two",
yName: "Two",
stacked: true,
},
{
type: "area",
xKey: "year",
yKey: "three",
yName: "Three",
stacked: true,
},
{
type: "area",
xKey: "year",
yKey: "four",
yName: "Four",
stacked: true,
},
{
type: "area",
xKey: "year",
yKey: "five",
yName: "Five",
stacked: true,
},
],
axes: {
x: {
type: "number",
nice: false,
label: {
autoRotate: false,
},
},
},
};
const donutOptions: AgPolarChartOptions = {
series: [
{
type: "pie",
title: {
text: "One",
},
calloutLabelKey: "year",
legendItemKey: "year",
angleKey: "one",
outerRadiusRatio: 0.6,
},
{
type: "donut",
title: {
text: "Two",
},
calloutLabelKey: "year",
legendItemKey: "year",
angleKey: "two",
showInLegend: false,
},
],
};
function getGeneratedData() {
return getData(start, variance, offset, length, seed);
}
ModuleRegistry.registerModules([
AnimationModule,
AreaSeriesModule,
BarSeriesModule,
CategoryAxisModule,
CrosshairModule,
DonutSeriesModule,
LegendModule,
LineSeriesModule,
NumberAxisModule,
PieSeriesModule,
ContextMenuModule,
]);
const options: AgCartesianChartOptions | AgPolarChartOptions = {
animation: {
enabled: true,
},
data: getGeneratedData(),
...barOptions,
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function changeSeriesBar() {
variance = 20;
offset = 0;
length = 8;
seed = 1234;
options.series = barOptions.series;
options.axes = barOptions.axes;
options.data = getGeneratedData();
chart.update(options);
}
function changeSeriesLine() {
variance = 4;
offset = 0;
length = 30;
seed = 1234;
options.series = lineOptions.series;
options.axes = lineOptions.axes;
options.data = getGeneratedData();
chart.update(options);
}
function changeSeriesArea() {
variance = 20;
offset = 0;
length = 30;
seed = 1234;
options.series = areaOptions.series;
options.axes = areaOptions.axes;
options.data = getGeneratedData();
chart.update(options);
}
function changeSeriesDonut() {
variance = 30;
offset = 0;
length = 6;
seed = 1234;
options.series = donutOptions.series;
options.axes = donutOptions.axes;
options.data = getGeneratedData();
chart.update(options);
}
function add() {
offset++;
length++;
options.data = getGeneratedData();
chart.update(options);
}
function remove() {
if (options.series?.[0].type === "pie") offset--;
length = Math.max(0, length - 1);
options.data = getGeneratedData();
chart.update(options);
}
function update() {
seed = Math.floor(random() * 1000);
options.data = getGeneratedData();
chart.update(options);
}
function addRemoveUpdate() {
if (options.series?.[0].type === "pie") offset--;
if (options.series?.[0].type !== "pie") offset++;
seed = Math.floor(random() * 1000);
options.data = getGeneratedData();
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).changeSeriesBar = changeSeriesBar;
(<any>window).changeSeriesLine = changeSeriesLine;
(<any>window).changeSeriesArea = changeSeriesArea;
(<any>window).changeSeriesDonut = changeSeriesDonut;
(<any>window).add = add;
(<any>window).remove = remove;
(<any>window).update = update;
(<any>window).addRemoveUpdate = addRemoveUpdate;
}
const NUM_DATA_POINTS = 30;
let _seed = 1234;
// Create a set of data with predictable "randomness"
export function getData(
start = [100, 100, 100, 100],
variance = 2,
offset = 0,
length = NUM_DATA_POINTS,
seed = _seed,
) {
// Vary the datum by a random proportion of the variance +ve or -ve
const vary = (n: number) =>
Math.max(0, n + variance * random() * 2 - variance);
_seed = seed;
const data: Array<{
year: number;
one: number;
two: number;
three: number;
four: number;
five: number;
}> = [
{
year: new Date().getFullYear() - NUM_DATA_POINTS,
one: start[0],
two: start[1],
three: start[2],
four: start[3],
five: start[4],
},
];
for (let i = 1; i < NUM_DATA_POINTS + offset; i++) {
data.push({
year: new Date().getFullYear() - NUM_DATA_POINTS + i,
one: vary(data[i - 1].one),
two: vary(data[i - 1].two),
three: vary(data[i - 1].three),
four: vary(data[i - 1].four),
five: vary(data[i - 1].five),
});
}
return data.slice(offset - (length - NUM_DATA_POINTS));
}
export function random() {
_seed = (_seed * 16807) % 2147483647;
return (_seed - 1) / 2147483646;
}
Duration Copy Link
You can use the duration option to specify the length of all animations in milliseconds.
For an initial load, this is simply the duration of the whole animation.
For a data update, the duration is the total time of all three animation phases together — remove, update then add.
{
animation: {
duration: 500,
},
}In this example, click a duration then change the series type to see the initial load animation.
import {
AgCartesianChartOptions,
AgCartesianSeriesTooltipRendererParams,
AgChartOptions,
AgCharts,
AgPolarChartOptions,
AgTooltipRendererResult,
AnimationModule,
AreaSeriesModule,
BarSeriesModule,
CategoryAxisModule,
ContextMenuModule,
CrosshairModule,
DonutSeriesModule,
LegendModule,
LineSeriesModule,
ModuleRegistry,
NumberAxisModule,
PieSeriesModule,
} from "ag-charts-enterprise";
import { DataType, getData } from "./data";
const numFormatter = new Intl.NumberFormat("en-US");
const tooltip = {
renderer: ({
datum,
yKey,
yName,
}: AgCartesianSeriesTooltipRendererParams<DataType>): AgTooltipRendererResult => {
return {
data: [
{ label: yName!, value: numFormatter.format(Number(datum[yKey])) },
],
};
},
};
const barOptions: AgCartesianChartOptions<DataType> = {
series: [
{
type: "bar",
xKey: "station",
yKey: "early",
stacked: true,
yName: "Early",
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "morningPeak",
yName: "Morning peak",
stacked: true,
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "interPeak",
yName: "Between peak",
stacked: true,
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "afternoonPeak",
yName: "Afternoon peak",
stacked: true,
tooltip,
},
{
type: "bar",
xKey: "station",
yKey: "evening",
yName: "Evening",
stacked: true,
tooltip,
},
],
axes: {
y: {
type: "number",
label: {
formatter: (params) => {
return params.value / 1000 + "k";
},
},
},
},
};
const lineOptions: AgCartesianChartOptions<DataType> = {
series: [
{
type: "line",
xKey: "station",
yKey: "early",
yName: "Early",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "morningPeak",
yName: "Morning peak",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "interPeak",
yName: "Between peak",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "afternoonPeak",
yName: "Afternoon peak",
tooltip,
},
{
type: "line",
xKey: "station",
yKey: "evening",
yName: "Evening",
tooltip,
},
],
axes: {
y: {
type: "number",
label: {
formatter: (params) => {
return params.value / 1000 + "k";
},
},
},
},
};
const areaOptions: AgCartesianChartOptions<DataType> = {
series: [
{
type: "area",
xKey: "station",
yKey: "early",
stacked: true,
yName: "Early",
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "morningPeak",
yName: "Morning peak",
stacked: true,
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "interPeak",
yName: "Between peak",
stacked: true,
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "afternoonPeak",
yName: "Afternoon peak",
stacked: true,
tooltip,
},
{
type: "area",
xKey: "station",
yKey: "evening",
yName: "Evening",
stacked: true,
tooltip,
},
],
axes: {
y: {
type: "number",
label: {
formatter: (params) => {
return params.value / 1000 + "k";
},
},
},
},
};
const donutOptions: AgPolarChartOptions<DataType> = {
series: [
{
type: "pie",
title: {
text: "Morning Peak",
},
calloutLabelKey: "station",
legendItemKey: "station",
angleKey: "morningPeak",
outerRadiusRatio: 0.6,
},
{
type: "donut",
title: {
text: "Afternoon Peak",
},
calloutLabelKey: "station",
legendItemKey: "station",
angleKey: "afternoonPeak",
showInLegend: false,
},
],
};
ModuleRegistry.registerModules([
AnimationModule,
AreaSeriesModule,
BarSeriesModule,
CategoryAxisModule,
CrosshairModule,
DonutSeriesModule,
LegendModule,
LineSeriesModule,
NumberAxisModule,
PieSeriesModule,
ContextMenuModule,
]);
const options:
| AgCartesianChartOptions<DataType>
| AgPolarChartOptions<DataType> = {
data: getData(),
animation: {
enabled: true,
},
...barOptions,
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function changeSeriesBar() {
options.series = barOptions.series;
options.axes = barOptions.axes;
chart.update(options);
}
function changeSeriesLine() {
options.series = lineOptions.series;
options.axes = lineOptions.axes;
chart.update(options);
}
function changeSeriesArea() {
options.series = areaOptions.series;
options.axes = areaOptions.axes;
chart.update(options);
}
function changeSeriesDonut() {
options.series = donutOptions.series;
options.axes = donutOptions.axes;
chart.update(options);
}
function changeDuration(duration: number) {
options.animation = { duration };
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).changeSeriesBar = changeSeriesBar;
(<any>window).changeSeriesLine = changeSeriesLine;
(<any>window).changeSeriesArea = changeSeriesArea;
(<any>window).changeSeriesDonut = changeSeriesDonut;
(<any>window).changeDuration = changeDuration;
}
export interface DataType {
station: string;
early: number;
morningPeak: number;
interPeak: number;
afternoonPeak: number;
evening: number;
}
export function getData(): DataType[] {
return [
{
station: "Finsbury\nPark",
early: 2454,
morningPeak: 16644,
interPeak: 9338,
afternoonPeak: 6346,
evening: 3547,
},
{
station: "Seven\nSisters",
early: 3927,
morningPeak: 7581,
interPeak: 5421,
afternoonPeak: 3245,
evening: 2036,
},
{
station: "Tottenham\nHale",
early: 6836,
morningPeak: 12740,
interPeak: 14964,
afternoonPeak: 12790,
evening: 8428,
},
{
station: "Warren\nStreet",
early: 9108,
morningPeak: 1210,
interPeak: 5902,
afternoonPeak: 10947,
evening: 5574,
},
{
station: "Oxford\nCircus",
early: 7170,
morningPeak: 1796,
interPeak: 26616,
afternoonPeak: 32269,
evening: 3665,
},
{
station: "Green\nPark",
early: 6252,
morningPeak: 1911,
interPeak: 11971,
afternoonPeak: 19749,
evening: 11582,
},
];
}
To highlight data changes with a flash effect, see Flash On Update.