Search Results for

    Show / Hide Table of Contents

    SciChart Android Tutorial - Annotations

    In the prior tutorials we have familiarized with a great and powerful SciChart functionality. In this one we are going to lean about another powerful SciChart API - Annotations API which allows placing different elements to the Chart.

    Annotation available out of the box in SciChart are listed below:

    • BoxAnnotation
    • LineAnnotation
    • LineArrowAnnotation
    • HorizontalLineAnnotation
    • VerticalLineAnnotation
    • TextAnnotation
    • AxisLabelAnnotation
    • AxisMarkerAnnotation
    • CustomAnnotation

    Getting Started

    This tutorial is suitable for Java and Kotlin.

    Note

    Source code for this tutorial can be found at our Github Repository: Java and Kotlin Tutorials Repository

    In this tutorial, we are going to build on top of the FIFO scrolling chart that was implemented in the previous Adding Realtime Updates tutorial.

    Please make corresponding amendments to your code if required.

    Adding Annotations to the Chart

    Lets add a kind of news bulletin markers to the chart, one per 100 data points. To achieve this, we are going to modify our updateData handler. We want to create a TextAnnotation with some text and background and add it to the annotations collection.

    See the modified code below:

    • Java
    • Java with Builders API
    • Kotlin
    • Xamarin.Android
    private final Runnable updateData = () -> {
        Integer x = count;
        UpdateSuspender.using(surface, () -> {
            lineDataSeries.append(x, Math.sin(x* 0.1));
            scatterDataSeries.append(x, Math.cos(x * 0.1));
    
            tryAddAnnotationAt(x);
    
            // zoom series to fit viewport size into X-Axis direction
            surface.zoomExtentsX();
            count += 1;
        });
    };
    
    private void tryAddAnnotationAt(int x) {
        // add label every 100 data points
        if (x % 100 == 0) {
            final TextAnnotation label = new TextAnnotation(this);
            label.setText("N");
            label.setX1(x);
            label.setY1(0);
            label.setHorizontalAnchorPoint(HorizontalAnchorPoint.Center);
            label.setVerticalAnchorPoint(VerticalAnchorPoint.Center);
            label.setFontStyle(new FontStyle(30f, Color.WHITE));
    
            // add label into annotation collection
            surface.getAnnotations().add(label);
    
            // if we add annotation and x > fifoCapacity
            // then we need to remove annotation which goes out of the screen
            if (x > fifoCapacity) {
                surface.getAnnotations().remove(0);
            }
        }
    }
    
    private final Runnable updateData = () -> {
        Integer x = count;
        UpdateSuspender.using(surface, () -> {
            lineDataSeries.append(x, Math.sin(x* 0.1));
            scatterDataSeries.append(x, Math.cos(x * 0.1));
    
            tryAddAnnotationAt(x);
    
            // zoom series to fit viewport size into X-Axis direction
            surface.zoomExtentsX();
            count += 1;
        });
    };
    
    private void tryAddAnnotationAt(int x) {
        // add label every 100 data points
        if (x % 100 == 0) {
            final TextAnnotation label = sciChartBuilder.newTextAnnotation()
                    .withText("N")
                    .withX1(x)
                    .withY1(0)
                    .withHorizontalAnchorPoint(HorizontalAnchorPoint.Center)
                    .withVerticalAnchorPoint(VerticalAnchorPoint.Center)
                    .withFontStyle(30f, Color.WHITE)
                    .build();
    
            // add label into annotation collection
            surface.getAnnotations().add(label);
    
            // if we add annotation and x > fifoCapacity
            // then we need to remove annotation which goes out of the screen
            if (x > fifoCapacity) {
                surface.getAnnotations().remove(0);
            }
        }
    }
    
    private val updateData = Runnable {
        val x = count
        UpdateSuspender.using(surface) {
            lineDataSeries.append(x, sin(x* 0.1))
            scatterDataSeries.append(x, cos(x * 0.1))
    
            tryAddAnnotationAt(x)
    
            // zoom series to fit viewport size into X-Axis direction
            surface.zoomExtentsX()
            count += 1
        }
    }
    
    private fun tryAddAnnotationAt(x: Int) {
        // add label every 100 data points
        if (x % 100 == 0) {
            val label = TextAnnotation(this)
            label.text = "N"
            label.x1 = x
            label.y1 = 0
            label.horizontalAnchorPoint = HorizontalAnchorPoint.Center
            label.verticalAnchorPoint = VerticalAnchorPoint.Center
            label.fontStyle = FontStyle(30f, Color.WHITE)
    
            // add label into annotation collection
            surface.annotations.add(label)
    
            // if we add annotation and x > fifoCapacity
            // then we need to remove annotation which goes out of the screen
            if (x > fifoCapacity) {
                surface.annotations.removeAt(0)
            }
        }
    }
    
    private void OnTick(object sender, ElapsedEventArgs e)
    {
        lock (_syncRoot)
        {
            var x = count;
            using (surface.SuspendUpdates())
            {
                lineDataSeries.Append(x, Math.Sin(x * 0.1));
                scatterDataSeries.Append(x, Math.Cos(x * 0.1));
    
                TryAddAnnotationAt(x);
    
                count += 1;
                surface.ZoomExtentsX();
            }
        }
    }
    
    private void TryAddAnnotationAt(int x)
    {
        if (x % 100 == 0)
        {
            var label = new TextAnnotation(this)
            {
                Text = "N",
                X1Value = x,
                Y1Value = 0,
                HorizontalAnchorPoint = HorizontalAnchorPoint.Center,
                VerticalAnchorPoint = VerticalAnchorPoint.Center,
                FontStyle = new FontStyle(30f, 0xFFFFFFFF)
            };
    
            // add label into annotation collection
            surface.Annotations.Add(label);
    
            // if we add annotation and x > fifoCapacity
            // then we need to remove annotation which goes out of the screen
            if (x > FifoCapacity)
            {
                surface.Annotations.RemoveAt(0);
            }
        }
    }
    
    Note

    After appending new data we call zoomExtents to make series to fit the viewport.

    Which will result in the following:

    Where to Go From Here?

    You can download the final project from our Java and Kotlin Tutorials Repository.

    Also, you can found next tutorial from this series here - SciChart Android Tutorial - Multiple Axis

    Of course, this is not the limit of what you can achieve with the SciChart Android. You might want to read the article about annotations:

    • Annotations API

    as well as some other general articles listed below:

    • Axis Types
    • 2D Chart Types
    • Chart Modifiers

    Finally, start exploring. The SciChart Android library and functionality is quite extensive. You can look into our SciChart Android Examples Suite which are full of 2D and 3D examples, which are also available on our GitHub

    Back to top © 2011-2025 SciChart. All rights reserved. | sitemap.xml