A Complete walkthrough of creating Pie Chart with advanced features.
Introduction
Silverlight has come a long way from just being a media and graphics enhancements tool to full blown Line of Business Application platform.In this short post we will dive into the inner workings of Pie Chart that is available as a part of
Silverlight Toolkit. Have a look at the image below which shows the output that we shall be working for.
Control Templates and Styles
Silverlight is a great technology to work with. It gives so much leverage and freedom to developers that you can can completely override the default look of any control and give more sparkles to it by adding styles . In this post I shall be using the combination of both. Scott Guthrie has great
post on his blog which discusses the control templates. I shall be targeting PieDataPoint, this class represents each slice in the pie chart. I shall be also using style palette which is part of System.Windows.Controls.DataVisualization.Toolkit assembly. In the style palette we will be setting the different backgrounds of each slice. Though this is completely optional if you don't specify the style palette , silverlight Charting engine takes the complete control and renders the colors of each slice automatically.Further using Styles and Control Templates I shall be changing the Legends that are getting displayed on the right side of the chart. I shall also be overriding the default tooltip text in the control template of PieDataPoint.
Getting Started
This post assumes that you have following software's installed on your computer.
Create new project of SilverLight Application as displayed in the figure below

Add the references of following assemblies
- System.Windows.Controls.DataVisualization.Toolkit
- System.Windows.Controls.Toolkit
Any chart requires data for its display. Here in this example we will generate the random figures (between 1000 and 50000) of each month (Jan to Dec).I have created MonthlyCollection class for it , the Total property of this class will be binded to Chart ItemsSource. The complete code listing of this class is given below.
Public Class MonthlyCollection
Private _Month As String
Public Property Month() As String
Get
Return _Month
End Get
Set(ByVal value As String)
_Month = value
End Set
End Property
Private _Amount As Double
Public Property Amount() As Double
Get
Return _Amount
End Get
Set(ByVal value As Double)
_Amount = value
End Set
End Property
Public Shared ReadOnly Property Total() As List(Of MonthlyCollection)
Get Dim objMonthlyCollection As New List(Of MonthlyCollection)
Dim Rnd As New Random
With objMonthlyCollection
.Add(New MonthlyCollection With {.Month = "Jan", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Feb", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Mar", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Apr", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "May", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Jun", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Jul", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Aug", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Sep", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Oct", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Nov", .Amount = Rnd.Next(1000, 50000)})
.Add(New MonthlyCollection With {.Month = "Dec", .Amount = Rnd.Next(1000, 50000)})
End With
Return objMonthlyCollection
End Get
End Property
End Class
Now as the data is in place , let us now look at the control templates and styles code. As we will be using the animation for each slice in a simultaneous mode. Let us first look at the PieDataPoint control template.
<ControlTemplate x:Key="PieDataPoint" TargetType="Chart:PieDataPoint">
<Path
Data="{TemplateBinding Geometry}"
Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"
RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<ScaleTransform x:Name="Scale" ScaleX="0" ScaleY="0"/>
</Path.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="RevealStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Shown">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Scale"
Storyboard.TargetProperty="ScaleX"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="Scale"
Storyboard.TargetProperty="ScaleY"
To="1"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Hidden">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Scale"
Storyboard.TargetProperty="ScaleX"
To="0"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="Scale"
Storyboard.TargetProperty="ScaleY"
To="0"
Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal" >
<ContentControl Content="Collection for " />
<ContentControl Content="{TemplateBinding IndependentValue}" />
<ContentControl Content=" is " />
<ContentControl DataContext="{TemplateBinding DependentValue}" Content="{Binding Converter= {StaticResource DataFormatter},ConverterParameter=\{0:C\}}" />
</StackPanel>
</ToolTipService.ToolTip>
</Path>
</ControlTemplate>
One thing in the above code that is worth observing is the ToolTip, using the powerful feature of control templates how am I transforming the mere tooltip text into useful information. Let us now look at how can I customize the Legends of the chart rather than just text.
<Style x:Key="LegendStyle" TargetType="Chart:LegendItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Chart:LegendItem">
<Grid>
<Rectangle Fill="{Binding Background}" Stroke="{Binding BorderBrush}" StrokeThickness="1" Margin="1" />
<DataVisuals:Title Content="{TemplateBinding Content}" Margin="2" Foreground="White" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the above code I am using TemplateBinding to bind the content and showing each legend in rectangle with the appropriate background. Finally let us look into the StylePallete , as discussed above this is an optional step but would be good to have if you want more control on the output. Have a look at the code below.
<DataVisuals:StylePalette x:Key="PieDataPointPalette">
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="#FFF4F4F4"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="#FF5A88CE"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="#FFCE5A5A"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="#FFFFFF72"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="Blue"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="Red"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="Green"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="Pink"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="Cyan"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="#FF555555"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="#FF313861"/>
</Style>
<Style TargetType="Chart:PieDataPoint">
<Setter Property="Template" Value="{StaticResource PieDataPoint}"/>
<Setter Property="Background" Value="#FF000000"/>
</Style>
</DataVisuals:StylePalette>
In this code I am targeting the style for the control template, PieDataPoint and setting its background property of various colors.One thing important to note here is that as my data represents of monthly collection which involves twelve months of the calendar. I need to specify twelve style attributes accordingly.The user can interact with the chart by clicking on the each slice of the pie chart. Once he click he gets corresponding info of the slice clicked on the labels on the right top.We can achieve this functionality by trapping the SelectionChanged event of Chart:PieSeries
Private Sub PieSeries_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
If e.AddedItems.Count >= 1 Then
Me.PnlInfo.DataContext = e.AddedItems(0)
Else
Me.PnlInfo.DataContext = Nothing
End If
End Sub
The above code assigns the first element of AddedItems Collection to the DataContext property of StackPanel.
Now let us look into the fetching of the new data, When user clicks on Refresh Data button the new data is binded to ItemsSource. Have a look at the code for the same.
Private Sub BtnRefresh_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim objPieSeries As DataVisualization.Charting.PieSeries
objPieSeries = CType(Me.PieChart.Series(0), DataVisualization.Charting.PieSeries)
objPieSeries.ItemsSource = MonthlyCollection.Total
End Sub
Closure
There is a well known saying that picture is worth thousand words. You can bring your data to life by providing visuals animations to it. It can be great help to create digital dashboards. I hope you must have enjoyed reading the post. Download the sample code from
here. Cheers and Happy Charting !