SciChart.js JavaScript 2D Charts API > Animations API > Dataset Animations
Dataset Animations

SciChart.js v2.x and above features a new API which allows you to animate between datasets on a chart. But the limitation is that the length of data vectors (length of X and Y values and animation values) must be the same.

Below find an example of animating between two different datasets. Note the Animation type includes style properties and is a specific animation type for the series, as per our Style Transition Animations documentation.

Worked Examples

Animating Data in a Scatter Series

You can animate the dataset in a scatter series by using the ScatterAnimation type. This allows you to set new data and animate to the new position. Find an example below:

import {SciChartSurface} from "scichart/Charting/Visuals/SciChartSurface";
import {NumericAxis} from "scichart/Charting/Visuals/Axis/NumericAxis";
import {EllipsePointMarker} from "scichart/Charting/Visuals/PointMarkers/EllipsePointMarker";
import {XyDataSeries} from "scichart/Charting/Model/XyDataSeries";
import {NumberRange} from "scichart/Core/NumberRange";
import {XyScatterRenderableSeries} from "scichart/Charting/Visuals/RenderableSeries/XyScatterRenderableSeries";
import {SciChartJSLightTheme} from "scichart/Charting/Themes/SciChartJSLightTheme";
import {ScatterAnimation} from "scichart/Charting/Visuals/RenderableSeries/Animations/ScatterAnimation";
import { easing} from "scichart/Core/Animations/EasingFunctions";
export async function scatterDataAnimation(divId) {
    const { sciChartSurface, wasmContext } = await SciChartSurface.create(divId, {
        theme: new SciChartJSLightTheme()
    });
    sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { visibleRange: new NumberRange(0, 5) }));
    sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { visibleRange: new NumberRange(0, 5) }));
    // Create a scatter series with some initial data
    const scatterSeries = new XyScatterRenderableSeries(wasmContext, {
        dataSeries: new XyDataSeries(wasmContext, {
            xValues: [1, 2, 3, 4, 5],
            yValues: [1.3, 2.3, 4, 3.3, 4.5]
        }),
        pointMarker: new EllipsePointMarker(wasmContext, {
            width: 11, height: 11, fill: "#FF3333BB", strokeThickness: 0
        })
    });
    sciChartSurface.renderableSeries.add(scatterSeries);
    // Update data using data animations
    const animateData = () => {
        const xValues = Array.from({length: 5}, () => Math.random() * 5);
        const yValues = Array.from({length: 5}, () => Math.random() * 5);
        scatterSeries.runAnimation(new ScatterAnimation({
            duration: 500,
            ease: easing.outQuad,
            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues })
        }));
        setTimeout(animateData, 1000);
    };
    setTimeout(animateData, 1000);
}

Combining Style and Data Animations

You can take the example above a step further and combine both style and data animations. Remember the constraint that datasets need the same amount of X,Y datapoints before and after. If this condition is met, you can achieve something like this:

import {SciChartSurface} from "scichart/Charting/Visuals/SciChartSurface";
import {NumericAxis} from "scichart/Charting/Visuals/Axis/NumericAxis";
import {EllipsePointMarker} from "scichart/Charting/Visuals/PointMarkers/EllipsePointMarker";
import {XyDataSeries} from "scichart/Charting/Model/XyDataSeries";
import {NumberRange} from "scichart/Core/NumberRange";
import {XyScatterRenderableSeries} from "scichart/Charting/Visuals/RenderableSeries/XyScatterRenderableSeries";
import {SciChartJSLightTheme} from "scichart/Charting/Themes/SciChartJSLightTheme";
import {ScatterAnimation} from "scichart/Charting/Visuals/RenderableSeries/Animations/ScatterAnimation";
import { easing} from "scichart/Core/Animations/EasingFunctions";
import {EPointMarkerType} from "scichart/types/PointMarkerType";
export async function scatterDataAnimationWithStyle(divId) {
    const { sciChartSurface, wasmContext } = await SciChartSurface.create(divId, {
        theme: new SciChartJSLightTheme()
    });
    sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { visibleRange: new NumberRange(0, 5) }));
    sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { visibleRange: new NumberRange(0, 5) }));
    // Create a scatter series with some initial data
    const scatterSeries = new XyScatterRenderableSeries(wasmContext, {
        dataSeries: new XyDataSeries(wasmContext, {
            xValues: [1, 2, 3, 4, 5],
            yValues: [1.3, 2.3, 4, 3.3, 4.5]
        }),
        pointMarker: new EllipsePointMarker(wasmContext, {
            width: 11, height: 11, fill: "#FF3333BB", strokeThickness: 0
        })
    });
    sciChartSurface.renderableSeries.add(scatterSeries);
    // Update data using data animations
    const animateDataAndStyle = () => {
        const xValues = Array.from({length: 5}, () => Math.random() * 5);
        const yValues = Array.from({length: 5}, () => Math.random() * 5);
        const randomColor = () => '#'+(0x1000000+Math.random()*0xffffff).toString(16).substr(1,6);
        const fillColor = randomColor();
        const strokeColor = randomColor();
        const size = Math.random() * 12 + 5;
        const pointMarkers = [EPointMarkerType.Ellipse, EPointMarkerType.Triangle, EPointMarkerType.Square];
        const randomMarker = () => pointMarkers[Math.floor(Math.random() * 3)];
        scatterSeries.runAnimation(new ScatterAnimation({
            duration: 500,
            ease: easing.outQuad,
            styles: {
                pointMarker: {
                    type: randomMarker(),
                    width: size,
                    height: size,
                    strokeThickness: 3,
                    stroke: strokeColor,
                    fill: fillColor
                }
            },
            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues })
        }));
        setTimeout(animateDataAndStyle, 1000);
    };
    setTimeout(animateDataAndStyle, 1000);
}

Animating Data in a Column Series

const { sciChartSurface, wasmContext } = await SciChartSurface.create(divElementId, {
    theme: new SciChartJSLightTheme()
});
sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext));
const columnSeries = new FastColumnRenderableSeries(wasmContext, {
    fill: "rgba(176, 196, 222, 1)",
    stroke: "#4682b4",
    strokeThickness: 2,
    dataPointWidth: 0.5,
    opacity: 0.7
});
sciChartSurface.renderableSeries.add(columnSeries);
const dataSeries = new XyDataSeries(wasmContext);
for (let i = 0; i < 20; i++) {
    dataSeries.append(i, Math.sin(i * 0.5));
}
columnSeries.dataSeries = dataSeries;
const dataSeries1 = new XyDataSeries(wasmContext);
for (let i = 0; i < 20; i++) {
    dataSeries1.append(5 + i / 2, Math.cos(i * 0.5));
}
columnSeries.runAnimation(
    new ColumnAnimation({
        duration: 3000,
        dataSeries: dataSeries1
    })
);
sciChartSurface.zoomExtents();
return { wasmContext, sciChartSurface };

Below is the result.