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.tsx

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 React

Overview

This example demonstrates how to implement Series Selection in a SciChart.js chart within a React application. It showcases interactive features where users can hover over and select chart series, triggering animations and visual style changes in real-time.

Technical Implementation

Leveraging the React framework, the chart is initialized using the SciChartReact component. A dedicated draw function sets up the SciChartSurface with a SeriesSelectionModifier, numeric X and Y axes and adds multiple spline line series, each equipped with custom event callbacks for hover (onHoveredChanged) and selection (onSelectedChanged) events. These event callbacks use the GenericAnimation API to smoothly animate opacity transitions and update visual properties such as stroke and point markers. Annotations and legends are also incorporated to provide context and enhance user interaction, as detailed in the SciChart.js Series Selection Documentation.

Features and Capabilities

This example highlights several key features including real-time hover effects, series selection modifications, and animated transitions. When a series is hovered, it smoothly transitions to full opacity while the others are dimmed. Selecting a series updates its visual style to distinguish it further, ensuring clear feedback for user interactions. The chart also includes text annotations and an integrated legend to improve usability and data interpretation.

Integration and Best Practices

By utilizing the modular nature of React, the example cleanly separates chart initialization from the component structure, following best practices for performance and maintainability. The use of event callbacks for dynamic style updates and the implementation of smooth animations with GenericAnimation are excellent examples of optimizing interactive charting in a React environment. Developers seeking further guidance on integrating SciChart.js with React may also refer to the React integration best practices for more detailed insights.

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