Demonstrates how to add and use MetaData in a chart using SciChart.js, High Performance JavaScript Charts
drawExample.ts
index.tsx
theme.ts
1import { appTheme } from "../../../theme";
2
3import {
4 DataLabelState,
5 ECoordinateMode,
6 EHorizontalAnchorPoint,
7 EStrokePaletteMode,
8 IPointMetadata,
9 IPointMarkerPaletteProvider,
10 IRenderableSeries,
11 LineSeriesDataLabelProvider,
12 NumericAxis,
13 NumberRange,
14 parseColorToUIntArgb,
15 SciChartSurface,
16 SplineLineRenderableSeries,
17 TextAnnotation,
18 TPointMarkerArgb,
19 TWebAssemblyChart,
20 Thickness,
21 TSciChart,
22 XyDataSeries,
23 XySeriesInfo,
24 EllipsePointMarker,
25 RolloverModifier,
26} from "scichart";
27
28export const drawExample = async (rootElement: string | HTMLDivElement): Promise<TWebAssemblyChart> => {
29 // Create a chart with X, Y axis
30 const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
31 theme: appTheme.SciChartJsTheme,
32 });
33 sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
34 sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { growBy: new NumberRange(0.2, 0.2) }));
35
36 // Given a dataset with X, Y but also additional values in the form of an object of any kind
37 const dataValues = [
38 { x: 0, y: 50, anObject: { label: "", pointColor: "#F48420", isSelected: false } },
39 { x: 1, y: 35, anObject: { label: "Orange Point", pointColor: "#F48420", isSelected: false } },
40 { x: 2, y: 68, anObject: { label: "Highest Point", pointColor: "#7BCAAB", isSelected: false } },
41 { x: 3, y: 58, anObject: { label: "Selected Point", pointColor: "#F48420", isSelected: true } },
42 { x: 4, y: 50, anObject: { label: "Orange Point", pointColor: "#F48420", isSelected: false } },
43 { x: 5, y: 50, anObject: { label: "", pointColor: "#F48420", isSelected: false } },
44 { x: 6, y: 40, anObject: { label: "Blue Point", pointColor: "#50C7E0", isSelected: false } },
45 { x: 7, y: 53, anObject: { label: "Selected Point", pointColor: "#F48420", isSelected: true } },
46 { x: 8, y: 55, anObject: { label: "", pointColor: "#F48420", isSelected: false } },
47 { x: 9, y: 23, anObject: { label: "Blue Point", pointColor: "#50C7E0", isSelected: false } },
48 { x: 10, y: 45, anObject: { label: "Selected Point", pointColor: "#F48420", isSelected: true } },
49 { x: 11, y: 12, anObject: { label: "Lowest Point", pointColor: "#EC0F6C", isSelected: false } },
50 { x: 12, y: 59, anObject: { label: "", pointColor: "#F48420", isSelected: false } },
51 { x: 13, y: 60, anObject: { label: "", pointColor: "#F48420", isSelected: false } },
52 ];
53
54 // You can create a dataseries with these object values as metadata
55 const xyDataSeriesWithMetadata = new XyDataSeries(wasmContext, {
56 xValues: dataValues.map((row) => row.x),
57 yValues: dataValues.map((row) => row.y),
58 metadata: dataValues.map((row) => row.anObject), // put any javascript object here
59 });
60
61 // You can assign this dataseries to a RenderableSeries in SciChart
62 const lineSeries = new SplineLineRenderableSeries(wasmContext, {
63 dataSeries: xyDataSeriesWithMetadata,
64 stroke: appTheme.VividSkyBlue,
65 strokeThickness: 3,
66 pointMarker: new EllipsePointMarker(wasmContext, {
67 width: 15,
68 height: 15,
69 strokeThickness: 0,
70 }),
71 });
72
73 // Now you can consume metadata in the following ways
74 // - Colouring points
75 // - Labelling points
76 // - Custom data for tooltips
77 // - Tagging datapoints with the objects for later use
78 //
79
80 // 1. via paletteprovider (colour points or segments based on metadata values)
81
82 // @ts-ignore
83 const getColorFromMetadata = (metadata) => {
84 // @ts-ignore
85 const pointColorArgb = parseColorToUIntArgb(metadata.pointColor);
86 const selectedColorArgb = 0xffffffff;
87 const fill = metadata.isSelected ? selectedColorArgb : pointColorArgb;
88 return fill;
89 };
90
91 const pointPaletteProvider: IPointMarkerPaletteProvider = {
92 strokePaletteMode: EStrokePaletteMode.SOLID,
93 onAttached(parentSeries: IRenderableSeries): void {},
94 onDetached(): void {},
95 overridePointMarkerArgb(
96 xValue: number,
97 yValue: number,
98 index: number,
99 opacity?: number,
100 metadata?: IPointMetadata
101 ): TPointMarkerArgb {
102 // Metadata values can be used in paletteprovider overrides
103 if (metadata) {
104 const fill = getColorFromMetadata(metadata);
105 return { stroke: fill, fill };
106 }
107 return undefined; // means use default colour
108 },
109 };
110 lineSeries.paletteProvider = pointPaletteProvider;
111
112 // 2. Via DataLabel provider
113 const dataLabelProvider = new LineSeriesDataLabelProvider({
114 // @ts-ignore
115 metaDataSelector: (metadata) => metadata.label, // This is how you route a label (string) from metadata to data-labels in scichart
116 style: { fontFamily: "Arial", fontSize: 16, padding: new Thickness(5, 5, 5, 5) },
117 color: appTheme.ForegroundColor,
118 });
119 lineSeries.dataLabelProvider = dataLabelProvider;
120 // This is how you override colors of labels on a per-label basis, which can also come from metadata
121 dataLabelProvider.getColor = (state: DataLabelState, label: string) => {
122 const metadata = state.getMetaData();
123 return getColorFromMetadata(metadata);
124 };
125
126 // 3. Via cursors and tooltips
127 lineSeries.rolloverModifierProps.markerColor = appTheme.DarkIndigo;
128 lineSeries.rolloverModifierProps.tooltipColor = appTheme.Indigo;
129 lineSeries.rolloverModifierProps.tooltipDataTemplate = (seriesInfo: XySeriesInfo): string[] => {
130 const valuesWithLabels: string[] = [];
131 // Line Series
132 const xySeriesInfo = seriesInfo as XySeriesInfo;
133
134 valuesWithLabels.push("X Value: " + xySeriesInfo.formattedXValue);
135 valuesWithLabels.push("Y Value: " + xySeriesInfo.formattedYValue);
136
137 valuesWithLabels.push(" ");
138 if (seriesInfo.pointMetadata) {
139 // @ts-ignore
140 let label = seriesInfo.pointMetadata.label;
141 label = label === "" ? "..." : label;
142 valuesWithLabels.push(`Metadata Label: "${label}"`);
143 // @ts-ignore
144 valuesWithLabels.push("Metadata Selected: " + seriesInfo.pointMetadata.isSelected);
145 }
146 return valuesWithLabels;
147 };
148
149 sciChartSurface.renderableSeries.add(lineSeries);
150
151 // Add a RolloverModifier for tooltips
152 sciChartSurface.chartModifiers.add(
153 new RolloverModifier({
154 showRolloverLine: false,
155 showTooltip: true,
156 })
157 );
158
159 // Add title annotation
160 sciChartSurface.annotations.add(
161 new TextAnnotation({
162 text: "Line Chart with Metadata (Objects per data-point)",
163 fontSize: 18,
164 textColor: appTheme.ForegroundColor,
165 x1: 0.5,
166 y1: 0,
167 opacity: 0.77,
168 horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
169 xCoordinateMode: ECoordinateMode.Relative,
170 yCoordinateMode: ECoordinateMode.Relative,
171 })
172 );
173
174 sciChartSurface.zoomExtents();
175 return { sciChartSurface, wasmContext };
176};
177This example demonstrates how to integrate SciChart.js within a React application to create high performance charts that leverage custom metadata. The chart renders a spline line chart where each Xy data point holds additional metadata (a custom JavaScript object). This metadata is used to drive custom point styling, data labels, and interactive tooltips.
The chart is initialized asynchronously using the SciChartSurface.create() function and is embedded within a React component using the <SciChartReact/> wrapper, as described in the React Charts with SciChart.js guide. A data series is constructed by mapping an array of objects with extra metadata to the XyDataSeries. Custom styling is implemented by overriding point marker colors through a custom PaletteProvider that implements the IPointMarkerPaletteProvider interface. Additionally, dynamic data labels are provided via the LineSeriesDataLabelProvider, enabling labels to be sourced directly from the metadata (see DataLabels from Metadata documentation). Additionally, the example shows how chart modifiers such as the RolloverModifier can be utilized to enhance user interaction by providing real-time metadata-driven tooltips.
Key features of this example include:
SplineLineRenderableSeries with custom point markers for enhanced visual style
The performance is optimized by leveraging asynchronous chart initialization and WebAssembly for high-performance rendering.The example illustrates best practices for integrating SciChart.js in React. By utilizing the <SciChartReact/> component, developers can ensure that the chart integrates smoothly with React’s component lifecycle. For further insight into efficient React integration and performance optimization techniques, refer to the React Charts with SciChart.js article and the Performance Optimisation of JavaScript Applications & Charts resource.

Demonstrates Hit-Testing a React Chart - point and click on the chart and get feedback about what data-points were clicked

Demonstrates adding Tooltips on mouse-move to a React Chart with SciChart.js RolloverModifier

Demonstrates adding a Cursor (Crosshair) to a React Chart with SciChart.js CursorModifier

Demonstrates adding Tooltips at certain positions to a React Chart with SciChart.js VerticalSliceModifier

Demonstrates Hit-Testing a React Chart - point and click on the chart and get feedback about what data-points were clicked

Demonstrates the DatapointSelectionModifier, which provides a UI to select one or many data points, and works with DataPointSelectionPaletteProvider to change the appearance of selected points

Demonstrates how to customise the tooltips for Rollover, Cursor and VerticalSlice modifiers in a React Chart with SciChart.js