React Animated Bar Chart Example

Creates a React 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.tsx

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 - React

Overview

This React example creates an animated visualization of ATP tennis rankings using SciChart.js. The component leverages the SciChartReact wrapper for seamless integration with React's lifecycle.

Technical Implementation

The chart is initialized via the initChart prop which creates a SciChartSurface with a FastRectangleRenderableSeries. The implementation uses EColumnMode.StartEnd for precise column positioning and a custom palette provider for country-based coloring.

Features and Capabilities

The component automatically animates between yearly ranking data using ColumnAnimation with easing functions. Data labels show player information, and the chart title updates dynamically. The flipped Y-axis properly displays rankings with #1 at the top.

Integration and Best Practices

The example demonstrates React best practices by encapsulating chart logic in the drawExample function. The SciChartReact component handles surface creation and cleanup automatically. For larger datasets, consider implementing virtualized data loading.

react Chart Examples & Demos

See Also: Charts added in v4 (16 Demos)

React Histogram Chart | React Charts | SciChart.js Demo

React Histogram Chart

Create a React Histogram Chart with custom texture fills and patterns. Try the SciChartReact wrapper component for seamless React integration today.

React Gantt Chart | React Charts | SciChart.js Demo

React Gantt Chart Example

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

React Choropleth Map | React Charts | SciChart.js Demo

React Choropleth Map Example

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

React Multi-Layer Map | React Charts | SciChart.js Demo

React Multi-Layer Map Example

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

React Vector Field Plot | React Charts | SciChart.js Demo

React Vector Field Plot

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

React Waterfall Chart | Bridge Chart | SciChart.js Demo

React Waterfall Chart | Bridge Chart

Build a React Waterfall Chart with dynamic coloring, multi-line data labels and responsive design, using the SciChartReact component for seamless integration.

React Box Plot Chart | React Charts | SciChart.js Demo

React Box Plot Chart

Try the React Box Plot Chart example for React-friendly chart lifecycle management, dynamic sub-surface positioning, and custom styling. Try the demo now.

React Triangle Series | Triangle Mesh Chart | SciChart.js

React Triangle Series | Triangle Mesh Chart

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

React Treemap Chart | React Charts | SciChart.js Demo

React Treemap Chart

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

NEW!
React Map Chart with Heatmap overlay | SciChart.js Demo

React Map Chart with Heatmap overlay

Design a highly dynamic React 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.

React Linear Gauges | React Charts | SciChart.js Demo

React Linear Gauges Example

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

NEW!
React Order of Rendering | React Charts | SciChart.js Demo

React Order of Rendering Example

The React 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 | React Charts | SciChart.js

React Responsive HTML Annotations Example

Build Responsive React 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

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

React Polar Modifiers | Polar Interactivity Modifiers

React 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.