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