SciChart.js JavaScript 2D Charts API > DataSeries API > DataSeries PointMetaData Api
DataSeries PointMetaData Api

SciChart.js v2.x or above now features a new API: The PointMetadata API. This allows you to store any additional kind of data to some or all x,y points in a data series.

This metadata can be used to:

  • Trade selected data points (see DataPoint Selection)
  • Change the stroke and fill and point-marker colours using a PaletteProvider
  • Display additional data in tooltips for CursorModifier and RolloverModifier, or generally as a result of any Hit-Test operation.

Adding Metadata to Series

Metadata is optional and can be set when a dataseries is first created, or whenever data is added or updated. The add, insert and update methods on a dataseries take an optional metadata parameter.

All metadata must implement the IPointMetadata interface, ie { isSelected: boolean }. Beyond that it can contain any kind of data, and even functions.

See the example below for how to create metadata when constructing an XyDataSeries and later when appending, inserting or updating that dataseries.

import {XyDataSeries} from "scichart/Charting/Model/XyDataSeries";

// Create metadata with initial values
const dataSeries = new XyDataSeries(wasmContext, {
    xValues: [1, 2, 3, 4],
    yValues: [4.3, 5.3, 6, 6.3],
    // Set optional metadata as an array of objects, one per x,y data-point
    metadata: [
        { isSelected: false, note: "This"},
        { isSelected: false, note: "is"},
        { isSelected: false, note: "some"},
        { isSelected: false, note: "metadata"}
    ]
});
// Append data with metadata
dataSeries.append(5, 6.5, { isSelected: false, note: "Appended", extra: 123 });
// Insert a point with metadata
dataSeries.insert(3, 3.5, 6.8, { isSelected: false, note: "Inserted"});
// Update a point and its metadata
dataSeries.update(0, 3.3, { isSelected: false, note: "Updated"});

Note: You do not have to set metadata on every point. The structure of the metadata does not have to be the same for every point.

Metadata Templates

If you just need to set the same metadata on every point, you can supply a single metadata object and it will be used as a template and be cloned onto each datapoint. For example:

import {XyDataSeries} from "scichart/Charting/Model/XyDataSeries";
import {SciChartSurface} from "scichart/Charting/Visuals/SciChartSurface";

// Create metadata with template
const dataSeries = new XyDataSeries(wasmContext, {
    xValues: [1, 2, 3, 4],
    yValues: [4.3, 5.3, 6, 6.3],
    metadata: { isSelected: false, note: ""} // Set single object, this will be cloned as a template for all metadata on the dataseries
});
// Update just a metadata value.  This will not trigger a chart redraw
dataSeries.getMetadataAt(0).note = "Updated";
// To force a redraw, use update and pass a new metadata object
dataSeries.update(0, 4.3, { isSelected: false, note: "Updated with redraw"});
// Or, to trigger a redraw, call invalidateElement() on the parent SciChartSurface
sciChartSurface.invalidatElement();

Metadata Generators

If you want to set complex metadata using the Builder Api you have the option to take control of how the metadata is deserialized and serialized by passing a MetadataGenerator. This is a class that should accept raw data in its constructor and have a getMetadata method that returns a metadata array.

class NoteMetadataGenerator {
    // Accept and store the raw data in the constructor
    constructor (data) {
        this.type = "noteGenerator";
        this.notes = data;
        // This is called by SciChart to get the metadata to set when the dataSeries is created
        this.getMetadata = () => this.notes.map(n => ({ isSelected: false, note: n }));
        this.toJSON = () => ({ type: this.type, data: this.notes });
    };
}
// Defining a Metadata Generator
class NoteMetadataGenerator implements I1DMetadataGenerator {
    type = "noteGenerator";
    notes: string[];
    // Accept and store the raw data in the constructor
    constructor (data: string[]) {
        this.notes = data;
    };
    // This is called by SciChart to get the metadata to set when the dataSeries is created
    getMetadata = () => this.notes.map(n => ({ isSelected: false, note: n }));
    toJSON = () => ({ type: this.type, data: this.notes });
    // unused for this example.  Used to create a clone of a metadata template for each data point.
    getSingleMetadata: () => IPointMetadata;
}

Before this class can be used with the builder api it must be registered. Then, it can be used like this:

import {chartBuilder} from "scichart/Builder/chartBuilder";
import {EBaseType} from "scichart/types/BaseType";

// call chartBuilder.registerType to register a new custom type
chartBuilder.registerType(EBaseType.MetadataGenerator, "noteGenerator", (data: any) => new NoteMetadataGenerator(data));

// use the chartBuilder api to build a chart with our NoteMetadataGenerator
chartBuilder.buildChart("scichart-div-id-4", {
    series: { type: ESeriesType.LineSeries, xyData: {
        xValues: [1, 2, 3, 4],
        yValues: [4.3, 5.3, 6, 6.3],
        metadata: { type: "noteGenerator", data: ["This", "is", "some", "metadata"] }
    }}
});
Note: for more info about the Builder API, please see the section in our documentation here.

Using Metadata to Colour Datapoints

SciChart.js features a powerful API - the PaletteProvider API - which allows you to individually colour line or mountain series segments, pointmarkers or candles / columns.

Metadata can be used as an input if you wanted to control series colour based on a custom object.

This example nelow uses metadata to drive line color explicitly.

import { XyDataSeries } from "scichart/Charting/Model/XyDataSeries";
import { parseColorToUIntArgb } from "scichart/utils/parseColor";

// Create series with metadata containing color
const dataSeries = new XyDataSeries(wasmContext, {
    xValues: [1, 2, 3, 4, 5],
    yValues: [4.3, 5.3, 6, 6.3, 5.7],
    metadata: [
        { isSelected: false, color: 'red' },
        { isSelected: false, color: 'green' },
        { isSelected: false },
        { isSelected: false, color: 'blue' },
        { isSelected: false },
    ],
});
// PaletteProvider implementing IStrokePaletteProvider
class LinePaletteProvider extends DefaultPaletteProvider {
    constructor() {
        super();
        this.strokePaletteMode = EStrokePaletteMode.SOLID;
    }
    overrideStrokeArgb(xValue, yValue, index, opacity, metadata) {
        if (metadata && metadata.color) {
            return parseColorToUIntArgb(metadata.color);
        } else {
            return undefined;
        }
    }
}
// Renderable series using the paletteProvider
const series = new FastLineRenderableSeries(wasmContext, {
    dataSeries,
    paletteProvider: new LinePaletteProvider(),
    strokeThickness: 5,
});

This example produces the following chart:

To learn more about the PaletteProvider API, see the documentation pages here.

Using Metadata in Modifier Tooltips

Using the ChartModifier API you can add tooltips and cursors to a SciChartSurface. See the documentation for RolloverModifier and CursorModifier for two ways to do this.

Maybe you want certain property from Metadata to appear in tooltips. If so, you can use some code like this:

// Create metadata with initial values
const dataSeries = new XyDataSeries(wasmContext, {
    xValues: [1, 2, 3, 4],
    yValues: [4.3, 5.3, 6, 6.3],
    metadata: [
        { isSelected: false, note: "This"},
        { isSelected: false, note: "is"},
        { isSelected: false, note: "some"},
        { isSelected: false, note: "metadata"}
    ]
});
// A function to get the text for the rolloverModifer tooltip
const metadataTooltipDataTemplate = (seriesInfo) => {
    const valuesWithLabels = [];
    if (seriesInfo.pointMetadata) {
        valuesWithLabels.push("Note: " + seriesInfo.pointMetadata.note);
    }
    valuesWithLabels.push("X: " + seriesInfo.formattedXValue + " Y: " + seriesInfo.formattedYValue);
    return valuesWithLabels;
};
const series = new FastLineRenderableSeries(wasmContext, { dataSeries, strokeThickness: 5 });
// You can set the toolTipDataTemplate on the RolloverModifier
sciChartSurface.chartModifiers.add(new RolloverModifier({tooltipDataTemplate: metadataTooltipDataTemplate }));
// Or if you need different templates for different series, set it on the renderableSeries
// renderableSeries1.rolloverModifierProps.tooltipDataTemplate = metadataTooltipDataTemplate;

The above example produces this chart.

Retrieving Metadata during Hit-Test (on Mouse Click)