Angular Chart Annotations

Demonstrates how to add Annotations (shapes, boxes, lines, text) to a Angular Chart using SciChart.js, High Performance JavaScript Charts

Fullscreen

Edit

 Edit

Docs

drawExample.ts

angular.ts

theme.ts

416398_exploration_fuel_nasa_rocket_space_icon.ts

Copy to clipboard
Minimise
Fullscreen
1import { appTheme } from "../../../theme";
2// import CustomImage from "./scichart-logo-white.png";
3import { rocketSvg } from "./416398_exploration_fuel_nasa_rocket_space_icon";
4import {
5    SciChartSurface,
6    NumericAxis,
7    NumberRange,
8    ZoomPanModifier,
9    LineAnnotation,
10    BoxAnnotation,
11    CustomAnnotation,
12    TextAnnotation,
13    EHorizontalAnchorPoint,
14    EVerticalAnchorPoint,
15    ECoordinateMode,
16    EAnnotationLayer,
17    IAnnotation,
18    HorizontalLineAnnotation,
19    ELabelPlacement,
20    VerticalLineAnnotation,
21    GenericAnimation,
22    EWrapTo,
23    NativeTextAnnotation,
24} from "scichart";
25
26export const drawExample = (CustomImage: string) => async (rootElement: string | HTMLDivElement) => {
27    // Create a SciChartSurface
28    const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
29        theme: appTheme.SciChartJsTheme,
30    });
31
32    // Create an XAxis and YAxis
33    const xAxis = new NumericAxis(wasmContext);
34    xAxis.visibleRange = new NumberRange(0, 10);
35    sciChartSurface.xAxes.add(xAxis);
36
37    const yAxis = new NumericAxis(wasmContext);
38    yAxis.visibleRange = new NumberRange(0, 10);
39    sciChartSurface.yAxes.add(yAxis);
40
41    // Optional: Add some interactivity modifiers
42    sciChartSurface.chartModifiers.add(new ZoomPanModifier({ enableZoom: true }));
43
44    const textColor = appTheme.ForegroundColor;
45    const stroke = appTheme.VividSkyBlue;
46    const strokeDashArray = [3, 3];
47
48    // Add TextAnnotations in the top left of the chart
49    //
50    const text1 = new TextAnnotation({
51        text: "Chart Annotations are Powerful!",
52        fontSize: 24,
53        x1: 0.3,
54        y1: 9.7,
55        textColor,
56    });
57    const text2 = new TextAnnotation({ text: "You can create text", fontSize: 18, x1: 2, y1: 9, textColor });
58
59    const nativeText = new NativeTextAnnotation({
60        text: "New! NativeText supports multi line with automatic wrapping, and rotation",
61        fontSize: 18,
62        x1: 7,
63        x2: 10,
64        y1: 9,
65        textColor,
66        wrapTo: EWrapTo.Annotation,
67    });
68
69    // Add Dashed line and anchor text center/right/left annotations
70    //
71    const lineDash = new LineAnnotation({ x1: 5, x2: 5, y1: 8.5, y2: 7, stroke, strokeDashArray });
72    const textAlignCenter = new TextAnnotation({
73        text: "Anchor Text Centered",
74        x1: 5,
75        y1: 8,
76        textColor,
77        horizontalAnchorPoint: EHorizontalAnchorPoint.Center, // anchorpoints control where the X,Y coord is located
78        verticalAnchorPoint: EVerticalAnchorPoint.Bottom,
79    });
80    const textAlignRight = new TextAnnotation({
81        text: "Anchor Text Right",
82        x1: 5,
83        y1: 7.8,
84        textColor,
85        horizontalAnchorPoint: EHorizontalAnchorPoint.Right,
86        verticalAnchorPoint: EVerticalAnchorPoint.Top,
87    });
88    const textAlignLeft = new TextAnnotation({
89        text: "or Anchor Text Left",
90        x1: 5,
91        y1: 7.5,
92        textColor,
93        horizontalAnchorPoint: EHorizontalAnchorPoint.Left,
94        verticalAnchorPoint: EVerticalAnchorPoint.Top,
95    });
96
97    // Watermark with CoordinateMode Relative
98    //
99    const textWatermark = new TextAnnotation({
100        text: "Create Centered Watermarks",
101        x1: 0.5,
102        y1: 0.5,
103        textColor,
104        opacity: 0.3,
105        horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
106        verticalAnchorPoint: EVerticalAnchorPoint.Center,
107        fontSize: 48,
108        fontWeight: "Bold",
109        xCoordinateMode: ECoordinateMode.Relative, // xCoordinateMode relative allows 0..1 to correspond to viewport left/right
110        yCoordinateMode: ECoordinateMode.Relative, // yCoordinateMode relative allows 0..1 to correspond to viewport top/bottom
111    });
112
113    // Lines
114    //
115    const textLines = new TextAnnotation({ fontSize: 13, text: "You can draw lines", x1: 0.3, y1: 6.3, textColor });
116    const line1 = new LineAnnotation({ stroke, strokeThickness: 2, x1: 1, x2: 2, y1: 4, y2: 6 });
117    const line2 = new LineAnnotation({ stroke, strokeThickness: 2, x1: 1.2, x2: 2.5, y1: 3.8, y2: 6 });
118
119    // Boxes
120    //
121    const textBoxes = new TextAnnotation({ fontSize: 13, text: "Draw Boxes with/without alignment", x1: 3.3, y1: 6.3 });
122
123    const box1 = new BoxAnnotation({
124        fill: appTheme.VividGreen + "33",
125        stroke: appTheme.VividGreen,
126        strokeThickness: 1,
127        x1: 3.5,
128        x2: 5,
129        y1: 3.9,
130        y2: 4.9,
131    });
132    const box2 = new BoxAnnotation({
133        fill: appTheme.VividSkyBlue + "33",
134        strokeThickness: 0,
135        x1: 0,
136        x2: 1,
137        y1: 4.4,
138        y2: 5.4,
139        xCoordinateMode: ECoordinateMode.Relative, // xCoordinateMode relative allows stretching a box horizontally to fit viewport
140    });
141    const box3 = new BoxAnnotation({
142        fill: appTheme.VividPink + "33",
143        stroke: appTheme.VividPink,
144        strokeThickness: 1,
145        x1: 4,
146        x2: 5.5,
147        y1: 5,
148        y2: 6,
149    });
150
151    // Custom shapes (Buy Sell arrow markers)
152    //
153    const textCustomShapes = new TextAnnotation({ fontSize: 13, text: "Or custom shapes using SVG", x1: 7, y1: 6.3 });
154    const customAnnotationBuyMarker = getBuyMarkerAnnotation(8, 6);
155    const customAnnotationSellMarker = getSellMarkerAnnotation(7.5, 5.5);
156
157    // Images and Vectors (Icons) SVG
158    //
159    const textImage = new TextAnnotation({
160        x1: 0.3,
161        y1: 3,
162        text: "Add images",
163        textColor,
164        verticalAnchorPoint: EVerticalAnchorPoint.Bottom,
165    });
166    const image = getImageAnnotation(0.3, 2.8, CustomImage, 241, 62);
167
168    // Vectors (SVG)
169    const testCustomSvg = new TextAnnotation({
170        x1: 3.3,
171        y1: 3,
172        text: "Add Vectors and Icons (SVG)",
173        textColor,
174        verticalAnchorPoint: EVerticalAnchorPoint.Bottom,
175    });
176    const customSvgAnnotation = new CustomAnnotation({ x1: 4.5, y1: 2.8, svgString: rocketSvg });
177
178    // Vertical or Horizontal lines with axis Label
179    //
180    const textVerticalLine = new TextAnnotation({
181        x1: 6.7,
182        y1: 3,
183        text: "Add Vertical/Horizontal Thresholds",
184        textColor,
185        verticalAnchorPoint: EVerticalAnchorPoint.Bottom,
186    });
187    const horizontalLineStretched = new HorizontalLineAnnotation({
188        labelPlacement: ELabelPlacement.Axis,
189        showLabel: true,
190        stroke,
191        strokeThickness: 3,
192        axisLabelFill: stroke,
193        axisLabelStroke: appTheme.ForegroundColor,
194        y1: 1, // The Y-value of the HorizontalLineAnnotation
195    });
196
197    const verticalLineStretched = new VerticalLineAnnotation({
198        labelPlacement: ELabelPlacement.Axis,
199        showLabel: true,
200        stroke,
201        strokeThickness: 3,
202        x1: 9, // Tye x-value of the VerticalLineAnnotation
203        axisLabelFill: stroke,
204        axisLabelStroke: appTheme.ForegroundColor,
205    });
206
207    // // Axis Markers
208    // const axisMarker = new AxisMarkerAnnotation({
209    //     y1: 5.2,
210    //     fontSize: 13,
211    //     fontStyle: "Bold"
212    // });
213
214    const allAnnotations = [
215        text1,
216        text2,
217        nativeText,
218        lineDash,
219        textAlignLeft,
220        textAlignRight,
221        textAlignCenter,
222        textCustomShapes,
223        textWatermark,
224        textLines,
225        line1,
226        line2,
227        textBoxes,
228        box1,
229        box2,
230        box3,
231        textImage,
232        image,
233        testCustomSvg,
234        customSvgAnnotation,
235        textVerticalLine,
236        verticalLineStretched,
237        horizontalLineStretched,
238        customAnnotationBuyMarker,
239        customAnnotationSellMarker,
240        // customAnnotationSvg
241    ];
242
243    // Add all the annotations to the chart
244    sciChartSurface.annotations.add(...allAnnotations);
245
246    // Just for fun, let's animate some animations using Scichart's GenericAnimation feature
247    const duration = 1000;
248    const delay = 800;
249    sciChartSurface.addAnimation(
250        addTypewriterEffect(duration, 0, text1),
251        addTypewriterEffect(duration, delay, text2),
252        addFadeEffect(duration, delay * 2, lineDash, textAlignCenter, textAlignLeft, textAlignRight),
253        addTypewriterEffect(duration, delay * 3, textAlignCenter),
254        addTypewriterEffect(duration, delay * 4, textAlignLeft),
255        addTypewriterEffect(duration, delay * 5, textAlignRight),
256        addTypewriterEffect(duration, delay * 2, nativeText),
257        addRotateEffect(duration, delay * 4, nativeText),
258        addFadeEffect(duration, delay * 6, textWatermark),
259        addFadeEffect(duration, delay * 7, textLines, line1, line2),
260        addFadeEffect(duration, delay * 8, textBoxes, box1, box2, box3),
261        addFadeEffect(duration, delay * 9, textCustomShapes, customAnnotationBuyMarker, customAnnotationSellMarker),
262        addFadeEffect(duration, delay * 10, textImage, image),
263        addFadeEffect(duration, delay * 11, testCustomSvg, customSvgAnnotation),
264        addTypewriterEffect(duration, delay * 12, textVerticalLine),
265        addFadeEffect(duration, delay * 12, textVerticalLine, verticalLineStretched, horizontalLineStretched)
266    );
267
268    return { sciChartSurface, wasmContext };
269};
270
271const addFadeEffect = (duration: number, delay: number, ...annotations: IAnnotation[]) => {
272    return new GenericAnimation<number>({
273        from: 0,
274        to: annotations[0].opacity,
275        onAnimate: (from: number, to: number, progress: number) => {
276            annotations.forEach((a) => (a.opacity = to * progress));
277        },
278        duration,
279        delay,
280        setInitialValueImmediately: true,
281    });
282};
283
284const addTypewriterEffect = (duration: number, delay: number, textAnnotation: { text: string }) => {
285    return new GenericAnimation<string>({
286        from: "",
287        to: textAnnotation.text,
288        onAnimate: (from: string, to: string, progress: number) => {
289            const length = Math.floor(to.length * progress);
290            textAnnotation.text = to.substring(0, length);
291        },
292        duration,
293        delay,
294        setInitialValueImmediately: true,
295    });
296};
297
298const addRotateEffect = (duration: number, delay: number, textAnnotation: NativeTextAnnotation) => {
299    return new GenericAnimation<number>({
300        from: 0,
301        to: 30,
302        onAnimate: (from: number, to: number, progress: number) => {
303            const angle = to * progress;
304            textAnnotation.rotation = angle;
305        },
306        duration,
307        delay,
308    });
309};
310
311const getBuyMarkerAnnotationSvgString = `<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg">
312        <g transform="translate(-53.867218,-75.091687)">
313            <path style="fill:#1cb61c;fill-opacity:0.34117647;stroke:#00b400;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
314                d="m 55.47431,83.481251 c 7.158904,-7.408333 7.158904,-7.408333 7.158904,-7.408333 l 7.158906,7.408333 H 66.212668 V 94.593756 H 59.053761 V 83.481251 Z"/>
315        </g>
316    </svg>`;
317
318// Returns a CustomAnnotation that represents a buy marker arrow
319// The CustomAnnotation supports SVG as content. Using Inkscape or similar you can create SVG content for annotations
320const getBuyMarkerAnnotation = (x1: number, y1: number): CustomAnnotation => {
321    return new CustomAnnotation({
322        x1,
323        y1,
324        verticalAnchorPoint: EVerticalAnchorPoint.Top,
325        horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
326        svgString: getBuyMarkerAnnotationSvgString,
327    });
328};
329
330const getSellMarkerAnnotationSvgString = `
331    <svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" >
332        <g transform="translate(-54.616083,-75.548914)">
333            <path style="fill:${appTheme.VividRed};fill-opacity:0.33;stroke:${appTheme.VividRed};stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
334                  d="m 55.47431,87.025547 c 7.158904,7.408333,7.158904,7.408333 7.158904,7.408333 L 69.79212, 87.025547 H 66.212668 V 75.913042 h -7.158907 v 11.112505 z"
335            />
336        </g>
337    </svg>`;
338
339const getImageAnnotation = (x1: number, y1: number, image: any, width: number, height: number): CustomAnnotation => {
340    return new CustomAnnotation({
341        x1,
342        y1,
343        verticalAnchorPoint: EVerticalAnchorPoint.Top,
344        horizontalAnchorPoint: EHorizontalAnchorPoint.Left,
345        svgString: `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg" style="background-color:transparent">
346                        <image href="${image}" height="${height}" width="${width}"/>
347                    </svg>`,
348    });
349};
350
351// Returns a CustomAnnotation that represents a sell marker arrow
352// The CustomAnnotation supports SVG as content. Using Inkscape or similar you can create SVG content for annotations
353const getSellMarkerAnnotation = (x1: number, y1: number): CustomAnnotation => {
354    return new CustomAnnotation({
355        x1,
356        y1,
357        verticalAnchorPoint: EVerticalAnchorPoint.Bottom,
358        horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
359        svgString: getSellMarkerAnnotationSvgString,
360    });
361};
362

See Also: Chart Annotations (6 Demos)

Coloring Series per-point using the PaletteProvider | SciChart.js Demo

Coloring Series per-point using the PaletteProvider

Demonstrates per-point coloring in JavaScript chart types with SciChart.js PaletteProvider API

Angular Chart Hoverable Buy Sell Marker Annotations | SciChart.js Demo

Angular Chart Hoverable Buy Sell Marker Annotations

Demonstrates how to place Buy/Sell arrow markers on a Angular Stock Chart using SciChart.js - Annotations API

Angular Mountain Chart Draggable Thresholds | SciChart.js Demo

Angular Mountain Chart Draggable Thresholds

Demonstrates how to add draggable thresholds which change the series color in the chart in SciChart.js

Angular Chart Editable Annotations | SciChart.js Demo

Angular Chart Editable Annotations

Demonstrates how to edit Annotations (shapes, boxes, lines, text, horizontal and vertical line) over a Angular Chart using SciChart.js Annotations API

Angular Quadrant Chart using Background Annotations | SciChart.js Demo

Angular Quadrant Chart using Background Annotations

Demonstrates how to color areas of the chart surface using background Annotations using SciChart.js Annotations API

Angular Chart Annotation Layers | SciChart.js Demo

Angular Chart Annotation Layers

Demonstrates how layering works a Angular Chart using SciChart.js Annotations API

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