Take a scoop of Silverlight Toolkit Pie Chart

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.  PieChart

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 Silverlight Application new project Add the references of following assemblies

  1. System.Windows.Controls.DataVisualization.Toolkit
  2. 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 !

Advertisements

4 thoughts on “Take a scoop of Silverlight Toolkit Pie Chart

  1. Dear Afzal Sahib!

    I have read your solution for uploading file on SharePoing programatically. It is good and must be helpfull for many. I have a related question. I have a window application from where I have created an XML document using xslt with XslCompiledTransform transform = new XslCompiledTransform();. So far I was writing it on local drive and it was fine. Now I want to write it on SharePoint folder. How can I do that?
    I know there is a way to read a source file and upload it by using PUT method or by using your code. But I do not know how to write it directly from my transform object.
    My knowledge of SharePoint is close to 0.

    Thanks

    Tayyab

    • Dear Tayyab
      I think it should go through provided if you have enough permissions on the folder where you are creating the file. Try it out and let me know the results.

      Alternatively you can also extend your current windows application to directly upload the document to the specific document library using SharePoint webservices model.

      Hope this helps

      Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s