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

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

React Chart with Multiple X Axes | SciChart.js Demo

React Chart with Multiple X Axes

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

React Chart with Secondary Y Axes | SciChart.js Demo

React Chart with Secondary Y Axes

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

Drag React Chart Axis to Scale or Pan | SciChart.js Demo

Drag React Chart Axis to Scale or Pan

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

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

Zoom and Pan a Realtime React Chart

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

Zoom and Pan with React Chart multiple Modifiers | SciChart.js Demo

Zoom and Pan with React Chart multiple Modifiers

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

Zoom and Pan with Overview Chart | SciChart.js Demo

Zoom and Pan with Overview Chart

Demonstrates how to zoom and pan with an Overview Chart

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