JavaScript Animated Bar Chart Example

Creates a JavaScript Animated Bar Chart using SciChart.js that displays animated ATP Year-end Top Ten rankings from 1990 to 2024.

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.html

vanilla.ts

theme.ts

atp-rankings.ts

Copy to clipboard
Minimise
Fullscreen
1import {
2    SciChartSurface,
3    NumericAxis,
4    FastRectangleRenderableSeries,
5    EColumnMode,
6    EColumnYMode,
7    Thickness,
8    EAxisAlignment,
9    ETextAlignment,
10    ETitlePosition,
11    IPointMetadata,
12    easing,
13    EDataLabelSkipMode,
14    EVerticalTextPosition,
15    EHorizontalTextPosition,
16    NumberRange,
17    XyxDataSeries,
18    ColumnAnimation,
19    XyDataSeries,
20    DefaultPaletteProvider,
21    TSciChart,
22    parseColorToUIntArgb,
23} from "scichart";
24
25import { appTheme } from "../../../theme";
26import { data } from "./atp-rankings";
27
28type ATPMetadata = IPointMetadata & {
29    rank: number;
30    name: string;
31    country: string;
32};
33class CountryPaletteProvider extends DefaultPaletteProvider {
34    private colorMap: Map<string, { stroke: number; fill: number }> = new Map<
35        string,
36        { stroke: number; fill: number }
37    >();
38
39    constructor(wasmContext: TSciChart) {
40        super();
41        const countries = [
42            "SE",
43            "CS",
44            "US",
45            "EC",
46            "AT",
47            "HR",
48            "NL",
49            "UA",
50            "RU",
51            "ZA",
52            "AU",
53            "GB",
54            "CL",
55            "SK",
56            "BR",
57            "CH",
58            "CZ",
59            "AR",
60            "RS",
61            "JP",
62            "ES",
63            "YU",
64            "FR",
65            "CA",
66            "BG",
67            "BE",
68            "GR",
69            "IT",
70            "NO",
71            "DE",
72            "PL",
73            "DK",
74        ];
75        const max = countries.length - 1;
76        for (let i = 0; i < countries.length; i++) {
77            const country = countries[i];
78            const stroke = parseColorToUIntArgb(appTheme.SciChartJsTheme.getStrokeColor(i, max, wasmContext));
79            const fill = parseColorToUIntArgb(appTheme.SciChartJsTheme.getFillColor(i, max, wasmContext));
80            this.colorMap.set(country, { stroke, fill });
81        }
82    }
83
84    public overrideStrokeArgb(
85        xValue: number,
86        yValue: number,
87        index: number,
88        opacity?: number,
89        metadata?: IPointMetadata
90    ): number | undefined {
91        const country = (metadata as ATPMetadata).country;
92        return this.colorMap.get(country).stroke;
93    }
94
95    public overrideFillArgb(
96        xValue: number,
97        yValue: number,
98        index: number,
99        opacity?: number,
100        metadata?: IPointMetadata
101    ): number | undefined {
102        const country = (metadata as ATPMetadata).country;
103        return this.colorMap.get(country).fill;
104    }
105}
106
107export const drawExample = async (rootElement: string | HTMLDivElement) => {
108    const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
109        theme: appTheme.SciChartJsTheme,
110    });
111
112    // Setup axes
113    sciChartSurface.xAxes.add(
114        new NumericAxis(wasmContext, {
115            visibleRange: new NumberRange(0, 15),
116            isVisible: false,
117        })
118    );
119
120    sciChartSurface.yAxes.add(
121        new NumericAxis(wasmContext, {
122            visibleRange: new NumberRange(0.5, 10.5),
123            axisTitle: "Rank",
124            axisTitleStyle: {
125                fontSize: 18,
126            },
127            axisAlignment: EAxisAlignment.Left,
128            drawMajorBands: false,
129            drawLabels: true,
130            drawMinorGridLines: false,
131            drawMajorGridLines: false,
132            drawMinorTickLines: false,
133            drawMajorTickLines: false,
134            keepLabelsWithinAxis: false,
135            autoTicks: false,
136            flippedCoordinates: true,
137            majorDelta: 1,
138            labelPrecision: 0,
139            labelStyle: {
140                fontSize: 22,
141                fontFamily: "Arial",
142            },
143        })
144    );
145
146    sciChartSurface.yAxes.get(0).axisRenderer.hideOverlappingLabels = false;
147
148    sciChartSurface.title = [`ATP Year-end Top 10 in ${data[0].year.toString()}`];
149
150    const topMargin = 30;
151    const rightMargin = 30;
152    const bottomMargin = 30;
153    const leftMargin = 30;
154
155    sciChartSurface.padding = new Thickness(topMargin, rightMargin, bottomMargin, leftMargin);
156
157    const xValues: number[] = [];
158    const x1Values: number[] = [];
159    const yValues: number[] = [];
160    const metadata: ATPMetadata[] = [];
161
162    for (const element of data[0].top10) {
163        xValues.push(0);
164        yValues.push(element.rank);
165        x1Values.push(16 - element.rank);
166        metadata.push({ isSelected: false, ...element });
167    }
168
169    // setup data
170    const dataSeriesA = new XyxDataSeries(wasmContext, { xValues, yValues, x1Values, metadata });
171    const dataSeriesB = new XyxDataSeries(wasmContext);
172
173    const rectangleSeries = new FastRectangleRenderableSeries(wasmContext, {
174        dataSeries: dataSeriesA,
175        columnXMode: EColumnMode.StartEnd,
176        columnYMode: EColumnYMode.CenterHeight,
177        defaultY1: 1,
178        strokeThickness: 4,
179        opacity: 0.3,
180        paletteProvider: new CountryPaletteProvider(wasmContext),
181        dataLabels: {
182            skipMode: EDataLabelSkipMode.ShowAll,
183            verticalTextPosition: EVerticalTextPosition.Center,
184            horizontalTextPosition: EHorizontalTextPosition.Center,
185            style: {
186                fontFamily: "Arial",
187                fontSize: 16,
188            },
189            color: appTheme.ForegroundColor,
190            metaDataSelector: (md) => {
191                const metadata = md as ATPMetadata;
192                return `${metadata.name.toString()} (${metadata.country.toString()})`;
193            },
194            //updateTextInAnimation: true
195        },
196    });
197    sciChartSurface.renderableSeries.add(rectangleSeries);
198    // Setup animations
199
200    const updateData = (i: number, curDataSeries: XyxDataSeries, nextDataSeries: XyxDataSeries) => {
201        sciChartSurface.title = [`ATP Year-end Top 10 in ${data[i].year.toString()}`];
202        nextDataSeries.clear();
203        const cur: ATPMetadata[] = [];
204        const next = data[i].top10;
205        // Series animations work by animating values at the same index, so it is important to preserve the order of entries, which may be totally unrelated to the display order
206        for (let p = 0; p < curDataSeries.count(); p++) {
207            // Look at all existing entries
208            const e = curDataSeries.getMetadataAt(p) as ATPMetadata;
209            // see if they should still be on the chart in the next period
210            const eNext = next.find((n) => n.name === e.name);
211            if (eNext) {
212                // Add to next data with new value
213                nextDataSeries.append(0, eNext.rank, 16 - eNext.rank, { isSelected: false, ...eNext });
214            } else {
215                if (curDataSeries.getNativeYValues().get(p) > 0) {
216                    // If they are currently in view, set them to be out of view in next period
217                    nextDataSeries.append(0, 12, 0, e);
218                }
219            }
220            // track all the current entries
221            cur.push(e);
222        }
223        for (const element of next) {
224            // Find entries that are completely new
225            const isNew = cur.find((e) => e.name === element.name) === undefined;
226            if (isNew) {
227                // add out of view in current data, and with new value in next data
228                curDataSeries.append(0, 12, 0, { isSelected: false, ...element });
229                nextDataSeries.append(0, element.rank, 16 - element.rank, { isSelected: false, ...element });
230            }
231        }
232        //Create an animation which will call the update for the following period when it completes
233        const animation = new ColumnAnimation({
234            duration: 1000,
235            ease: easing.inOutQuart,
236            dataSeries: nextDataSeries as any as XyDataSeries,
237            onCompleted: () => {
238                if (i < data.length - 2) {
239                    updateData(i + 1, curDataSeries, nextDataSeries);
240                }
241            },
242        });
243        rectangleSeries.runAnimation(animation);
244    };
245
246    sciChartSurface.titleStyle = {
247        color: appTheme.ForegroundColor,
248        fontSize: 30,
249        alignment: ETextAlignment.Center,
250        position: ETitlePosition.Top,
251        placeWithinChart: false,
252        padding: Thickness.fromString("40 0 0 0"),
253    };
254    updateData(1, dataSeriesA, dataSeriesB);
255
256    return { sciChartSurface, wasmContext };
257};
258

Animated Columns Chart - JavaScript

Overview

This example demonstrates how to create an animated column chart visualizing ATP tennis rankings over time using SciChart.js. The implementation uses FastRectangleRenderableSeries with custom coloring by country and smooth animations between yearly data updates.

Technical Implementation

The chart initializes with a SciChartSurface and configures a flipped NumericAxis for rankings display. Data is loaded from a structured dataset containing player rankings by year. The ColumnAnimation handles transitions between years with easing functions for smooth movement.

Features and Capabilities

The example showcases dynamic data updates with player position changes animated over time. A custom CountryPaletteProvider assigns colors based on player nationality, while data labels display player names and countries. The chart title updates automatically to reflect the current year being displayed.

Integration and Best Practices

The vanilla JavaScript implementation demonstrates proper resource management with surface disposal. For performance, the animation uses efficient data series updates rather than recreating the entire chart. The example could be extended with interactive features using Chart Modifiers.

javascript Chart Examples & Demos

See Also: Charts added in v4 (16 Demos)

JavaScript Histogram Chart | Javascript Charts | SciChart.js

JavaScript Histogram Chart

Create a JavaScript Histogram Chart with custom texture fills and patterns. Try the SciChart.js library for seamless integration today.

JavaScript Gantt Chart | Javascript Charts | SciChart.js Demo

JavaScript Gantt Chart Example

Build a JavaScript Gantt Chart with SciChart. View the demo for horizontal bars, rounded corners and data labels to show project timelines and task completion.

JavaScript Choropleth Map | Javascript Charts | SciChart.js Demo

JavaScript Choropleth Map Example

Create a JavaScript Choropleth map, a type of thematic map where areas are shaded or patterned in proportion to the value of a variable being represented.

JavaScript Multi-Layer Map | Javascript Charts | SciChart.js

JavaScript Multi-Layer Map Example

Create a JavaScript Multi-Layer Map Example, using FastTriangleRenderableSeries with GeoJSON data-points using a constrained delaunay triangulation algorithm.

JavaScript Vector Field Plot | Javascript Charts | SciChart.js

JavaScript Vector Field Plot

View the JavaScript Vector Field Plot example from SciChart, including dynamic vector generation, gradient-colored segments, and interactive zoom/pan. Try demo.

JavaScript Waterfall Chart | Bridge Chart | SciChart.js

JavaScript Waterfall Chart | Bridge Chart

Build a JavaScript Waterfall Chart with dynamic coloring, multi-line data labels and responsive design. Try SciChart.js for seamless integration today.

JavaScript Box Plot Chart | Javascript Charts | SciChart.js Demo

JavaScript Box Plot Chart

Try the JavaScript Box-Plot Chart examples with developer-friendly chart lifecycle management, dynamic sub-surface positioning, and custom styling.

JavaScript Triangle Series | Triangle Mesh Chart | SciChart

JavaScript Triangle Series | Triangle Mesh Chart

Create JavaScript Triangle Meshes with the Triangle Series from SciChart. This demo supports strip mode, list mode and the drawing of polygons. View the example.

JavaScript Treemap Chart | Javascript Charts | SciChart.js Demo

JavaScript Treemap Chart

Create a JavaScript Treemap Chart to define rectangle positions based on total value. Use SciChart FastRectangleRenderableSeries and d3-hierarchy.js layouts.

NEW!
JavaScript Map Chart with Heatmap overlay | SciChart.js

JavaScript Map Chart with Heatmap overlay

Design a highly dynamic JavaScript Map Chart with Heatmap overlay with SciChart's feature-rich JavaScript Chart Library. Get your free demo today.

Realtime Audio Analyzer Bars Demo | SciChart.js Demo

Realtime Audio Analyzer Bars Demo

Demonstrating the capability of SciChart.js to create a JavaScript Audio Analyzer Bars and visualize the Fourier-Transform of an audio waveform in realtime.

JavaScript Linear Gauges | Javascript Charts | SciChart.js Demo

JavaScript Linear Gauges Example

View the JavaScript Linear Gauge Chart example to combine rectangles & annotations. Create a linear gauge dashboard with animated indicators and custom scales.

NEW!
JavaScript Order of Rendering | Javascript Charts | SciChart.js

JavaScript Order of Rendering Example

The JavaScript Order of Rendering example gives you full control of the draw order of series and annotations for charts. Try SciChart's advanced customizations.

Responsive HTML Annotations | Javascript Charts | SciChart.js

JavaScript Responsive HTML Annotations Example

Build Responsive JavaScript HTML Annotations with SciChart. Use the advanced CSS container queries for responsive text layout and custom design. View demo now.

HTML Annotations and Custom in-chart Controls | SciChart

HTML Annotations and Custom in-chart Controls Example

JavaScript HTML Chart Control example demonstrates advanced HTML annotation integration and how to render HTML components within charts. Try the SciChart demo.

JavaScript Polar Modifiers | Polar Interactivity Modifiers

JavaScript Polar Modifiers | Polar Interactivity Modifiers Demo

Explore SciChart's Polar Interactivity Modifiers including zooming, panning, and cursor tracking. Try the demo to trial the Polar Chart Behavior Modifiers.

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL.