Showcases how SciChart.js can load and display 1-Million Data-points in milliseconds. Click the Reload button at the bottom of the demo to see the chart draw again.
import {
EAxisAlignment,
EAutoRange,
ECoordinateMode,
EHorizontalAnchorPoint,
EAnnotationLayer,
EVerticalAnchorPoint,
FastLineRenderableSeries,
MouseWheelZoomModifier,
NumericAxis,
NumberRange,
SciChartSurface,
TextAnnotation,
XyDataSeries,
ZoomExtentsModifier,
ZoomPanModifier,
} from "scichart";
import { appTheme } from "./appTheme";
export type TTimeSpan = {
title: string;
durationMs: number;
};
export const drawExample = async (rootElement: string | HTMLDivElement) => {
const { wasmContext, sciChartSurface } = await SciChartSurface.create(rootElement, {
theme: appTheme.SciChartJsTheme,
});
sciChartSurface.xAxes.add(
new NumericAxis(wasmContext, {
// axisTitle: "X Axis",
visibleRange: new NumberRange(0, 1000000),
autoRange: EAutoRange.Never,
useNativeText: true,
})
);
sciChartSurface.yAxes.add(
new NumericAxis(wasmContext, {
// axisTitle: "Y Axis",
axisAlignment: EAxisAlignment.Left,
visibleRange: new NumberRange(-5000, 5000),
autoRange: EAutoRange.Never,
useNativeText: true,
})
);
const watermarkAnnotation = (text: string, offset: number = 0) => {
const annotation = new TextAnnotation({
text,
fontSize: 42,
fontWeight: "Bold",
textColor: appTheme.ForegroundColor,
x1: 0.5,
y1: 0.5,
yCoordShift: offset,
opacity: 0.33,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
verticalAnchorPoint: EVerticalAnchorPoint.Center,
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
annotationLayer: EAnnotationLayer.BelowChart,
});
return annotation;
};
// add a title annotation
sciChartSurface.annotations.add(watermarkAnnotation("SciChart.js Performance Demo"));
sciChartSurface.annotations.add(watermarkAnnotation("1 Million Data-Points", 52));
const POINTS = 1_000_000;
const dataSeries = new XyDataSeries(wasmContext, { capacity: POINTS, isSorted: true, containsNaN: false });
sciChartSurface.renderableSeries.add(
new FastLineRenderableSeries(wasmContext, {
dataSeries,
stroke: appTheme.VividSkyBlue,
strokeThickness: 2,
})
);
sciChartSurface.chartModifiers.add(
new ZoomExtentsModifier(),
new ZoomPanModifier({ enableZoom: true }),
new MouseWheelZoomModifier()
);
let updateTimeSpans: (newTimeSpans: TTimeSpan[]) => void = () => null;
const xValues = new Float64Array(POINTS);
const yValues = new Float64Array(POINTS);
// Buttons for chart
const loadPoints = () => {
// Clear state
dataSeries.clear();
const newTimeSpans: TTimeSpan[] = [];
// Start clouting Points generation time
const generateTimestamp = Date.now();
let prevYValue = 0;
for (let i = 0; i < POINTS; i++) {
const curYValue = Math.random() * 10 - 5;
xValues[i] = i;
yValues[i] = prevYValue + curYValue;
prevYValue += curYValue;
}
// Add the first time span: Generating 1M data points
newTimeSpans.push({
title: "Generate 1M Data Points",
durationMs: Date.now() - generateTimestamp,
});
// Start counting batch append time
const appendTimestamp = Date.now();
dataSeries.appendRange(xValues, yValues);
// Add the second time span: Generation of data point
newTimeSpans.push({
title: "Append 1M Data Points",
durationMs: Date.now() - appendTimestamp,
});
// Subscribe to sciChartSurface.rendered event,
// and calculate time duration between the append and
// the first frame after it
const firstFrameTimestamp = Date.now();
let frameIndex: number = 0;
let nextFramesTimestamp: number;
const handler = () => {
if (frameIndex === 0) {
// Add the third time span: Render the first frame
newTimeSpans.push({
title: "Render the frame",
durationMs: Date.now() - firstFrameTimestamp,
});
nextFramesTimestamp = Date.now();
} else {
// Unsubscribe from sciChartSurface.rendered
updateTimeSpans(newTimeSpans);
sciChartSurface.rendered.unsubscribe(handler);
// Zoom extents at the end of performance measurement
sciChartSurface.zoomExtents(250);
}
setTimeout(sciChartSurface.invalidateElement, 0);
// Increment frame index
frameIndex++;
};
sciChartSurface.rendered.subscribe(handler);
};
let timerId: NodeJS.Timeout;
const startUpdate = () => {
timerId = setInterval(loadPoints, 200);
};
const stopUpdate = () => {
clearInterval(timerId);
};
const reloadOnce = () => {
loadPoints();
};
const subscribeToInfo = (listener: (newTimeSpans: TTimeSpan[]) => void) => {
updateTimeSpans = listener;
};
return { sciChartSurface, controls: { startUpdate, stopUpdate, reloadOnce, subscribeToInfo } };
};
This example demonstrates how to integrate SciChart.js within an Angular application to efficiently render one million data points in milliseconds. It showcases high-performance real-time charting while providing detailed performance measurements during data generation, appending, and rendering.
The implementation uses an Angular standalone component that imports the ScichartAngularComponent from the scichart-angular package and leverages Angular lifecycle hooks (such as OnInit) to initialize the chart. Within the component, NumericAxis are added and TextAnnotations are added to display a static watermark. Event binding is used to capture reload events and real-time updates of performance data, a technique further explained in Angular Data Binding: An Ultimate Guide By Experts.
Key capabilities include real-time update functionality, interactive reloads via native buttons styled with shared CSS classes, and precise performance tracking for data generation, data appending, and frame rendering. The example emphasizes an efficient handling of extensive datasets through clear performance results, making it an essential resource for developers looking to integrate high-frequency data updates in Angular applications.
The chart integration emphasizes best practices such as utilizing Angular dependency injection for modular configuration and capitalizing on Angular's robust event and data binding mechanisms. Shared CSS classes keep the user interface responsive and accessible. Developers can gain more insights into using dependency injection by visiting the Angular Dependency Injection guide and explore external library integrations through this Stack Overflow discussion. For additional performance optimization techniques, the Angular Performance Optimization article is a recommended resource.











