Angular Animated Bar Chart Example

Creates a Angular 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

angular.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 - Angular

Overview

This Angular standalone component demonstrates an animated tennis rankings visualization using SciChart.js. The implementation uses the scichart-angular package for seamless integration with Angular's component system.

Technical Implementation

The chart is configured through the drawExample function passed to the ScichartAngularComponent. It creates a SciChartSurface with a FastRectangleRenderableSeries using EColumnYMode.CenterHeight for proper column sizing.

Features and Capabilities

The component animates yearly ranking changes with smooth transitions using ColumnAnimation. A custom palette provider colors columns by player nationality, and data labels display player information. The flipped Y-axis correctly represents ranking positions.

Integration and Best Practices

The example follows Angular best practices by using standalone components and proper dependency management. The scichart-angular wrapper handles chart lifecycle management, including WebAssembly context creation and cleanup.

angular Chart Examples & Demos

See Also: Charts added in v4 (16 Demos)

Angular Histogram Chart | Angular Charts | SciChart.js Demo

Angular Histogram Chart

Create an Angular Histogram Chart with custom texture fills and patterns. Try the SciChartAngular wrapper component for seamless Angular integration today.

Angular Gantt Chart | Angular Charts | SciChart.js Demo

Angular Gantt Chart Example

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

Angular Choropleth Map | Angular Charts | SciChart.js Demo

Angular Choropleth Map Example

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

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

Angular Multi-Layer Map Example

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

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

Angular Vector Field Plot

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

Angular Waterfall Chart | Bridge Chart | SciChart.js Demo

Angular Waterfall Chart | Bridge Chart

Build an Angular Waterfall Chart with dynamic coloring, multi-line data labels & responsive design, using ScichartAngular component for seamless integration

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

Angular Box Plot Chart

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

Angular Triangle Series | Triangle Mesh Chart | SciChart

Angular Triangle Series | Triangle Mesh Chart

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

Angular Treemap Chart | Angular Charts | SciChart.js Demo

Angular Treemap Chart

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

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

Angular Map Chart with Heatmap overlay

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

Angular Linear Gauges | Angular Charts | SciChart.js Demo

Angular Linear Gauges Example

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

NEW!
Angular Order of Rendering | Angular Charts | SciChart.js

Angular Order of Rendering Example

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

Angular Responsive HTML Annotations Example

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

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

Angular Polar Modifiers | Polar Interactivity Modifiers

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