Silverlight Feeds - All your Silverlight feeds in one place.

Sponsors

Thursday, August 27, 2009

Pie Chart Easy AS….

by jesseliberty via Jesse Liberty - Silverlight Geek on 8/27/2009 6:33:58 PM

I wanted to add an animated pie chart to my previous post.  The samples from the Toolkit are terrific, but sometimes it is difficult to find the easiest, most cookbook like process; so for those of you who might want to do the same, here is an annotated walk-through of creating this animated pie chart:

I began by opening Visual Studio and creating a new Silverlight Application, and saying no to the offer to create a Web application.

The UI, created in Page.xaml consists of the header and the Chart, placed in a Grid. You can easily do this in Blend or, in this case the layout is so simple, I hard-coded it in Xaml:

<UserControl 
xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;
assembly=System.Windows.Controls.DataVisualization.Toolkit"

x:Class="Pi.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="350" Height="350">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>



<TextBlock Text="Division of Effort Among Activities"
Margin="20,10,0,0"
Grid.Row="0"
FontFamily="Georgia"
FontSize="18"
Foreground="Blue" />

<chartingToolkit:Chart x:Name="ActivityChart"
Margin="20"
Grid.Row="1">
<chartingToolkit:Chart.Series>
<chartingToolkit:PieSeries Title="Fall Activity"
IndependentValueBinding="{Binding Name}"
DependentValueBinding="{Binding Value}" />
</chartingToolkit:Chart.Series>
</chartingToolkit:Chart>

    </Grid>
</UserControl>

The key Xaml here is the Chart control which contains a Series which in turn contains a PieSeries. The PieSeries has an Independent and a Dependent set of values, as explained in some detail here.

To have a set of values to bind to, I created a data class that I named Activity. The Activity class has three properties of interest:

  • Name – used to hold the independent value
  • Value – used to hold the dependent value
  • Activities – returns a list of Activity objects
   1: using System;
   2: using System.Collections.Generic;
   3:  
   4: namespace Pi
   5: {
   6:   public class Activity
   7:   {
   8:     public string Name { get; set; }
   9:     public double Value { get; set; }
  10:     
  11:     // static property to retrieve 
  12:     // List of Activity objects
  13:     public static List<Activity> Activities
  14:     {
  15:       get
  16:       {
  17:         // value of 5 and names of activities are hard coded
  18:         // Generalizing is left as an exercise for the ambitious
  19:         var percentages = FillPercentages(5);  
  20:         var activitiesList = new List<Activity>()
  21:              {
  22:                new Activity() {Name = "RiaServices", Value = percentages[0]},
  23:                new Activity() {Name = "DataGrid", Value = percentages[1]},
  24:                new Activity() {Name = "Behaviors", Value = percentages[2]},
  25:                new Activity() {Name = "VSM", Value = percentages[3]},
  26:                new Activity() {Name = "SampleData", Value = percentages[4]}
  27:              };
  28:         return activitiesList;
  29:       }
  30:     }
  31:  
  32:     // fill List<Double> with n doubles that sum to 1.0
  33:     // where n = numDoubles
  34:     private static List<Double> FillPercentages(int numDoubles)
  35:     {
  36:       var pctgs = new List< Double >();
  37:       var r = new Random();
  38:       double total = 0.0;
  39:       
  40:       for (int i = 0; i < numDoubles-1;)
  41:       {
  42:  
  43:         double val = r.NextDouble();
  44:         if ( val + total < 1.0)
  45:         {
  46:           pctgs.Add(val);
  47:           ++i;
  48:         }
  49:       }
  50:       pctgs.Add( 1.0 - total );  // final value
  51:       return pctgs;
  52:     } 
  53:  
  54:   }   // end class
  55: }     // end namespace

On line 13 we start the definition of the Activities property (only a get accessor is implemented)

On line 19 we delegate to a helper method generating 5 random values between 0 and 1 that together sum to 1. These will be treated as the relative percentages reflected in the pie chart.

Lines 20-27 fill our five hard-coded activities with the generated percentages and on line 28 we return the List of Activity objects we just created.

The code-behind for MainPage uses a dispatch timer to call a helper method FillPie every 4 seconds.

The helper method sets the ItemSource property on the PieSeries to whatever is returned by the static Activities property of the Activity class. Retrieving that property causes the percentages to be regenerated, and the chart is redrawn.

 

   1: using System;
   2: using System.Windows.Controls;
   3: using System.Windows.Controls.DataVisualization.Charting;
   4: using System.Windows.Threading;
   5:  
   6: namespace Pi
   7: {
   8:   public partial class MainPage : UserControl
   9:   {
  10:     public MainPage()
  11:     {
  12:       InitializeComponent();
  13:       Animate();
  14:     }
  15:  
  16:     private void Animate()
  17:     {
  18:       var timer = new DispatcherTimer();
  19:       timer.Start();  // Run once for display
  20:       // lambda syntax - same as
  21:       // timer.Tick +=new EventHandler(FillPie);
  22:       // but then you'd need FillPie to take an object and event args
  23:       timer.Tick +=
  24:           ( ( s, args ) => FillPie() );  // every tick call FillPie
  25:  
  26:       // http://msdn.microsoft.com/en-us/library/cc316852.aspx
  27:       timer.Interval = new TimeSpan( 0, 0, 4 ); // 4 seconds
  28:       timer.Start();
  29:     }
  30:  
  31:  
  32:     private void FillPie()
  33:     {
  34:       var cs = ActivityChart.Series[0] as PieSeries;
  35:       if ( cs != null )
  36:       {
  37:         // generating the data is handled by the static property
  38:         cs.ItemsSource = Activity.Activities;
  39:       }
  40:       else
  41:       {
  42:         throw new InvalidCastException( "Expected Series[0] to be a column" );
  43:       }  // end else
  44:     }    // end method
  45:   }      // end class
  46: }        // end namespace

Notice that on lines 23 and 24 we register the FillPie method with the event using lambda notation; this makes short work of using a method that does not happen to need the standard arguments (object, eventArgs).

Timer.Start is called on line 19 to cause an immediate drawing of the pie, and then again on line 28 to implement the new time interval.

email it!bookmark it!digg it!

Original Post: Pie Chart Easy AS….

Subscribe

New Feed

Product Spotlight

Recently Updated Sources

Legal Note

The content of the postings is owned by the respective author. Silverlight Feeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on Silverlight Feeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us