SciChart WPF 2D Charts > Tutorials > MVVM > Tutorial 07b - Adding Annotations with MVVM
Tutorial 07b - Adding Annotations with MVVM

Adding Annotations in MVVM

Source code for this tutorial can be found at our SciChart.WPF.Examples Github Repository under v5.x > Tutorials

We want to now add some Annotations in MVVM. To do this, lets create first our Annotation type, taken from Tutorial 07 - Adding Annotations.

Copy Code

<s:CustomAnnotation x:Class="SciChart.Mvvm.Tutorial.InfoAnnotation"

        <LinearGradientBrush x:Key="infoAnnotationBackground" StartPoint="0,0" EndPoint="0,1">
            <GradientStop Offset="0.5" Color="#FFF" />
            <GradientStop Offset="1" Color="#77C0D4EE" />


        <!-- Low-cost drop shadow -->
        <Border CornerRadius="2" BorderThickness="1" BorderBrush="#333" Background="#333" Opacity="0.8" Margin="2,2,0,0"/>

        <!-- News bullet body -->
        <Border CornerRadius="2" BorderThickness="1" BorderBrush="#555" Background="{StaticResource infoAnnotationBackground}">
            <TextBlock Text="N" Padding="3" FontWeight="Bold" FontSize="10"/>

        <!-- Creating the tooltip. In the TradeOverlayExampleViewModel we set a News
       object as datacontext of this annotation -->
            <ToolTip Foreground="#222">
                <Grid Margin="6" MaxHeight="100" MaxWidth="150">
                    <TextBlock Text="Show more info here!" Foreground="#3333FF"/>


Copy Code
using SciChart.Charting.Visuals.Annotations;
namespace SciChart.Mvvm.Tutorial
    public partial class InfoAnnotation : CustomAnnotation
        public InfoAnnotation()

We also need a ViewModel for the custom annotation. We base this off CustomAnnotationViewModel as follows:

Copy Code
using System;
using SciChart.Charting.Model.ChartSeries;
namespace SciChart.Mvvm.Tutorial
    public class InfoAnnotationViewModel : CustomAnnotationViewModel
        public override Type ViewType
            get { return typeof(InfoAnnotation); }

Now to add these to our charts using MVVM. We can't access the SciChartSurface.Annotations property, as this is on the SciChartSurface which is a view item, and cannot (should not) be accessed from the ViewModel.

Instead we're going to use the AnnotationsBinding MarkupExtension to add these to the chart.


Dynamically Adding Annotations in the ViewModel

In order to add Annotations in the ViewModel, we need to do a few things:

  1. Declare a collection of IAnnotationViewModel, similar to the RenderableSeries collection.
  2. Add our InfoAnnotationViewModel to this collection with X1,Y1 values to tag them onto the chart.
  3. In the view, we need to include a default style for InfoAnnotation to inherit from one of our built-in styles. This ensures that X1,X2 and other default properties are bound.

Let's do this below:

Copy Code
public class MainViewModel : BindableObject
    private string _chartTitle = "Hello SciChart World!";
    private string _xAxisTitle = "XAxis";
    private string _yAxisTitle = "YAxis";
    private ObservableCollection<IRenderableSeriesViewModel> _renderableSeries = new ObservableCollection<IRenderableSeriesViewModel>();
    private bool _enablePan;
    private bool _enableZoom = true;
    private XyDataSeries<double, double> _lineData;
    private DummyDataProvider _dummyDataProvider = new DummyDataProvider();
    private ObservableCollection<IAnnotationViewModel> _annotations = new ObservableCollection<IAnnotationViewModel>();
    public MainViewModel()
        // Subscribe to future updates
        int i = 0;
        _dummyDataProvider.SubscribeUpdates((newValues) =>
            // Append when new values arrive
            _lineData.Append(newValues.XValues, newValues.YValues);
            // Zoom the chart to fit
            // Every 100th datapoint, add an annotation
            if (i % 100 == 0)
                Annotations.Add(new InfoAnnotationViewModel() 
                   X1 = _lineData.XValues.Last(),
                   Y1 = 0.0
    private void CreateChartData()
        var initialDataValues = _dummyDataProvider.GetHistoricalData();
        // Create a DataSeries. We later apply this to a RenderableSeries
        _lineData = new XyDataSeries<double, double>() { SeriesName = "TestingSeries" };
        // Append some data to the chart                                
        _lineData.Append(initialDataValues.XValues, initialDataValues.YValues);        
    private void CreateChartSeries()
        // Create a RenderableSeries. Apply the DataSeries created before
        _renderableSeries = new ObservableCollection<IRenderableSeriesViewModel>();
        RenderableSeries.Add(new LineRenderableSeriesViewModel()
            StrokeThickness = 2,
            Stroke = Colors.SteelBlue,
            DataSeries = _lineData,
            StyleKey = "LineSeriesStyle"
    public ObservableCollection<IAnnotationViewModel> Annotations
        get { return _annotations; }
            _annotations = value;
    public ObservableCollection<IRenderableSeriesViewModel> RenderableSeries
        get { return _renderableSeries; }
            _renderableSeries = value;
    // ... ChartTitle, XAxisTitle, YAxisTitle, EnableZoom omitted for brevity ...


We need to update our view code as well.

  1. Ensure that all the resources in MainWindow.xaml are included in a resource dictionary.
  2. Include the default.xaml styles from SciChart. We need this for our base styule for CustomAnnotation
  3. Include a style for InfoAnnotation. We need this to ensure default properties such as X1,Y1 are data-bound.
Copy Code
            <ResourceDictionary Source="/SciChart.Charting;component/Themes/Default.xaml"/>
        <local:MainViewModel x:Key="MainViewModel"/>
        <!-- The TooltipControl template is defined below -->
        <!-- Change this if you want to have a non-default tooltip container -->
        <!-- The ContentPresenter is bound to the DataContext (a SeriesInfo type) -->
        <!-- and the ContentTemplate is the DataTemplate for the SeriesInfo -->
        <!-- Finally, the TooltipContainerStyle is set on the RenderableSeries via Style -->
        <Style x:Key="TooltipContainer" TargetType="s:TooltipControl">
            <Setter Property="Template">
                    <ControlTemplate TargetType="s:TooltipControl">
                        <Border Background="#ff6495ed"
                            <ContentPresenter Content="{TemplateBinding DataContext}"
                                            ContentTemplate="{TemplateBinding ContentTemplate}" />

        <!-- Tooltip Template for an XyDataSeries binds to XySeriesInfo -->
        <!-- Check out the properties on XySeriesInfo to see what you can bind to -->
        <DataTemplate x:Key="TooltipTemplate" DataType="s:XySeriesInfo">
            <StackPanel Orientation="Vertical">
                <TextBlock Foreground="White">
                <Run Text="Series: "/>
                <Run Text="{Binding SeriesName, StringFormat='{}{0}:'}"/>
                <TextBlock Foreground="White">
                <Run Text="X-Value: "/>
                <Run Text="{Binding FormattedXValue, Mode=OneWay}"/>
                <TextBlock Foreground="White">
                <Run Text="Y-Value: "/>
                <Run Text="{Binding FormattedYValue, Mode=OneWay}"/>
        <!-- Style applied via x:Key name in ViewModel. See StyleKey property of LineRenderableSeriesViewModel -->
        <Style TargetType="s:BaseRenderableSeries"  x:Key="LineSeriesStyle">
            <Setter Property="s:RolloverModifier.TooltipContainerStyle" Value="{StaticResource TooltipContainer}"/>
            <Setter Property="s:RolloverModifier.TooltipTemplate" Value="{StaticResource TooltipTemplate}"/>
            <Setter Property="s:RolloverModifier.IncludeSeries" Value="True"/>
            <Setter Property="StrokeThickness" Value="2"/>

        <!-- Style applied to InfoAnnotation ensures default properties are bound -->
        <Style TargetType="local:InfoAnnotation" BasedOn="{StaticResource MvvmCustomAnnotationStyle}"/>

Running the code, we now see this: