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.
drawExample.ts
index.tsx
theme.ts
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};
170This example demonstrates a high performance, virtualized charting solution implemented with React and SciChart.js. The application dynamically loads a subset of data based on the current zoom and pan state of the main chart while concurrently displaying an overview chart that represents the entire dataset to provide context.
The implementation utilizes the <SciChartReact/> component within a functional React component using hooks. The main chart initializes with a numeric x-axis and y-axis, and uses a FastLineRenderableSeries to render data fetched asynchronously via the fetch API. To optimize performance and avoid unnecessary data requests, RxJS's debounceTime operator is used to throttle updates triggered by visibleRangeChanged events. The overview chart is created manually using SciChartOverview with its own data series, highlighting a master-detail chart synchronization pattern. As the chart is zoomed or scrolled, data is fetched from REST endpoints using the fetch API, and the number of loaded data points is adjusted, providing a virtualized big-data chart.
This solution delivers real-time updates through efficient asynchronous data loading and utilizes advanced interaction modifiers such as zoom, pan, and drag for an engaging user experience. The overview chart efficiently represents the full data range, while the main chart focuses on a detailed view with optimized data rendering. Developers can further explore robust React chart integration for techniques to handle high data rates.
The example leverages React hooks for state management and lifecycle handling to ensure charts are only rendered after full initialization. It follows best practices for asynchronous data fetching, handling errors with user notifications directly on the chart.

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

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

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

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

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

Demonstrates how to zoom and pan with an Overview Chart

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

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

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