Demonstrates real-time oscilloscope style effects with SciChart.js, High Performance JavaScript Charts
drawExample.ts
index.html
ExampleDataProvider.ts
vanilla.ts
theme.ts
1import {
2 CentralAxesLayoutManager,
3 EAxisAlignment,
4 EInnerAxisPlacementCoordinateMode,
5 FastLineRenderableSeries,
6 GlowEffect,
7 ICentralAxesLayoutManagerOptions,
8 NumberRange,
9 NumericAxis,
10 SciChartSurface,
11 XyDataSeries,
12} from "scichart";
13import { ExampleDataProvider } from "../../../ExampleData/ExampleDataProvider";
14import { appTheme } from "../../../theme";
15
16const AMPLITUDE = 200;
17
18export const drawExample = async (rootElement: string | HTMLDivElement) => {
19 const { wasmContext, sciChartSurface } = await SciChartSurface.create(rootElement, {
20 theme: appTheme.SciChartJsTheme,
21 });
22
23 // Optional parameters to control exact placement of the axis
24 // Below: These are defaults, but we specify them for completeness of the example
25 // Relative coordinate mode and 0.5 means 'place half way'
26 const options: ICentralAxesLayoutManagerOptions = {
27 horizontalAxisPositionCoordinateMode: EInnerAxisPlacementCoordinateMode.Relative,
28 verticalAxisPositionCoordinateMode: EInnerAxisPlacementCoordinateMode.Relative,
29 horizontalAxisPosition: 0.5,
30 verticalAxisPosition: 0.5,
31 };
32
33 // Configure x,y axis with central layout - oscilloscope style
34 sciChartSurface.xAxes.add(
35 new NumericAxis(wasmContext, {
36 visibleRange: new NumberRange(0, 900),
37 isInnerAxis: true,
38 axisAlignment: EAxisAlignment.Top,
39 labelStyle: {
40 color: appTheme.PaleSkyBlue,
41 },
42 axisBorder: {
43 borderTop: 1,
44 color: appTheme.VividSkyBlue,
45 },
46 })
47 );
48
49 sciChartSurface.yAxes.add(
50 new NumericAxis(wasmContext, {
51 visibleRange: new NumberRange(-300, 300),
52 isInnerAxis: true,
53 axisAlignment: EAxisAlignment.Left,
54 labelStyle: {
55 color: appTheme.PaleSkyBlue,
56 },
57 axisBorder: {
58 borderLeft: 1,
59 color: appTheme.VividSkyBlue,
60 },
61 })
62 );
63
64 // Control the placement of the axis by specifying CentralAxesLayoutManager
65 // and isInnerAxis property
66 sciChartSurface.layoutManager = new CentralAxesLayoutManager(options);
67
68 const addSeries = (stroke: string, opacity: number) => {
69 const amplitude = Math.random() * AMPLITUDE;
70 const effect = new GlowEffect(wasmContext, {
71 range: 0,
72 intensity: 0.5,
73 });
74 const lineSeries = new FastLineRenderableSeries(wasmContext, { stroke, effect });
75 lineSeries.strokeThickness = 3;
76 lineSeries.opacity = opacity;
77 sciChartSurface.renderableSeries.add(lineSeries);
78 const { xValues, yValues } = ExampleDataProvider.getNoisySinewave(500, 900, 7, amplitude, 30);
79 lineSeries.dataSeries = new XyDataSeries(wasmContext, { xValues, yValues });
80 return lineSeries;
81 };
82
83 const seriesColor = appTheme.VividTeal;
84 const series1 = addSeries(seriesColor, 1);
85 const series2 = addSeries(seriesColor, 0.9);
86 const series3 = addSeries(seriesColor, 0.8);
87 const series4 = addSeries(seriesColor, 0.7);
88 const series5 = addSeries(seriesColor, 0.6);
89 const series6 = addSeries(seriesColor, 0.5);
90 const series7 = addSeries(seriesColor, 0.4);
91 const series8 = addSeries(seriesColor, 0.3);
92 const series9 = addSeries(seriesColor, 0.2);
93 const series10 = addSeries(seriesColor, 0.1);
94
95 let timerId: NodeJS.Timeout;
96
97 const reassignRenderableSeries = () => {
98 const oldSeries = series10.dataSeries;
99 series10.dataSeries = series9.dataSeries;
100 series9.dataSeries = series8.dataSeries;
101 series8.dataSeries = series7.dataSeries;
102 series7.dataSeries = series6.dataSeries;
103 series6.dataSeries = series5.dataSeries;
104 series5.dataSeries = series4.dataSeries;
105 series4.dataSeries = series3.dataSeries;
106 series3.dataSeries = series2.dataSeries;
107 series2.dataSeries = series1.dataSeries;
108
109 const amplitude = Math.random() * AMPLITUDE;
110 const dataSeries = new XyDataSeries(wasmContext);
111 ExampleDataProvider.fillNoisySinewave(500, 900, 7, amplitude, 30, dataSeries);
112 series1.dataSeries = dataSeries;
113 // To prevent memory leak we should delete
114 oldSeries.delete();
115
116 timerId = setTimeout(reassignRenderableSeries, 20);
117 };
118
119 const stopUpdate = () => {
120 clearTimeout(timerId);
121 timerId = undefined;
122 };
123
124 // Buttons for chart
125 const startUpdate = () => {
126 if (timerId) {
127 stopUpdate();
128 }
129 reassignRenderableSeries();
130 };
131
132 return { wasmContext, sciChartSurface, controls: { startUpdate, stopUpdate } };
133};
134This example demonstrates how to create a realtime oscilloscope‐style chart with ghosted traces using SciChart.js in JavaScript. The chart is built by manually configuring chart components such as axes, renderable series, and custom layout managers without relying on higher-level frameworks. The purpose of the example is to simulate continuous data updates, creating a layered “ghosting” effect by stacking multiple traces with decreasing opacity.
The core of the implementation is found in the drawExample.js file. A new chart is created via the call to SciChartSurface.create(), following the guidelines in the Getting Started with SciChart JS documentation and the Tutorial 01 - Including SciChart.js in an HTML Page using CDN documentation. Two NumericAxis objects are added, one for the x-axis and one for the y-axis, and a CentralAxesLayoutManager is used to position the axes centrally as detailed in the Central Axis Layout documentation. The example constructs ten instances of FastLineRenderableSeries with a glow effect created via GlowEffect and links them to noisy sinewave data generated using a ExampleDataProvider. To simulate realtime data, a function continuously reassigns the data series from one renderable series to the next and creates a new data series for the first trace. The process uses a recursive setTimeout (every 20ms) to update the data, a pattern that is explained in the DataSeries Realtime Updates documentation. To manage memory, the example ensures that every old data series is deleted once it has been replaced, following best practices available in the Memory Best Practices guide.
The example showcases several advanced features of SciChart.js including:
FastLineRenderableSeries are rendered with the same color but with decreasing opacity to produce a fading ghost effect. Additional visual polish is achieved by applying a Glow Effect to each series.XyDataSeries to generate and update the noisy sinewave data is central to the technique, as referenced in the XyDataSeries API documentation.Although this example is implemented in JavaScript, its techniques can be adapted for integration within other frameworks. The core logic of realtime updates, memory management, and visual customization is separated from any framework-specific code. This approach allows developers to integrate similar implementations into Angular, React or other environments by simply referencing the core drawing function. Additionally, the performance implications of using recursive setTimeout for realtime updates are discussed in various performance optimization guides, which can be helpful when adapting this example for high-frequency data updates.

This demo showcases the incredible realtime performance of our JavaScript charts by updating the series with millions of data-points!

This demo showcases the incredible performance of our JavaScript Chart by loading 500 series with 500 points (250k points) instantly!

This demo showcases the incredible performance of our JavaScript Chart by loading a million points instantly.

See the frequency of recordings with the JavaScript audio spectrum analyzer example from SciChart. This real-time visualizer demo uses a Fourier Transform.

Demonstrates how to create Oil and Gas Dashboard

This demo showcases the incredible realtime performance of our JavaScript charts by updating the series with millions of data-points!

This dashboard demo showcases the incredible realtime performance of our JavaScript charts by updating the series with millions of data-points!

This demo showcases the incredible realtime performance of our JavaScript charts by updating the series with millions of data-points!

Demonstrates a custom modifier which can convert from single chart to grid layout and back.

Demonstrates how to repurpose a Candlestick Series into dragabble, labled, event markers

Population Pyramid of Europe and Africa

Demonstrates how to use the SVG render layer in SciChart.js to maintain smooth cursor interaction on heavy charts with millions of points.