Datapoint Metadata Tooltips on Angular 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 an Angular Chart

Overview

This example demonstrates how to integrate SciChart.js within an Angular application to render a high performance 2D chart. Each data point carries custom metadata that drives dynamic point coloring, advanced tooltips, and data labels. The example leverages asynchronous chart initialization along with WebAssembly rendering for optimal performance.

Technical Implementation

The chart is created asynchronously using SciChart.js's API where numeric axes, a spline line series, and annotations are programmatically configured. A data series is constructed by mapping raw X and Y values along with metadata - custom JavaScript objects containing properties which can drive label text, custom data-point color, and selection state. This metadata is then utilized in multiple ways: a custom PaletteProvider dynamically adjusts point marker colors based on metadata, a custom DataLabelProvider extracts labels directly from metadata for each point, and a RolloverModifier displays interactive tooltips that include metadata details. For additional details on implementing metadata-driven tooltips and data labels, refer to the Metadata and Tooltips documentation. The asynchronous initialization approach and Angular integration using ScichartAngularComponent is further detailed in the Getting Started with SciChart JS guide.

Features and Capabilities

The example includes real-time interactive updating of point appearance based on metadata, custom point coloring using a PaletteProvider, and dynamic labeling via a DataLabelProvider. Interactive tooltips display extra information such as custom labels and selection status, enhancing user interaction. The implementation leverages WebAssembly for high performance rendering, ensuring that even with these advanced features the chart remains responsive. Developers can explore the customization options provided by the PaletteProvider API and further refine label behavior as described in Getting Labels from Metadata.

Integration and Best Practices

In Angular applications, managing the chart lifecycle is crucial. The example demonstrates efficient integration by initializing the chart asynchronously and ensuring proper disposal to prevent memory leaks. Performance enhancements are achieved through the use of WebAssembly and optimized rendering techniques outlined in the Performance Optimisation of JavaScript Applications & Charts guide. This approach emphasizes best practices for integrating complex, high performance charts in Angular environments while offering extensive customization through metadata.

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