How to: Add Annotations to a Chart

This how-to guide will show you how to add various types of annotations to your chart.

NOTE: Annotations are a premium charts feature.

In order to add annotations to your chart you need to do the following:

  1. Retrieve the AnnotationsManager from the ShinobiChart
  2. Use one of the add methods on the AnnotationsManager to create and add an annotation to the chart

Annotations provide a means of adding visual cues to a chart. These may take the form of shapes, markers, text or other visual elements and are displayed in the plot area either above or below the data.

In the Annotations sample project, a line series is plotted showing the closing stock price of Google Inc. over the period 2010 - 2014. The loadStockPriceData method reads this data in from a .csv file held in the res/raw folder. Without going into the implementation details, the main points are that this method returns a list of data points (that is, objects that implement the Data interface) and so can be passed into the line series’ data adapter, and that as it loads the data it stores the data points for specific Android™ releases in a HashMap for later use.

Adding Text Annotations

So, now we’ve got all this information, lets add some textual labels to identify each Android release on the chart. In the addReleaseTextAnnotations method the first thing we do is retrieve the AnnotationsManager from the ShinobiChart:

Java

AnnotationsManager annotationsManager = shinobiChart.getAnnotationsManager();

C#

AnnotationsManager annotationsManager = shinobiChart.AnnotationsManager;

Then we iterate through each Entry in the releaseInfo map, pulling out the required data and creating an equivalent text annotation; this is done by simply calling the addTextAnnotation method:

Java

for (Entry<String, Data<Date, Double>> entry : releaseInfo.entrySet()) {

    String releaseName = entry.getKey();
    Date releaseDate = entry.getValue().getX();
    Double closingPrice = entry.getValue().getY();

    annotationsManager.addTextAnnotation(
            releaseName, releaseDate, closingPrice, shinobiChart.getXAxis(), shinobiChart.getYAxis());
    }
}

C#

foreach (KeyValuePair<string, IData> entry in releaseInfo) {

    string releaseName = entry.Key;
    Date releaseDate = (Date) entry.Value.GetX();
    double closingPrice = (double) entry.Value.GetY();

    annotationsManager.AddTextAnnotation(releaseName, releaseDate, closingPrice, shinobiChart.XAxis, shinobiChart.YAxis);
}

Our chart now has a set of textual labels containing the name of each Android release, positioned at the relevant date and stock price on top of the line series.

Text Annotations

Adding a Line Annotation

Annotations are not limited to just being text labels. Often, it is useful to highlight certain areas of your data: line, band and box annotations all can help with this.

Lets add a horizontal line annotation on to our chart to highlight the stock price crossing the $1000 mark. We want it to be fairly subtle so we’ll set its thickness to 2dp. If you’re following in the code sample, the below code is in the addThousandDollarLineAnnotation method.

Java

Annotation thousandLine = annotationsManager.addHorizontalLineAnnotation(
        1000, 2.0f, shinobiChart.getXAxis(), shinobiChart.getYAxis());

C#

Annotation thousandLine = annotationsManager.AddHorizontalLineAnnotation(
        1000, 2.0f, shinobiChart.XAxis, shinobiChart.YAxis);

An interesting thing to note here is that we center the annotation around ‘1000’ on the Y axis (rather than ‘1000.0’). The method accepts any Object, however, it must be of a type that is compatible with the Y axis. As our Y axis is a NumberAxis we can pass in any subclass of Number; even though the NumberAxis works with Doubles, an Integer here will be perfectly fine. If we were to pass in an incompatible type a ClassCastException would be thrown at runtime.

Positioning and Styling an Annotation

You may have noticed in the code snippet above we kept hold of a reference to the line annotation; all of the add methods on the AnnotationsManager return the annotation they create. This allows the annotation to be subsequently customized in a number of ways.

Firstly, we want this annotation to be displayed behind the line series, not in front of it. This is simply achieved by calling the setPosition method on the annotation with one of the values in the Annotation.Position enum.

Next we want to change the color of the line so that it is a faint, translucent green. As with the other visual elements on a ShinobiChart, each annotation has its own style object which controls its visual appearance. The only property relevant to a line annotation is the background color so we set it as follows:

Java

thousandLine.getStyle().setBackgroundColor(Color.argb(20, 0, 255, 0));
shinobiChart.redrawChart();

C#

thousandLine.Style.BackgroundColor = Color.Argb(20, 0, 255, 0);
shinobiChart.RedrawChart();

Remember to call redrawChart in order for the style change to take effect.

Line Annotation

Advanced Custom Annotations

For our final annotation, let’s add the Android logo to chart behind the line series. Instead of it being a set width and height though, we’re going to make it span a range on the X and on the Y axis so that it grows and shrinks as the user pans and zooms.

Firstly, we create an ImageView to hold the logo image file (which is in the res/drawable folder). We also give the ImageView a LayoutParams object with its width and height set to 0. By doing this, the annotation will know to span the X axis and Y axis ranges that we’ll set on it in a moment. In the code sample, the relevant method is addAndroidLogoAnnotation.

Java

ImageView androidLogo = new ImageView(this);
androidLogo.setImageResource(R.drawable.android_robot);
androidLogo.setScaleType(ImageView.ScaleType.FIT_XY);
androidLogo.setLayoutParams(new LayoutParams(0, 0));

C#

ImageView androidLogo = new ImageView(this);
androidLogo.SetImageResource(Resource.Drawable.android_robot);
androidLogo.SetScaleType(ImageView.ScaleType.FitXy);
androidLogo.LayoutParameters = new ViewGroup.LayoutParams (0, 0);

We now have the view we want the annotation to use so we can go ahead and create the annotation:

Java

Annotation logoAnnotation = annotationsManager.addViewAnnotation(
        androidLogo, null, null, shinobiChart.getXAxis(), shinobiChart.getYAxis());

C#

Annotation logoAnnotation = annotationsManager.AddViewAnnotation(
        androidLogo, null, null, shinobiChart.XAxis, shinobiChart.YAxis);

Notice that the X and Y values are set to null. Usually, when creating a custom view annotation you will want to place it at a specific location on the plot area. As we’ll be using ranges the X and Y values are irrelevant hence passing in null.

All that’s left to do is position the annotation behind the data and set the X and Y ranges on it:

Java

logoAnnotation.setPosition(Annotation.Position.BEHIND_DATA);

calendar.set(2011, Calendar.JULY, 1);
Date min = calendar.getTime();
calendar.set(2012, Calendar.JULY, 1);
Date max = calendar.getTime();

logoAnnotation.setXRange(new DateRange(min, max));

logoAnnotation.setYRange(new NumberRange(300.0, 900.0));

C#

logoAnnotation.AnnotationPosition = Annotation.Position.BehindData;

logoAnnotation.XRange = new DateRange(new DateTime(2011, 7, 1), new DateTime(2012, 7, 1));

logoAnnotation.YRange = new NumberRange(300.0, 900.0);

And here it is, our chart with all its annotations!

Custom view Annotation

See related code sample: Annotations Sample, in the samples/annotations folder of your product download (Xamarin.Android/samples/Annotations if you’re using Xamarin.Android).

Android is a trademark of Google Inc. The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.