Virtualized Angular Charts: Load Data on Zoom/Pan

Whenever the visible range changes, the chart requests data from the server, which returns a reduced view of the dataset, in this case using a very simple take every nth point method. The overview is created manually because it does not share data with the main chart but has a reduced view of the entire dataset.

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.tsx

theme.ts

Copy to clipboard
Minimise
Fullscreen
1import { Subject, debounceTime } from "rxjs";
2
3import {
4    easing,
5    EAutoRange,
6    EAxisAlignment,
7    EHorizontalAnchorPoint,
8    EVerticalAnchorPoint,
9    EWrapTo,
10    EXyDirection,
11    FastLineRenderableSeries,
12    MouseWheelZoomModifier,
13    NativeTextAnnotation,
14    NumberRange,
15    NumericAxis,
16    SciChartOverview,
17    SciChartSurface,
18    XAxisDragModifier,
19    XyDataSeries,
20    YAxisDragModifier,
21    ZoomExtentsModifier,
22    ZoomPanModifier,
23    ECoordinateMode,
24    AxisBase2D,
25} from "scichart";
26import { appTheme } from "../../../theme";
27
28export const getChartsInitializationApi = () => {
29    let mainSurface: SciChartSurface;
30    let mainXAxis: AxisBase2D;
31    let mainDataSeries: XyDataSeries;
32
33    const createMainChart = async (rootElement: string | HTMLDivElement) => {
34        const { wasmContext, sciChartSurface } = await SciChartSurface.create(rootElement, {
35            theme: appTheme.SciChartJsTheme,
36        });
37        const xAxis = new NumericAxis(wasmContext, {
38            axisAlignment: EAxisAlignment.Bottom,
39            visibleRange: new NumberRange(4000000, 5000000),
40            autoRange: EAutoRange.Never,
41            labelPrecision: 0,
42            useNativeText: true,
43        });
44
45        sciChartSurface.xAxes.add(xAxis);
46        const yAxis = new NumericAxis(wasmContext, {
47            axisAlignment: EAxisAlignment.Right,
48            visibleRange: new NumberRange(-5000, 5000),
49            autoRange: EAutoRange.Never,
50            labelPrecision: 0,
51            useNativeText: true,
52        });
53        sciChartSurface.yAxes.add(yAxis);
54
55        const dataSeries = new XyDataSeries(wasmContext, { containsNaN: false, isSorted: true });
56        const rendSeries = new FastLineRenderableSeries(wasmContext, {
57            dataSeries,
58            strokeThickness: 2,
59            stroke: appTheme.VividOrange,
60        });
61        sciChartSurface.renderableSeries.add(rendSeries);
62        rendSeries.rolloverModifierProps.tooltipTextColor = "black";
63        rendSeries.rolloverModifierProps.showRollover = true;
64
65        sciChartSurface.chartModifiers.add(
66            new ZoomExtentsModifier({ xyDirection: EXyDirection.YDirection }),
67            new XAxisDragModifier(),
68            new YAxisDragModifier(),
69            new ZoomPanModifier({ enableZoom: true }),
70            new MouseWheelZoomModifier()
71        );
72
73        // Create an observable stream
74        const subject = new Subject<NumberRange>();
75
76        // Push visible range changes into the observable
77        xAxis.visibleRangeChanged.subscribe(async (args) => {
78            subject.next(args.visibleRange);
79        });
80
81        // subscribe to the observable with a debounce
82        subject.pipe(debounceTime(250)).subscribe((r: NumberRange) => {
83            // Fetch data and update the dataSeries
84            loadPoints(r.min, r.max, sciChartSurface.domCanvas2D.width, dataSeries)
85                .then(() => {
86                    // Update the y axis
87                    const yRange = yAxis.getWindowedYRange(null);
88                    yAxis.animateVisibleRange(yRange, 250, easing.outExpo);
89                })
90                .catch((err) =>
91                    showError(
92                        sciChartSurface,
93                        "Server data is unavailable.  Please do npm run build, then npm start and access the site at localhost:3000"
94                    )
95                );
96        });
97
98        mainSurface = sciChartSurface;
99        mainXAxis = xAxis;
100        mainDataSeries = dataSeries;
101
102        return { sciChartSurface };
103    };
104
105    const createOverview = async (rootElement: string | HTMLDivElement) => {
106        const overview = await SciChartOverview.create(mainSurface, rootElement, { theme: appTheme.SciChartJsTheme });
107        const overviewData = new XyDataSeries(mainSurface.webAssemblyContext2D, { containsNaN: false, isSorted: true });
108        // Load the full dataSet
109        loadPoints(0, 10000000, overview.overviewSciChartSurface.domCanvas2D.width, overviewData).catch((err) => {});
110
111        const overviewSeries = overview.overviewSciChartSurface.renderableSeries.get(0);
112        overviewSeries.dataSeries = overviewData;
113        overview.overviewSciChartSurface.zoomExtents();
114
115        return { sciChartSurface: overview.overviewSciChartSurface };
116    };
117
118    const afterOverviewInit = () => {
119        // Load initial data
120        loadPoints(
121            mainXAxis.visibleRange.min,
122            mainXAxis.visibleRange.max,
123            mainSurface.domCanvas2D.width,
124            mainDataSeries
125        )
126            .then(() => {
127                mainSurface.zoomExtents();
128            })
129            .catch((err) =>
130                showError(
131                    mainSurface,
132                    "Server data is unavailable.  Please do npm run build, then npm start and access the site at localhost:3000"
133                )
134            );
135    };
136
137    return { createMainChart, createOverview, afterOverviewInit };
138};
139
140const loadPoints = async (xFrom: number, xTo: number, chartWidth: number, dataSeries: XyDataSeries) => {
141    chartWidth = Math.floor(chartWidth);
142
143    const response = await fetch(`api/data/${xFrom}-${xTo}/${chartWidth}`);
144    const data: { x: number[]; y: number[] } = await response.json();
145    console.log(`Loaded ${data.x.length} points`);
146    dataSeries.clear();
147    dataSeries.appendRange(data.x, data.y);
148};
149
150const showError = (sciChartSurface: SciChartSurface, message: string) => {
151    if (!sciChartSurface.annotations.getById("error")) {
152        sciChartSurface.annotations.add(
153            new NativeTextAnnotation({
154                id: "error",
155                text: message,
156                x1: 0.5,
157                y1: 0.5,
158                textColor: "red",
159                fontSize: 24,
160                horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
161                verticalAnchorPoint: EVerticalAnchorPoint.Center,
162                xCoordinateMode: ECoordinateMode.Relative,
163                yCoordinateMode: ECoordinateMode.Relative,
164                lineSpacing: 5,
165                wrapTo: EWrapTo.ViewRect,
166            })
167        );
168    }
169};
170

Virtualized Data With Overview - Angular

Overview

This example demonstrates a high performance, virtualized data visualization solution using Angular and SciChart.js. It dynamically loads a reduced subset of data based on the current zoom and pan state while providing an overview chart that displays a condensed view of the full dataset for contextual insight.

Technical Implementation

The main chart is created by initializing a SciChartSurface with numeric axes and a FastLineRenderableSeries. Data is fetched asynchronously via the fetch API from a server endpoint and loaded into the chart using a custom function. To enhance responsiveness of the virtualized chart, RxJS’s debounceTime operator is used to throttle visible range change events from the x-axis, ensuring that expensive data requests occur only after interactions have settled. Interaction modifiers such as ZoomExtentsModifier, XAxisDragModifier, YAxisDragModifier, ZoomPanModifier, and MouseWheelZoomModifier provide intuitive chart navigation, as outlined in the SciChart.js documentation.

Features and Capabilities

This solution supports real-time updates by asynchronously loading only the necessary portion of data when the visible range changes. The independent overview chart, created using SciChartOverview, offers a reduced view of the entire dataset, enabling users to quickly navigate large data sets. The virtualized data rendering approach ensures that performance remains optimal even when dealing with extensive datasets.

Integration and Best Practices

The implementation leverages Angular’s component lifecycle by initializing the main chart before setting up the overview chart, ensuring that dependent chart components are rendered only after the necessary data and configurations are in place. This method aligns with Angular's best practices for lifecycle management when using the scichart-angular package. Additionally, performance optimization through RxJS and asynchronous data handling is crucial for maintaining responsiveness, making the example a solid reference for integrating high performance SciChart.js components in Angular applications.

angular Chart Examples & Demos

See Also: Zoom and Pan a Chart (9 Demos)

Angular Chart with Multiple X Axes | SciChart.js Demo

Angular Chart with Multiple X Axes

Demonstrates Multiple X & Y Axis on a Angular Chart using SciChart.js. SciChart supports unlimited left, right, top, bottom X, Y axis with configurable alignment and individual zooming, panning

Angular Chart with Secondary Y Axes | SciChart.js Demo

Angular Chart with Secondary Y Axes

Demonstrates Secondary Y Axis on a Angular Chart using SciChart.js. SciChart supports unlimited, multiple left, right, top, bottom X, Y axis with configurable alignment and individual zooming, panning

Drag Angular Chart Axis to Scale or Pan | SciChart.js

Drag Angular Chart Axis to Scale or Pan

Demonstrates how to Zoom, Scale or Pan individual Axis on a Angular Chart with SciChart.js AxisDragModifiers

Zoom and Pan a Realtime Angular Chart | SciChart.js Demo

Zoom and Pan a Realtime Angular Chart

Demonstrates how to zoom and pan a realtime Angular Chart while it is updating, with SciChart.js ZoomState API

Zoom and Pan with Angular Chart multiple Modifiers | SciChart

Zoom and Pan with Angular Chart multiple Modifiers

Demonstrates how to use multiple Zoom and Pan Modifiers on a Angular Chart with SciChart.js

Zoom and Pan with Overview Chart | Angular Charts | SciChart.js

Zoom and Pan with Overview Chart

Demonstrates how to zoom and pan with an Overview Chart

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.

NEW!
High Precision Date Axis | Angular Charts | SciChart.js Demo

High Precision Date Axis

Demonstrates 64-bit precision Date Axis in SciChart.js handling Nanoseconds to Billions of Years

NEW!
Angular Overview for SubCharts with Range Selection

Angular Overview for SubCharts with Range Selection

Demonstrates how to build synchronized multi-panel charts with an overview range selector using SciChart.js in Angular

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