Datapoint Metadata Tooltips on React Chart

Demonstrates how to add and use MetaData in a chart using SciChart.js, High Performance JavaScript Charts

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.tsx

theme.ts

Copy to clipboard
Minimise
Fullscreen
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};
177

MetaData Labels, Tooltips and Rendering on a React Chart

Overview

This 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.

Technical Implementation

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.

Features and Capabilities

Key features of this example include:

  • Custom point coloring and highlighting based on metadata values
  • Dynamic labeling where data labels are automatically derived from each point's metadata
  • Advanced tooltips that display additional metadata such as custom labels and selection status
  • The use of SplineLineRenderableSeries with custom point markers for enhanced visual style The performance is optimized by leveraging asynchronous chart initialization and WebAssembly for high-performance rendering.

Integration and Best Practices

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.

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL.