Using Series Selection

Demonstrates how to add Series Selection to a chart using SciChart.js, High Performance JavaScript Charts

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.html

vanilla.ts

theme.ts

Copy to clipboard
Minimise
Fullscreen
1import { appTheme } from "../../../theme";
2
3import {
4    ECoordinateMode,
5    EHorizontalAnchorPoint,
6    IRenderableSeries,
7    NumericAxis,
8    NumberRange,
9    SciChartSurface,
10    SplineLineRenderableSeries,
11    TextAnnotation,
12    XyDataSeries,
13    SeriesSelectionModifier,
14    AUTO_COLOR,
15    EPointMarkerType,
16    LegendModifier,
17    GenericAnimation,
18} from "scichart";
19
20// Generate some data for the example
21const dataSize = 30;
22const xValues: number[] = [];
23const yValues: number[] = [];
24const y1Values: number[] = [];
25const y2Values: number[] = [];
26const y3Values: number[] = [];
27const y4Values: number[] = [];
28for (let i = 0; i < dataSize; i++) {
29    xValues.push(i);
30    y4Values.push(Math.random());
31    y3Values.push(Math.random() + 1);
32    y2Values.push(Math.random() + 1.8);
33    y1Values.push(Math.random() + 2.5);
34    yValues.push(Math.random() + 3.6);
35}
36
37// Custom function called when series is hovered
38const onHoveredChanged = (sourceSeries: IRenderableSeries, isHovered: boolean) => {
39    console.log(`Series ${sourceSeries.dataSeries.dataSeriesName} isHovered=${isHovered}`);
40    const targetSeriesOpacity = 1;
41    const otherSeriesOpacity = isHovered ? 0.3 : 1;
42
43    const sciChartSurface = sourceSeries.parentSurface;
44    const otherSeries = sciChartSurface.renderableSeries.asArray().filter((rs) => rs !== sourceSeries);
45
46    // Use the genericanimations feature to animate opacity on the hovered series
47    // TODO: SciChart devs will think of a way to make this code more succinct!
48    sciChartSurface.addAnimation(
49        new GenericAnimation({
50            from: sourceSeries.opacity,
51            to: targetSeriesOpacity,
52            duration: 100,
53            onAnimate: (from, to, progress) => {
54                const opacity = (to - from) * progress + from;
55                sourceSeries.opacity = opacity;
56                sourceSeries.pointMarker.opacity = opacity;
57            },
58        })
59    );
60    // Dim opacity on the other non-hovered series
61    sciChartSurface.addAnimation(
62        new GenericAnimation({
63            from: otherSeries[0].opacity,
64            to: otherSeriesOpacity,
65            duration: 100,
66            onAnimate: (from, to, progress) => {
67                const opacity = (to - from) * progress + from;
68                otherSeries.forEach((rs) => {
69                    rs.opacity = opacity;
70                    rs.pointMarker.opacity = opacity;
71                });
72            },
73        })
74    );
75};
76
77// Custom function called when a series is selected or deselected
78const onSelectedChanged = (sourceSeries: IRenderableSeries, isSelected: boolean) => {
79    console.log(`Series ${sourceSeries.dataSeries.dataSeriesName} isSelected=${isSelected}`);
80
81    // When selected, set the stroke = white, or reset previous value
82    const targetSeriesStroke = isSelected ? appTheme.ForegroundColor : sourceSeries.pointMarker.fill;
83    sourceSeries.stroke = targetSeriesStroke;
84    sourceSeries.pointMarker.stroke = targetSeriesStroke;
85};
86
87export const drawExample = async (rootElement: string | HTMLDivElement) => {
88    const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
89        theme: appTheme.SciChartJsTheme,
90    });
91
92    sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
93    sciChartSurface.yAxes.add(
94        new NumericAxis(wasmContext, {
95            growBy: new NumberRange(0.1, 0.1),
96        })
97    );
98
99    sciChartSurface.chartModifiers.add(
100        new SeriesSelectionModifier({
101            enableHover: true,
102            enableSelection: true,
103        })
104    );
105
106    sciChartSurface.renderableSeries.add(
107        new SplineLineRenderableSeries(wasmContext, {
108            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues, dataSeriesName: "First Series" }),
109            pointMarker: {
110                type: EPointMarkerType.Ellipse,
111                options: { fill: AUTO_COLOR, stroke: AUTO_COLOR, strokeThickness: 3, width: 20, height: 20 },
112            },
113            strokeThickness: 3,
114            onHoveredChanged,
115            onSelectedChanged,
116        })
117    );
118
119    sciChartSurface.renderableSeries.add(
120        new SplineLineRenderableSeries(wasmContext, {
121            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: y1Values, dataSeriesName: "Second Series" }),
122            pointMarker: {
123                type: EPointMarkerType.Ellipse,
124                options: { fill: AUTO_COLOR, stroke: AUTO_COLOR, strokeThickness: 3, width: 20, height: 20 },
125            },
126            strokeThickness: 3,
127            onHoveredChanged,
128            onSelectedChanged,
129        })
130    );
131
132    sciChartSurface.renderableSeries.add(
133        new SplineLineRenderableSeries(wasmContext, {
134            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: y2Values, dataSeriesName: "Third Series" }),
135            pointMarker: {
136                type: EPointMarkerType.Ellipse,
137                options: { fill: AUTO_COLOR, stroke: AUTO_COLOR, strokeThickness: 3, width: 20, height: 20 },
138            },
139            strokeThickness: 3,
140            onHoveredChanged,
141            onSelectedChanged,
142        })
143    );
144
145    sciChartSurface.renderableSeries.add(
146        new SplineLineRenderableSeries(wasmContext, {
147            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: y3Values, dataSeriesName: "Fourth Series" }),
148            pointMarker: {
149                type: EPointMarkerType.Ellipse,
150                options: { fill: AUTO_COLOR, stroke: AUTO_COLOR, strokeThickness: 3, width: 20, height: 20 },
151            },
152            strokeThickness: 3,
153            onHoveredChanged,
154            onSelectedChanged,
155        })
156    );
157
158    // Add title annotation
159    sciChartSurface.annotations.add(
160        new TextAnnotation({
161            text: "Hover, Click & Select to animate style!",
162            fontSize: 20,
163            textColor: appTheme.ForegroundColor,
164            x1: 0.5,
165            y1: 0,
166            opacity: 0.77,
167            horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
168            xCoordinateMode: ECoordinateMode.Relative,
169            yCoordinateMode: ECoordinateMode.Relative,
170        })
171    );
172
173    // Add a legend to the chart
174    sciChartSurface.chartModifiers.add(new LegendModifier({ margin: 25 }));
175
176    return { sciChartSurface, wasmContext };
177};
178

Chart Series Selection/Hover in JavaScript

Overview

This example demonstrates how to implement interactive series selection and hover events in SciChart.js using JavaScript. Multiple renderable series are added to a chart and enhanced with custom event handlers to provide visual feedback when a series is hovered or selected. Developers can learn more about these capabilities by exploring the Series Selection documentation and the [SeriesSelectionModifier] TypeDoc API(https://www.scichart.com/documentation/js/v5/typedoc/classes/seriesselectionmodifier.html) reference.

Technical Implementation

The chart is initialized by calling SciChartSurface.create() with a WebAssembly context, and NumericAxis components are added to provide dynamic scaling with a customizable NumberRange. A SeriesSelectionModifier is added to the chart and onHoveredChanged and onSelectedChanged event handlers are implemented to adjust the opacity and stroke color of each series. In particular, the example uses GenericAnimation to smoothly transition visual properties when series are hovered, while other series are dimmed to emphasize the active one. Annotations such as TextAnnotation are added to display instructions and, together with a LegendModifier, help provide a legend which adds context to the data.

Features and Capabilities

This example highlights several advanced features of SciChart.js including:

  • Interactive Series Selection: Implemented via the SeriesSelectionModifier, enabling both hover and click-based selection events.
  • Custom Animations: Smooth transitions for visual feedback are achieved using GenericAnimation, allowing dynamic changes in opacity and stroke color.
  • Annotations and Legends: A text annotation provides user guidance while a legend is integrated using the LegendModifier for clear data series labeling.
  • Resource Management: The chart instance is properly disposed of using the delete method on the SciChartSurface, following best practices detailed in the Getting Started with SciChart JS guide.

Integration and Best Practices

While this example is implemented using JavaScript, it demonstrates patterns that are easily transferable to frameworks like React, Angular, or Vue. Developers are encouraged to follow efficient performance practices by leveraging the WebAssembly context (wasmContext) for processing large datasets, as showcased in the SciChart.js Performance Demo.

This comprehensive example serves as a practical guide for adding interactivity and advanced visual customizations to SciChart.js charts using plain JavaScript while adhering to best practices for performance optimization and resource management.

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