Creating Custom DataPoint Annotations in Silverlight Charts

Posted Thu Nov 19, 2009 @ 8:02 AM

As most people are by now aware, the recently released Web.UI 2009.3, introduces a Silverlight Charting control.  Although the main reasons for using the charting control is to visually display the relationship between data, at times this may not be enough on its own.  Sometimes you want to display additional information about each data point.  This can be accomplished with DataPoint annotations or DataPoint popups on mouseovers.

Here we are going to focus on how to enable DataPoint annotations and also how to customize them.

Enabling DataPoint Annotations

We'll start with a basic pie chart on which we'll enable DataPoint annotations on the series.  Our XAML code will look like this:

<Chart:Chart x:Name="Chart1" Width="300" Height="260" XValue="Month" ChartKind="Doughnut" Visibility="Collapsed">
<Chart:Chart.DataSeries>
<Chart:Series YValue="Value" ShowPointAnnotations="True" />
</Chart:Chart.DataSeries>
</Chart:Chart>

In our code-behind we will create a simple static data class and set it as our chart's data source:

public class ChartData 
{
public string Month { get; set; }
public double Value { get; set; }
}

...

public void Chart_Loaded(object sender, RoutedEventArgs e)
{
Chart chart = sender as Chart;
chart.DataSource = new ChartData[]
{
new ChartData() { Month = "Jan", Value = 5212000 },
new ChartData() { Month = "Feb", Value = 2356000 },
new ChartData() { Month = "Mar", Value = 1451000 },
new ChartData() { Month = "Apr", Value = 4088000 },
new ChartData() { Month = "May", Value = 993600 },
};
chart.Visibility = Visibility.Visible;
}

This will produce the following chart:

Customizing the DataPoint Annotations

By enabling the DataPoint annotations on a series, the DataPoint's Y value is displayed by default.  This does not always produce the desirable effect.  We may want to format this value, the XAML container that displays it or display additional values associated with the DataPoint.  We do this by creating the XAML template for the DataPoint annotation and setting it on the series' DataPointAnnotationTemplate property.

The example below will create a custom annotation container with a background, displaying the Y value of the DataPoint:

<Chart:Chart x:Name="Chart1" Width="300" Height="260" XValue="Month" ChartKind="Doughnut" Visibility="Collapsed">
<Chart:Chart.DataSeries>
<Chart:Series YValue="Value" ShowPointAnnotations="True" >
<Chart:Series.DataPointAnnotationTemplate>
<DataTemplate>
<Border Background="#60000000" CornerRadius="3">
<TextBlock Text="{Binding DataPoint.Y, Converter={StaticResource SalesAmountConverter}}" Foreground="White" FontWeight="Bold" FontSize="11" Margin="4 2"/>
</Border>
</DataTemplate>
</Chart:Series.DataPointAnnotationTemplate>
</Chart:Series>
</Chart:Chart.DataSeries>
</Chart:Chart>

If we take a closer look, the TextBlock that displays the value is programmed to show the DataPoint's Y value, but that value is processed through a custom converter.  This allows us to add custom formatting to the actual value of the DataPoint.  In this example, we will create a converter that displays the value as a currency, but rounds it off to thousands (K) or millions (M) in order to make the annotation shorter.

public class SalesAmountConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double)
{
string suffix = "";
double val = (double)value;

if (val >= 1000000)
{
suffix = "M";
val /= 1000000;
}
else if (val >= 1000)
{
suffix = "K";
val /= 1000;
}
return String.Format("{0}{1}", val.ToString("c"), suffix);
}
return "?";
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return 0.0;
}
}

This will now produce the following chart:

Additional Customization Suggestions

It is important to note that in the custom template we can access any of the properties of the DataPoint.  An interesting property to keep in mind is DataPoint's Tag property.  This property has no internal use and it's sole purpose is hold additional information associated with the DataPoint that needs to be calculated at run-time and used within the custom templates for DataPoint annotations or pop-ups.  As such, we can create a custom object that can hold multiple properties such as colors and text that we can then access in the XAML template in order to further customize it.  An example of this can be seen in the tutorial that describes custom DataPoint pop-ups.

Comments

» There are currently no comments for this blog post.

Click here to log in or create an account.