Using VerticalSliceModifier

Demonstrates how to use tooltips at fixed positions using SciChart.js, High Performance JavaScript Charts

Fullscreen

Edit

 Edit

Docs

drawExample.ts

angular.ts

ExampleDataProvider.ts

theme.ts

Copy to clipboard
Minimise
Fullscreen
1import { appTheme } from "../../../theme";
2import { ExampleDataProvider } from "../../../ExampleData/ExampleDataProvider";
3import {
4    EllipsePointMarker,
5    ENumericFormat,
6    FastLineRenderableSeries,
7    MouseWheelZoomModifier,
8    NumberRange,
9    NumericAxis,
10    RolloverLegendSvgAnnotation,
11    VerticalSliceModifier,
12    SciChartSurface,
13    XyDataSeries,
14    ZoomExtentsModifier,
15    ZoomPanModifier,
16    SeriesInfo,
17    TWebAssemblyChart,
18    ECoordinateMode,
19    NativeTextAnnotation,
20    EWrapTo,
21    EHorizontalAnchorPoint,
22    TextAnnotation,
23    Logger,
24} from "scichart";
25
26export const drawExample = async (rootElement: string | HTMLDivElement) => {
27    // Create a SciChartSurface with X,Y Axis
28    const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
29        theme: appTheme.SciChartJsTheme,
30    });
31    sciChartSurface.xAxes.add(
32        new NumericAxis(wasmContext, {
33            growBy: new NumberRange(0.05, 0.05),
34            labelFormat: ENumericFormat.Decimal,
35            labelPrecision: 4,
36        })
37    );
38
39    sciChartSurface.yAxes.add(
40        new NumericAxis(wasmContext, {
41            growBy: new NumberRange(0.1, 0.1),
42            labelFormat: ENumericFormat.Decimal,
43            labelPrecision: 4,
44        })
45    );
46
47    // Add some data
48    const data1 = ExampleDataProvider.getFourierSeriesZoomed(0.6, 0.13, 5.0, 5.15);
49    const lineSeries0 = new FastLineRenderableSeries(wasmContext, {
50        dataSeries: new XyDataSeries(wasmContext, {
51            xValues: data1.xValues,
52            yValues: data1.yValues,
53            dataSeriesName: "First Line Series",
54        }),
55        strokeThickness: 3,
56        stroke: appTheme.VividSkyBlue,
57        pointMarker: new EllipsePointMarker(wasmContext, {
58            width: 7,
59            height: 7,
60            strokeThickness: 0,
61            fill: appTheme.VividSkyBlue,
62        }),
63    });
64    sciChartSurface.renderableSeries.add(lineSeries0);
65
66    const data2 = ExampleDataProvider.getFourierSeriesZoomed(0.5, 0.12, 5.0, 5.15);
67    const lineSeries1 = new FastLineRenderableSeries(wasmContext, {
68        dataSeries: new XyDataSeries(wasmContext, {
69            xValues: data2.xValues,
70            yValues: data2.yValues,
71            dataSeriesName: "Second Line Series",
72        }),
73        strokeThickness: 3,
74        stroke: appTheme.VividOrange,
75        pointMarker: new EllipsePointMarker(wasmContext, {
76            width: 7,
77            height: 7,
78            strokeThickness: 0,
79            fill: appTheme.VividOrange,
80        }),
81    });
82    sciChartSurface.renderableSeries.add(lineSeries1);
83
84    const data3 = ExampleDataProvider.getFourierSeriesZoomed(0.4, 0.11, 5.0, 5.15);
85    const lineSeries2 = new FastLineRenderableSeries(wasmContext, {
86        dataSeries: new XyDataSeries(wasmContext, {
87            xValues: data3.xValues,
88            yValues: data3.yValues,
89            dataSeriesName: "Third Line Series",
90        }),
91        strokeThickness: 3,
92        stroke: appTheme.MutedPink,
93        pointMarker: new EllipsePointMarker(wasmContext, {
94            width: 7,
95            height: 7,
96            strokeThickness: 0,
97            fill: appTheme.MutedPink,
98        }),
99    });
100    sciChartSurface.renderableSeries.add(lineSeries2);
101
102    // Here is where we add rollover tooltip behaviour
103    //
104    const vSlice1 = new VerticalSliceModifier({
105        x1: 5.06,
106        xCoordinateMode: ECoordinateMode.DataValue,
107        isDraggable: true,
108        // Defines if rollover vertical line is shown
109        showRolloverLine: true,
110        rolloverLineStrokeThickness: 1,
111        rolloverLineStroke: appTheme.VividGreen,
112        lineSelectionColor: appTheme.VividGreen,
113        // Shows the default tooltip
114        showTooltip: true,
115        // Optional: Overrides the legend template to display additional info top-left of the chart
116        tooltipLegendTemplate: getTooltipLegendTemplate,
117        // Optional: Overrides the content of the tooltip
118        tooltipDataTemplate: getTooltipDataTemplate,
119    });
120    const vSlice2 = new VerticalSliceModifier({
121        x1: 0.75,
122        xCoordinateMode: ECoordinateMode.Relative,
123        isDraggable: true,
124        // Defines if rollover vertical line is shown
125        showRolloverLine: true,
126        rolloverLineStrokeThickness: 1,
127        rolloverLineStroke: appTheme.VividOrange,
128        lineSelectionColor: appTheme.VividOrange,
129        // Shows the default tooltip
130        showTooltip: true,
131        // Optional: Overrides the content of the tooltip
132        tooltipDataTemplate: getTooltipDataTemplate,
133    });
134    sciChartSurface.chartModifiers.add(vSlice1, vSlice2);
135
136    // Optional: Additional customisation may be done per-series, e.g.
137    //
138    lineSeries0.rolloverModifierProps.tooltipTextColor = appTheme.DarkIndigo;
139    lineSeries2.rolloverModifierProps.tooltipColor = appTheme.VividPink;
140
141    const textAnn1 = new NativeTextAnnotation({
142        text: "xCoordinateMode: DataValue\nMoves with data\nLinked to Legend\nDraggable",
143        textColor: appTheme.ForegroundColor,
144        y1: 0.88,
145        xCoordinateMode: ECoordinateMode.Pixel,
146        yCoordinateMode: ECoordinateMode.Relative,
147        horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
148    });
149    // Link the annotation position with the verticalSlice
150    sciChartSurface.layoutMeasured.subscribe((data) => {
151        textAnn1.x1 = vSlice1.verticalLine.x1;
152    });
153    sciChartSurface.annotations.add(textAnn1);
154
155    const textAnn2 = new NativeTextAnnotation({
156        text: "xCoordinateMode: Relative\nFixed position\nDraggable ",
157        textColor: appTheme.ForegroundColor,
158        y1: 0.88,
159        xCoordinateMode: ECoordinateMode.Pixel,
160        yCoordinateMode: ECoordinateMode.Relative,
161        horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
162    });
163    sciChartSurface.layoutMeasured.subscribe((data) => {
164        textAnn2.x1 = vSlice2.verticalLine.x1;
165    });
166    sciChartSurface.annotations.add(textAnn2);
167
168    // Add further zooming and panning behaviours
169    sciChartSurface.chartModifiers.add(new ZoomPanModifier({ enableZoom: true }));
170    sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
171    sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
172
173    sciChartSurface.zoomExtents();
174    return { sciChartSurface, wasmContext };
175};
176
177const getTooltipDataTemplate = (
178    seriesInfo: SeriesInfo,
179    tooltipTitle: string,
180    tooltipLabelX: string,
181    tooltipLabelY: string
182) => {
183    // Lines here are returned to the tooltip and displayed as text-line per tooltip
184    const lines: string[] = [];
185    lines.push(tooltipTitle);
186    lines.push(`x: ${seriesInfo.formattedXValue}`);
187    lines.push(`y: ${seriesInfo.formattedYValue}`);
188    return lines;
189};
190
191// Override the standard tooltip displayed by CursorModifier
192const getTooltipLegendTemplate = (seriesInfos: SeriesInfo[], svgAnnotation: RolloverLegendSvgAnnotation) => {
193    let outputSvgString = "";
194
195    // Foreach series there will be a seriesInfo supplied by SciChart. This contains info about the series under the house
196    seriesInfos.forEach((seriesInfo, index) => {
197        if (seriesInfo.isWithinDataBounds) {
198            const lineHeight = 30;
199            const y = 50 + index * lineHeight;
200            // Use the series stroke for legend text colour
201            const textColor = seriesInfo.stroke;
202            // Use the seriesInfo formattedX/YValue for text on the
203            outputSvgString += `<text x="8" y="${y}" font-size="16" font-family="Verdana" fill="${textColor}">
204                                    ${seriesInfo.seriesName}: X=${seriesInfo.formattedXValue}, Y=${seriesInfo.formattedYValue}
205                                </text>`;
206        }
207    });
208
209    // Content here is returned for the custom legend placed in top-left of the chart
210    return `<svg width="100%" height="100%">
211                <text x="8" y="20" font-size="15" font-family="Verdana" fill="lightblue">Custom Rollover Legend</text>
212                ${outputSvgString}
213            </svg>`;
214};
215

Using Vertical Slice Modifier - Angular

Overview

This Angular example demonstrates how to integrate SciChart.js into an Angular application using the ScichartAngularComponent. The purpose of the example is to showcase how to add draggable vertical slices to a high-performance chart, enabling tooltips at fixed positions and dynamic annotation updates.

Technical Implementation

The example leverages Angular’s property binding to pass an asynchronous chart initialization function (drawExample) to the ScichartAngularComponent. The drawExample function creates a SciChartSurface with asynchronously loaded WebAssembly content using SciChartSurface.create(), as described in the SciChartSurface.create documentation. Axes are configured using NumericAxis with specific label format settings and precision to ensure clear data presentation. Multiple line series are added with the FastLineRenderableSeries, each utilizing custom point markers. The key feature, the VerticalSliceModifier, is applied in two configurations: one using data-bound coordinates (ECoordinateMode.DataValue) and another using relative coordinates. This modifier not only displays a rollover line but also implements custom tooltips using callback functions, aligning with the concepts detailed in the SciChart.js VerticalSliceModifier Documentation. Additionally, Angular’s asynchronous operations are smoothly integrated with WebAssembly-based chart rendering and event handling.

Features and Capabilities

The example highlights several advanced features:

  • Real-time Updates: The chart uses preRender event subscriptions to dynamically update annotation positions linked to the draggable vertical slices, in line with principles found in The Annotations API Overview.
  • Custom Tooltips and Legends: Custom callback functions format tooltip text and legends, displaying precise data values for each data series.
  • Interactive Modifiers: Additional modifiers like ZoomPanModifier, ZoomExtentsModifier, and MouseWheelZoomModifier enhance the interactivity, allowing users to pan, zoom, and explore the data effectively.

Integration and Best Practices

The integration process encapsulates the initialization logic within a standalone Angular component using scichart-angular which simplifies the process of embedding a SciChart.js chart within an Angular application. This example demonstrates best practices in managing asynchronous operations, dynamic event handling, and resource cleanup in Angular. For a deeper understanding of Angular component binding and lifecycle management, developers can refer to relevant articles on integrating asynchronous data with Angular components, such as the How to use property binding with asynchronous data? discussion. Moreover, performance optimization techniques for WebGL charts are inherent in the use of FastLineRenderableSeries and efficient rendering, aligning with the best practices outlined in the Performance Optimisation of JavaScript Applications & Charts guide.

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