SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and iOS Chart & Android Chart Components

1.5 Only! The following article requires Annotations API feature in SciChart v1.5. A trial version can be downloaded now at www.scichart.com/downloads

Annotations are Easy!

Using the new Annotations API in SciChart v1.5, you can place any UIElement on the a SciChartSurface, either above or below the chart series in both WPF and Silverlight. In this tutorial we are going to create some annotations in Xaml, using the Visual Studio designer. So, without further ado, let’s get started!

Creating the Example

Let’s start by creating a new WPF Application and adding a UserControl called AnnotationsInXaml. Now add the following Xaml to it. Make sure you include the xaml namespaces!

<UserControl x:Class="Abt.Controls.SciChart.Example.Examples.IWantTo.AnnotateAChart.AnnotationsInXaml"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
             mc:Ignorable="d" 
             d:DesignHeight="600" d:DesignWidth="800">

    <Grid>

        <s:SciChartSurface x:Name="sciChart"
                           ClipModifierSurface="True"                           
                           s:ThemeManager.Theme="Chrome">

            <s:SciChartSurface.XAxis>
                <s:NumericAxis TextFormatting="0.0#">
                    <s:NumericAxis.VisibleRange>
                        <s:DoubleRange Min="0" Max="10"/>
                    </s:NumericAxis.VisibleRange>
                </s:NumericAxis>
            </s:SciChartSurface.XAxis>

            <s:SciChartSurface.YAxis>
                <s:NumericAxis TextFormatting="0.0#">
                    <s:NumericAxis.VisibleRange>
                        <s:DoubleRange Min="0" Max="10"/>
                    </s:NumericAxis.VisibleRange>
                </s:NumericAxis>
            </s:SciChartSurface.YAxis>

        </s:SciChartSurface>

    </Grid>

</UserControl>

Viewing your UserControl in the designer, you should see something like this. You’ll notice you can now see the chart window in the designer even without any data so long as you define a VisibleRange. Yes, that’s a v1.5 improvement!

Blank chart in the Designer

Your first Annotation

Now let’s start by adding some annotations. The first will be a TextAnnotation (why not?). Annotations are added inside the SciChartSurface.Annotations collection. Add the following Xaml inside the SciChartSurface tags:

<s:SciChartSurface.Annotations>                
	<s:TextAnnotation X1="0.5" Y1="9.5" Text="Annotations are Easy!" FontSize="24" />                               
</s:SciChartSurface.Annotations>

Take a look at the designer view. You should see this:

Your first annotation! Told you they were easy

Ok that’s great! So what’s going on here? The X1,Y1 properties are data-points. This means that if you create an annotation at X1=5, Y1=10 then it will be positioned at this data-point and will move with the data as you pan the chart.

TextAnnotation Anchor Points

Let’s take it up a notch. Create a few more text annotations and begin to experiment with the X1, Y1 properties and Anchor point properties:

<s:SciChartSurface.Annotations>                
    <s:TextAnnotation X1="0.3" Y1="9.7" Text="Annotations are Easy!" FontSize="24" />
    <s:TextAnnotation X1="1.0" Y1="9" Text="You can create text" FontSize="18" />

    <s:TextAnnotation X1="5.0" Y1="8.0" VerticalAnchorPoint="Bottom" HorizontalAnchorPoint="Center" Text="Anchor Center (X1, Y1)" />
    <s:TextAnnotation X1="5.0" Y1="8.0" VerticalAnchorPoint="Top" HorizontalAnchorPoint="Right" Text="Anchor Right"/>
    <s:TextAnnotation X1="5.0" Y1="8.0" VerticalAnchorPoint="Top" HorizontalAnchorPoint="Left" Text="or Anchor Left"/>
</s:SciChartSurface.Annotations>

Try playing around with the Anchor properties. The TextAnnotation is positioned using a single X1,Y1 coordinate. The default values of the anchor point properties are HorizontalAnchorPoint.Left and default VerticalAnchorPoint.Top. This means the top-left corner of the TextAnnotation is positioned at X1,Y1. You can set the HorizontalAnchorPoint.Left to Left, Center, Right and VerticalAnchorPoint to Top, Center, Right to change the positioning of the text around the coordinate.

Multiple positioned Text Annotations

How HorizontalAnchorPoint and VerticalAnchorPoint affect positioning

Creating a Watermark with Relative Positioning

So far all the annotations we have placed have used Absolute Positioning. In this mode, if the X1,Y1 coordinate of an annotation is set to 10,20 then the annotation will always be at the data-point 10,20. If you scroll or pan the chart, the annotation will pan too.

If you want to position an annotation at a certain area of the chart (e.g. Center) and you don’t want it to pan with the chart, then you can use Relative Positioning. A short example is found below. Notice we also set AnnotationCanvas=BelowChart to place the watermark text beneath the chart series.

<s:TextAnnotation CoordinateMode="Relative" AnnotationCanvas="BelowChart" FontSize="72" FontWeight="Bold"
                    Foreground="#22000000" Text="Watermark"
                    HorizontalAnchorPoint="Center" VerticalAnchorPoint="Center"
                    X1="0.5" Y1="0.5"/>

Creating a Watermark using CoordinateMode=Relative

When CoordinateMode.Relative is used, the X1,Y1 coordinates are relative to the bounds of the chart. So a value of X1=0.2 means 20% along the current X-Axis range. X1=0.5 means 50% etc…

Lines, Arrows and Boxes

Yes, there are other annotation types too! Now let’s create some lines and boxes. In the same example, add the following Xaml below your existing annotations:

<!-- Lines and LineArrow -->
<s:TextAnnotation X1="0.3" Y1="6.3" Text="Draw Lines with" FontSize="12"/>
<s:TextAnnotation X1="0.3" Y1="6.0" Text="or without arrows" FontSize="12"/>
<s:LineAnnotation X1="1" Y1="4" X2="2" Y2="6" StrokeThickness="2" Stroke="#555"/>
<s:LineArrowAnnotation X1="1.2" Y1="3.8" X2="2.5" Y2="6" StrokeThickness="2" Stroke="#555"/>

<!-- Boxes -->
<s:TextAnnotation X1="3.3" Y1="6.3" Text="Draw boxes" FontSize="12"/>
<s:BoxAnnotation X1="3.5" Y1="4" X2="5" Y2="5" BorderThickness="1" BorderBrush="#279B27" Background="#55279B27" CornerRadius="3"/>
<s:BoxAnnotation X1="4" Y1="4.5" X2="5.5" Y2="5.5" BorderThickness="1" BorderBrush="#FF1919" Background="#55FF1919" CornerRadius="3"/>
<s:BoxAnnotation X1="4.5" Y1="5" X2="6" Y2="6" BorderThickness="1" BorderBrush="#1964FF" Background="#551964FF" CornerRadius="3"/>

Ok that’s great, you should have something like this in your designer window by now. The same rules about Relative and Absolute positioning apply to lines and boxes too. However, because Line/LineArrow/Box has X1,Y1,X2,Y2 properties, there is no Anchor point. You can position the box or line accurately using the end-points.

Lines, LineArrow and Box Annotations

Creating Custom Shapes using PathAnnotation

I can hear you saying – that’s great, but I want to render a banana shape not the built in types. How do I do that? Ok, well one way is you can use the PathAnnotation. This is a very simple annotation that exposes the same properties as System.Windows.Shapes.Path. In the following example we can create buy/sell markers (Block Arrow) using a simple path geometry. The following example doesn’t render a banana I’m afraid but does show a buy & sell marker (which might actually be useful):

<!-- Custom Shapes using Path -->
<s:TextAnnotation X1="7" Y1="6.3" Text="Or Custom Shapes" FontSize="12"/>
<s:PathAnnotation X1="7.5" Y1="5" Fill="#57B22020" Stroke="#FF990000" StrokeThickness="1" Data="m 3.5 0.5 4 0 0 8 3 0 -5 5 -5 -5 3 0 z"/>
<s:PathAnnotation X1="8" Y1="5.5" Fill="#571CB61C" Stroke="#FF00B400" StrokeThickness="1" Data="m 4 14 4 0 0 -8 3 0 -5 -5 -5 5 3 0 z"/>

Ta-dah! Path annotations let you create any shape

Horizontal Lines

A common use case we hear from users is they want to create a Horizontal Line annotation at a specific Y-Value, which should display the Y data-value and be draggable. Well, we’re not going to go into dragging just here (that’s for another day!), but to create a static annotation which does the above is as easy as 1 2 3 …

<!-- Horizontal Lines -->
<s:HorizontalLineAnnotation HorizontalAlignment="Right" X1="5" Y1="3.2" Stroke="Orange" StrokeThickness="2">
    <s:TextAnnotation s:HorizontalLineAnnotation.Dock="Left" Foreground="Orange" 
                    FontSize="12" FontWeight="Bold" VerticalAlignment="Top" 
                    HorizontalAlignment="Right" Text="Right Aligned, with text on left"/>
</s:HorizontalLineAnnotation>

<s:HorizontalLineAnnotation HorizontalAlignment="Stretch" Y1="2.8" Stroke="Orange" StrokeThickness="2">
    <s:TextAnnotation s:HorizontalLineAnnotation.Dock="Top" HorizontalAlignment="Right" Margin="0,0,0,0" Foreground="Orange" 
                    FontSize="12" FontWeight="Bold"
                    Text="2.8"/>
</s:HorizontalLineAnnotation>

Now you should have created two horizontal lines. The first is right aligned, by defining X1 as a relative or absolute coordinate and setting HorizontalAlignment=Right, you right align the line at a defined Y1 point.

The second line is stretched across the chart. This uses HorizontalAlignment.Stretch and specifies a Y1 point. Both line annotations also have nested TextAnnotations, which can be docked around the line to get the desired effect.

HorizontalLineAnnotation’s provide a flexible way to show a line & text at a Y-value

Events and Interaction

So, if you really want to be an annotation guru you’ll want to attach events, or tooltips to your annotations. After all, they are data-markers right? They must allow you to drill into the data via eventing. The following Xaml shows how you can attach a tooltip, or a mouse event to an annotation for further data-visibility goodness:

<!-- Events and Interaction -->
<s:TextAnnotation X1="0.3" Y1="2.5" Text="Or Textboxes with hover & click events" FontSize="12"/>

<s:TextAnnotation X1="0.3" Y1="2.0" X2="2.3" Y2="1.0" Text="(Hover Me)" Foreground="White" BorderBrush="#990000" Background="#87B22020" BorderThickness="2" CornerRadius="5" MouseEnter="TextAnnotation1_MouseEnter"/>
<s:TextAnnotation X1="2.5" Y1="2.0" X2="4.5" Y2="1.0" Text="(Click Me)" Foreground="White" BorderBrush="#990000" Background="#87B22020" BorderThickness="2" CornerRadius="5" MouseDown="TextAnnotation2_MouseClick"/>
<s:TextAnnotation X1="4.8" Y1="2.0" X2="6.8" Y2="1.0" Text="(Tooltip)" Foreground="White" BorderBrush="#990000" Background="#87B22020" BorderThickness="2" CornerRadius="5" ToolTipService.ToolTip="Tah-dah! I have a tooltip"/>

<s:TextAnnotation X1="7.2" Y1="2.0" Text="Above or below the"/>
<s:TextAnnotation X1="7.2" Y1="1.6" Text="Chart Series!"/>

In the code-behind, we’ll have to add some event handlers to demonstrate that these are working:

public partial class AnnotationsInXaml : UserControl
{
    public AnnotationsInXaml()
    {
        InitializeComponent();
    }

    private void TextAnnotation2_MouseClick(object sender, System.Windows.Input.MouseEventArgs e)
    {
        ((TextAnnotation) sender).Text = "Clicked!";
    }

    private void TextAnnotation1_MouseEnter(object sender, MouseEventArgs e)
    {
        ((TextAnnotation)sender).Text = "Hovered!";
    }
}

You should now have three boxes with events attached. The first, a hover event, the second a click event and the third a tooltip. Because Annotations are just WPF UIElements, you can template the tooltips and use MVVM / binding to create immersive charting applications where hovering over or clicking a marker shows a drill down of data to the user.

The completed annotations example. Wow! That’s a lot of annotations in a short space of time!

Example Source Code

This article doesn’t contain a source code download, however the working example is included in the SciChart Trial. In addition, you can see a live Silverlight 5 example here: Annotations are Easy.

4 Comments

  1. Tell O'Neal says:

    Do you have any examples adding annotations with a date time XAxis?

    • Andrew says:

      Hi there,

      It’s really easy, just set the X1, X2 parameters to a DateTime.

      If the XAxis is a CategoryDateTimeAxis, then you need to set the X1, X2 parameters to an integer (index to data)

      Hope that helps!

  2. Ari Sagiv says:

    Is there any way to use a custom usercontrol as an annotation?

Leave a Reply