Changing Pie Slice colours in Silverlight 3 Chart Control

As most of you know, Silverlight 3 includes the new charting controls. It is a functionality that Windows developer hoped would ship out of the box for a long time. It lets us easily add visually compelling functionality and the “Wow” factor to our applications.

On my most recent project, I was using the Pie chart control of SL3 to display some data in the application. Hmmm… pie …

Anyway, The Legend on the chart was taking up too much room and I wanted to have bit more control on the colours of each of the pie slices. This would allow me to create my own fancy Legend/Key into the graph and have full control over the display.

As it turns out, the PieSeries control doesn’t really expose the pie datapoint property in an easily consumable manner. After some research I found some resources that demonstrated how to change certain properties of various charts. The most relevant one was the one dealing with how to change the mouse over text for each of the pie slices.

Essentially, it requires us to Re-Style the Pie chart and supply our own customisations in a new style. Since the charting controls are open source, we don’t have to start from scratch. We can cut and paste the existing style and modify it as we see fit.

None of these other posts dealt with the matter of changing the colour of a pie slice though. They all seemed happy cycling through the predefined colours in the style and not having access to them outside of the chart control.

My customisations allow us to have more control over the slice colours. In a typical Model-View-View-Model pattern, we might have a colour associated with a particular data point. We might use that property to set the colour of a pie slice or a border or foreground of a completely different control.

In the example below, I set the graph colors and use the same colours in a Datagrid to fill a rectangle to generate my own “Legend”. Basically, I can bind the colour associated with this data point to any control in the application.

PieChartExample

The “View-Model” class in this case is a class called PieSlice. This exposes three important properties, the percentage (Dependent value), the Description (Independent value) and the Radial Gradient Brush (Completely customisable). In our PieSeries control, we specify a new Style by setting the StylePalette property as shown below.

    <chartingToolkit:Chart x:Name="SamplePercentageChart"  Grid.Row="0"
                               DataContext="{Binding ElementName=PieSampleUserControl}" >
 
            <chartingToolkit:PieSeries DependentValueBinding="{Binding Percentage}" 
                                       ItemsSource="{Binding PieSlices}"
                                       StylePalette="{StaticResource MyStylePalette}"
                                		IndependentValueBinding="{Binding }" >
 
            </chartingToolkit:PieSeries>
        </chartingToolkit:Chart>

Note that Silverlight 3 also supports Element binding which we will take advantage of to set the DataContext to the “Code Behind” class. This allow us to quickly expose a dummy PieSlices property in our user control that we can bind to. Our user control class looks something like this

    public partial class MainPage : UserControl
    {
 
        public List<PieSlice> PieSlices { get; set; }
 
        public MainPage()
        {
            InitializeComponent();
            List<PieSlice> sampleData = new List<PieSlice>();
            sampleData.Add (new PieSlice("SliceOne", 25, "#FFB9D6F7", "#FF284B70")); // Blue
            sampleData.Add (new PieSlice("SliceTwo", 25, "#FFFBB7B5", "#FF702828")); // Red
            sampleData.Add (new PieSlice("SliceThree", 25, "#FFB8C0AC", "#FF5F7143")); // Light Green
            sampleData.Add(new PieSlice("SliceFour", 25, "#FFFDE79C" , "#FFF6BC0C" )); // Yellow 
         }
}

Now that we have set the custom style for the style palette, we need to actually write it. We create a PieChartStyles.xaml file and create a resource dictionary to hold our custom styles and control templates. We can then add this dictionary to our application wide resource dictionary or our control specific resource dictionary.

First, we overwrite the control template for the PieDataPoint by setting the template property as shown below

    <datavis:StylePalette x:Key="MyStylePalette" >
        <Style TargetType="Control">
            <Setter Property="Template" Value="{StaticResource MyPieDataPointTemplate}">
        </Style>
    </datavis:StylePalette>

Note that you need to add the “datavis” xml namespace that references the “System.Windows.Controls.DataVisualization” CLR namespace. (All this is available in the sample project that can be downloaded as a zip file.)

Now we have to specify the Template we will use with each of the Pie data points. For this we pretty much get the existing control template as it is from here. This ensures that our charts look just like the out of the box charts. The most important customisation we do is change the Background property of the Path Control. Currently it is set as

   ...
 <Path 
   x:Name="Slice"
   Data="{TemplateBinding Geometry}"
   Fill="{TemplateBinding Background}"
   Stroke="{TemplateBinding BorderBrush}"
StrokeMiterLimit="1">

The background property in turn is set by the style palette. But now that we are exposing the colour we want as a ColorGradientBrush property, we can bind to it directly. This changes our control template above to the following.

   ...
 <Path 
   x:Name="Slice"
   Data="{TemplateBinding Geometry}"
   Fill="{Binding SliceColor}"
   Stroke="{TemplateBinding BorderBrush}"
StrokeMiterLimit="1">

Note that one possibility is to expose a start colour and end colour property on the View-Model and bind these to the gradient stops rather than create a RadialGradientBrush. But the GradientStop class does not inherit from FrameworkElement class. This stops databinding and throws up a very general and unhelpful AG_E_PARSER_BAD_PROPERTY_VALUE exception. So I ended up creating a RadialGradientBrush and binding to that instead.

The complete sample application can be downloaded here

Tags: , ,


SetPageWidth