The PointMetadata API in SciChart.js allows you to:
- Tag any X,Y point in a DataSeries with a custom JavaScript object
- It can be used with the DataPoint Selection Modifier to enable per-point selection
- It can be used with the PaletteProvider API to provide custom colouring of data-points in a series.
- It can be used with tooltips such as CursorModifier and RolloverModifier to display extra data or info inside a tooltip
- Finally, it can be used in the result of any Hit-Test operation where X,Y,Metadata can be queried on click
Adding Metadata to Charts
Metadata is optional and can be set when a dataseries is first created, or whenever data is added or updated. Metadata is just a JavaScript object and can contain any properties, objects, even functions.
See the example below for how to create metadata when constructing an XyDataSeries and how to consume it in a RolloverModifier.
This results in the following output
<div id="scichart-root" ></div>
body { margin: 0; }
#scichart-root { width: 100%; height: 100vh; }
async function addingMetadata(divElementId) {
// #region ExampleA
// Demonstrates how to add PointMetadata to a DataSeries and consume it in SciChart.js
const {
SciChartSurface,
NumericAxis,
FastLineRenderableSeries,
XyDataSeries,
SciChartJsNavyTheme,
EllipsePointMarker,
NumberRange,
RolloverModifier
} = SciChart;
// or, for npm, import { SciChartSurface, ... } from "scichart"
const { wasmContext, sciChartSurface } = await SciChartSurface.create(divElementId, {
theme: new SciChartJsNavyTheme(),
});
const growBy = new NumberRange(0.1, 0.1);
sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { growBy }));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { growBy }));
// Create metadata with initial values. Metadata can be any JS object
const dataSeries = new XyDataSeries(wasmContext, {
xValues: [1, 2, 3, 4, 5],
yValues: [4.3, 5.3, 6, 6.3, 6.4],
metadata: [
{ stringValue: "Here's", customValue: 7 },
undefined, // nothing at this index
{ stringValue: "Some" },
{ }, // empty object at this index
{ stringValue: "Metadata", customValue: 99},
]
});
// Add a line series with the metadata
sciChartSurface.renderableSeries.add(new FastLineRenderableSeries(wasmContext, {
dataSeries,
pointMarker: new EllipsePointMarker(wasmContext, { width: 11, height: 11, fill: "#364BA0", stroke: "#50C7E0", strokeThickness: 2 }),
}));
// Add a RolloverModifier configured to output X,Y,Metadata.stringValue and customValue
sciChartSurface.chartModifiers.add(new RolloverModifier( {
snapToDataPoint: true,
tooltipDataTemplate: (seriesInfo) => [
`X: ${seriesInfo.formattedXValue}`,
`Y: ${seriesInfo.formattedYValue}`,
`Metadata.stringValue: ${seriesInfo.pointMetadata?.stringValue ?? 'null'}`,
`Metadata.customValue: ${seriesInfo.pointMetadata?.customValue ?? 'null'}`
]
}));
// #endregion
const { TextAnnotation, EHorizontalAnchorPoint, ECoordinateMode, EAnnotationLayer } = SciChart;
const options = {
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
x1: 0.5,
y1: 0.5,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.33,
textColor: "White",
};
sciChartSurface.annotations.add(new TextAnnotation({
text: "Create Metadata Example",
fontSize: 36,
yCoordShift: -125,
... options,
}));
sciChartSurface.annotations.add(new TextAnnotation({
text: "Hover over the chart to see metadata",
fontSize: 20,
yCoordShift: -75,
... options,
}));
};
addingMetadata("scichart-root");
async function builderExample(divElementId) {
// #region ExampleB
// Demonstrates how to add PointMetadata to a DataSeries and consume it in SciChart.js with the BuilderAPI
const {
chartBuilder,
ESeriesType,
EThemeProviderType,
EChart2DModifierType,
EPointMarkerType
} = SciChart;
// or, for npm, import { chartBuilder, ... } from "scichart"
const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(divElementId, {
surface: { theme: { type: EThemeProviderType.Dark } },
series: [
{
type: ESeriesType.LineSeries,
// Metadata is set in xyData property
xyData: {
xValues: [1, 2, 3, 4, 5],
yValues: [4.3, 5.3, 6, 6.3, 6.4],
metadata: [
{ stringValue: "Here's", customValue: 7 },
undefined, // nothing at this index
{ stringValue: "Some" },
{ }, // empty object at this index
{ stringValue: "Metadata", customValue: 99},
]
},
options: {
stroke: "#C52E60",
pointMarker: {
type: EPointMarkerType.Ellipse,
options: {
width: 11, height: 11, fill: "White"
}
}
}
}
],
// Configure a Rollovermodifier to display metadata
modifiers: [{
type: EChart2DModifierType.Rollover,
options: {
snapToDataPoint: true,
tooltipDataTemplate: (seriesInfo) => [
`X: ${seriesInfo.formattedXValue}`,
`Y: ${seriesInfo.formattedYValue}`,
`Metadata.stringValue: ${seriesInfo.pointMetadata?.stringValue ?? 'null'}`,
`Metadata.customValue: ${seriesInfo.pointMetadata?.customValue ?? 'null'}`
]
}
}]
});
// #endregion
};
// Uncomment this to use the builder example
//builderExample("scichart-root");
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:
<div id="scichart-root" ></div>
body { margin: 0; }
#scichart-root { width: 100%; height: 100vh; }
async function metadataTemplates(divElementId) {
// Demonstrates how to add PointMetadata to a DataSeries and consume it in SciChart.js
const {
SciChartSurface,
NumericAxis,
FastLineRenderableSeries,
XyDataSeries,
SciChartJsNavyTheme,
EllipsePointMarker,
NumberRange,
RolloverModifier
} = SciChart;
// or, for npm, import { SciChartSurface, ... } from "scichart"
const { wasmContext, sciChartSurface } = await SciChartSurface.create(divElementId, {
theme: new SciChartJsNavyTheme(),
});
const growBy = new NumberRange(0.1, 0.1);
sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { growBy }));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { growBy }));
// #region ExampleA
// Set a single object, this will be cloned as a template for all metadata on the dataseries
const dataSeries = new XyDataSeries(wasmContext, {
xValues: [1, 2, 3, 4, 5],
yValues: [4.3, 5.3, 6, 6.3, 6.4],
metadata: { stringValue: "All the same value", customValue: 7 },
});
// Update just a metadata value
// Update just a metadata value. This will not trigger a chart redraw
dataSeries.getMetadataAt(0).stringValue = "Updated #0";
// To force a redraw, use update and pass a new metadata object
dataSeries.update(1, 5.3, { stringValue: "Updated #1 with redraw", customValue: 99 });
// Or, to trigger a redraw, call invalidateElement() on the parent SciChartSurface
sciChartSurface.invalidateElement();
// #endregion
// Add a line series with the metadata
sciChartSurface.renderableSeries.add(new FastLineRenderableSeries(wasmContext, {
dataSeries,
pointMarker: new EllipsePointMarker(wasmContext, { width: 11, height: 11, fill: "White" }),
}));
// Add a RolloverModifier configured to output X,Y,Metadata.stringValue and customValue
sciChartSurface.chartModifiers.add(new RolloverModifier( {
snapToDataPoint: true,
tooltipDataTemplate: (seriesInfo) => [
`X: ${seriesInfo.formattedXValue}`,
`Y: ${seriesInfo.formattedYValue}`,
`Metadata.stringValue: ${seriesInfo.pointMetadata?.stringValue ?? 'null'}`,
`Metadata.customValue: ${seriesInfo.pointMetadata?.customValue ?? 'null'}`
]
}));
// #endregion
const { TextAnnotation, EHorizontalAnchorPoint, ECoordinateMode, EAnnotationLayer } = SciChart;
const options = {
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
x1: 0.5,
y1: 0.5,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.33,
textColor: "White",
};
sciChartSurface.annotations.add(new TextAnnotation({
text: "Metadata Templates Example",
fontSize: 36,
yCoordShift: -125,
... options,
}));
sciChartSurface.annotations.add(new TextAnnotation({
text: "Hover over the chart to see metadata",
fontSize: 20,
yCoordShift: -75,
... options,
}));
};
metadataTemplates("scichart-root");
async function builderExample(divElementId) {
// Demonstrates how to add PointMetadata to a DataSeries and consume it in SciChart.js with the BuilderAPI
const {
chartBuilder,
ESeriesType,
EThemeProviderType,
EChart2DModifierType,
EPointMarkerType
} = SciChart;
// or, for npm, import { chartBuilder, ... } from "scichart"
// #region ExampleB
const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(divElementId, {
surface: { theme: { type: EThemeProviderType.Dark } },
series: [
{
type: ESeriesType.LineSeries,
// Metadata is set in xyData property
xyData: {
xValues: [1, 2, 3, 4, 5],
yValues: [4.3, 5.3, 6, 6.3, 6.4],
metadata: { stringValue: "All the same value", customValue: 7 },
},
// ...
// #endregion
options: {
stroke: "#C52E60",
pointMarker: {
type: EPointMarkerType.Ellipse,
options: {
width: 11, height: 11, fill: "White"
}
}
}
}
],
// Configure a Rollovermodifier to display metadata
modifiers: [{
type: EChart2DModifierType.Rollover,
options: {
snapToDataPoint: true,
tooltipDataTemplate: (seriesInfo) => [
`X: ${seriesInfo.formattedXValue}`,
`Y: ${seriesInfo.formattedYValue}`,
`Metadata.stringValue: ${seriesInfo.pointMetadata?.stringValue ?? 'null'}`,
`Metadata.customValue: ${seriesInfo.pointMetadata?.customValue ?? 'null'}`
]
}
}]
});
};
// Uncomment this to use the builder example
//builderExample("scichart-root");
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.
Before this class can be used with the builder api it must be registered. Then, it can be used like this:
<div id="scichart-root" ></div>
body { margin: 0; }
#scichart-root { width: 100%; height: 100vh; }
// #region ExampleA
// Create a metadata class. Confirms to interface I1DMetadataGenerator
class ExampleMetadataGenerator {
// Accept and store the raw data in the constructor
constructor (stringArray) {
console.log(`${stringArray}`);
this.stringValues = stringArray
this.type = "ExampleMetadataGenerator";
};
// This is called by SciChart to get the metadata to set when the dataSeries is created
getMetadata = () => this.stringValues.map(s => ({ stringValue: s }));
// Unused for this example. Used to create a clone of metadata template for each datapoint
getSingleMetadata = () => ({ stringValue: "" });
// Required for serialization and builder API
toJSON = () => ({ type: this.type, data: this.stringValues });
}
// #endregion
async function metadataGenerators(divElementId) {
// Demonstrates how to add PointMetadata to a DataSeries and consume it in SciChart.js
const {
SciChartSurface,
NumericAxis,
FastLineRenderableSeries,
XyDataSeries,
SciChartJsNavyTheme,
EllipsePointMarker,
NumberRange,
RolloverModifier,
EBaseType,
chartBuilder
} = SciChart;
// or, for npm, import { SciChartSurface, ... } from "scichart"
const { wasmContext, sciChartSurface } = await SciChartSurface.create(divElementId, {
theme: new SciChartJsNavyTheme(),
});
const growBy = new NumberRange(0.1, 0.1);
sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { growBy }));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { growBy }));
// #region ExampleB
// call chartBuilder.registerType to register a new custom type
chartBuilder.registerType(EBaseType.MetadataGenerator, "ExampleMetadataGenerator", (data) => new ExampleMetadataGenerator(data));
// Assign a Metadata generator instance to create metadata dynamically
const dataSeries = new XyDataSeries(wasmContext, {
xValues: [1, 2, 3, 4, 5],
yValues: [4.3, 5.3, 6, 6.3, 6.4],
metadata: { type: "ExampleMetadataGenerator", data: ["Here's", "Some", "Metadata", "From", "Generator"] },
});
// #endregion
// Add a line series with the metadata
sciChartSurface.renderableSeries.add(new FastLineRenderableSeries(wasmContext, {
dataSeries,
pointMarker: new EllipsePointMarker(wasmContext, { width: 11, height: 11, fill: "White" }),
}));
// Add a RolloverModifier configured to output X,Y,Metadata.stringValue and customValue
sciChartSurface.chartModifiers.add(new RolloverModifier( {
snapToDataPoint: true,
tooltipDataTemplate: (seriesInfo) => [
`X: ${seriesInfo.formattedXValue}`,
`Y: ${seriesInfo.formattedYValue}`,
`Metadata.stringValue: ${seriesInfo.pointMetadata?.stringValue ?? 'null'}`
]
}));
// #endregion
const { TextAnnotation, EHorizontalAnchorPoint, ECoordinateMode, EAnnotationLayer } = SciChart;
const options = {
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
x1: 0.5,
y1: 0.5,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.33,
textColor: "White",
};
sciChartSurface.annotations.add(new TextAnnotation({
text: "Metadata Generators Example",
fontSize: 36,
yCoordShift: -125,
... options,
}));
sciChartSurface.annotations.add(new TextAnnotation({
text: "Hover over the chart to see metadata",
fontSize: 20,
yCoordShift: -75,
... options,
}));
};
metadataGenerators("scichart-root");
async function builderExample(divElementId) {
// Demonstrates how to add PointMetadata to a DataSeries and consume it in SciChart.js with the BuilderAPI
const {
chartBuilder,
ESeriesType,
EThemeProviderType,
EChart2DModifierType,
EPointMarkerType,
EBaseType
} = SciChart;
// or, for npm, import { chartBuilder, ... } from "scichart"
// #region ExampleC
// call chartBuilder.registerType to register a new custom type
chartBuilder.registerType(EBaseType.MetadataGenerator, "ExampleMetadataGenerator", (data) => new ExampleMetadataGenerator(data));
const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(divElementId, {
surface: { theme: { type: EThemeProviderType.Dark } },
series: [
{
type: ESeriesType.LineSeries,
// Metadata is set in xyData property
xyData: {
xValues: [1, 2, 3, 4, 5],
yValues: [4.3, 5.3, 6, 6.3, 6.4],
metadata: { type: "ExampleMetadataGenerator", data: ["Here's", "Some", "Metadata", "From", "Generator"] },
},
// ...
// #endregion
options: {
stroke: "#C52E60",
pointMarker: {
type: EPointMarkerType.Ellipse,
options: {
width: 11, height: 11, fill: "White"
}
}
}
}
],
// Configure a Rollovermodifier to display metadata
modifiers: [{
type: EChart2DModifierType.Rollover,
options: {
snapToDataPoint: true,
tooltipDataTemplate: (seriesInfo) => [
`X: ${seriesInfo.formattedXValue}`,
`Y: ${seriesInfo.formattedYValue}`,
`Metadata.stringValue: ${seriesInfo.pointMetadata?.stringValue ?? 'null'}`
]
}
}]
});
};
// Uncomment this to use the builder example
//builderExample("scichart-root");