Demonstrates how to add and use MetaData in a chart using SciChart.js, High Performance JavaScript Charts
drawExample.ts
index.html
vanilla.ts
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 create an interactive line chart using SciChart.js with JavaScript. It visualizes a dataset where each Xy data point is augmented with metadata that drives customizations such as point colors, dynamic labels, and interactive tooltips.
The chart is set up by asynchronously initializing a SciChartSurface with configured X and Y axes using the NumericAxis class and a defined growBy range via NumberRange. An XyDataSeries is created by mapping the provided X and Y values and attaching a metadata object (a custom JavaScript object) for each Xy data point. Customizations are applied through a custom PaletteProvider that adjusts the color of each point marker based on metadata. This is achieved using the helper function parseColorToUIntArgb for color conversion. Additionally, a custom DataLabelProvider extracts labels from metadata with a metaDataSelector, following concepts from Getting Labels from Metadata. A RolloverModifier is employed to provide interactive tooltips, enabling dynamic adjustments of marker and tooltip colors based on the underlying data. Text annotations are added using the TextAnnotation class, which supports relative coordinate modes for flexible placement.
This example showcases metadata-driven customization where additional properties within each data point dictate not only the visual styling (such as point marker color via a custom palette provider) but also the data labels and tooltips. Such an approach allows each data point to be individually styled and can support features like highlighting or selection. Developers seeking to further understand the concepts can read about the DataSeries Metadata API here.
The implementation follows best practices for asynchronous initialization and resource cleanup in JavaScript, as shown by returning a destructor function that disposes of the SciChartSurface when no longer needed. This pattern is recommended in the Getting Started with SciChart JS guide. Although a React wrapper is provided in the project, the core implementation uses plain JavaScript, making it highly adaptable to various environments. By leveraging these techniques, developers can build highly interactive charts with a focus on performance and maintainability.

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

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

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

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

Demonstrates Hit-Testing a JavaScript 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 JavaScript Chart with SciChart.js