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    LegendModifier,
16    GenericAnimation,
17    EllipsePointMarker,
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: new EllipsePointMarker(wasmContext, {
110                fill: AUTO_COLOR,
111                stroke: AUTO_COLOR,
112                strokeThickness: 3,
113                width: 20,
114                height: 20,
115            }),
116            strokeThickness: 3,
117            onHoveredChanged,
118            onSelectedChanged,
119        })
120    );
121
122    sciChartSurface.renderableSeries.add(
123        new SplineLineRenderableSeries(wasmContext, {
124            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: y1Values, dataSeriesName: "Second Series" }),
125            pointMarker: new EllipsePointMarker(wasmContext, {
126                fill: AUTO_COLOR,
127                stroke: AUTO_COLOR,
128                strokeThickness: 3,
129                width: 20,
130                height: 20,
131            }),
132            strokeThickness: 3,
133            onHoveredChanged,
134            onSelectedChanged,
135        })
136    );
137
138    sciChartSurface.renderableSeries.add(
139        new SplineLineRenderableSeries(wasmContext, {
140            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: y2Values, dataSeriesName: "Third Series" }),
141            pointMarker: new EllipsePointMarker(wasmContext, {
142                fill: AUTO_COLOR,
143                stroke: AUTO_COLOR,
144                strokeThickness: 3,
145                width: 20,
146                height: 20,
147            }),
148            strokeThickness: 3,
149            onHoveredChanged,
150            onSelectedChanged,
151        })
152    );
153
154    sciChartSurface.renderableSeries.add(
155        new SplineLineRenderableSeries(wasmContext, {
156            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues: y3Values, dataSeriesName: "Fourth Series" }),
157            pointMarker: new EllipsePointMarker(wasmContext, {
158                fill: AUTO_COLOR,
159                stroke: AUTO_COLOR,
160                strokeThickness: 3,
161                width: 20,
162                height: 20,
163            }),
164            strokeThickness: 3,
165            onHoveredChanged,
166            onSelectedChanged,
167        })
168    );
169
170    // Add title annotation
171    sciChartSurface.annotations.add(
172        new TextAnnotation({
173            text: "Hover, Click & Select to animate style!",
174            fontSize: 20,
175            textColor: appTheme.ForegroundColor,
176            x1: 0.5,
177            y1: 0,
178            opacity: 0.77,
179            horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
180            xCoordinateMode: ECoordinateMode.Relative,
181            yCoordinateMode: ECoordinateMode.Relative,
182        })
183    );
184
185    // Add a legend to the chart
186    sciChartSurface.chartModifiers.add(new LegendModifier({ margin: 25 }));
187
188    return { sciChartSurface, wasmContext };
189};
190

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.