|
Dec
23
Written by:
Jeremiah Morrill
12/23/2008 7:43 PM
My buddy, who is learning Silverlight and MVVM, has been using the new Chart controls from the Silverlight Toolkit. The road block he was having was being able to data bind a collection of collections to a Chart's series. This was difficult because the Series property of the Chart does not play nice. So me being such a wonderful friend, I whipped up a quick attached behavior to allow this. Here is the usage: <Charting:Chart x:Name="chart"
Helper:ChartHelper.DependentValueBinding="Value"
Helper:ChartHelper.IndependentValueBinding="Key"
Helper:ChartHelper.Title="TitlePropertyOnCollection"
Helper:ChartHelper.SeriesType="Line"
Helper:ChartHelper.SeriesSource="{Binding Path=MyCollectionofCollections}" />Here is the code: public enum SeriesType
{
Line,
Bar,
Column,
Scatter,
Pie
}
public class ChartHelper
{
#region SeriesSource
public static readonly DependencyProperty SeriesSourceProperty =
DependencyProperty.RegisterAttached("SeriesSource",
typeof(IEnumerable),
typeof(ChartHelper),
new PropertyMetadata(SeriesSourceChanged));
public static IEnumerable GetSeriesSource(DependencyObject d)
{
return (IEnumerable)d.GetValue(SeriesSourceProperty);
}
public static void SetSeriesSource(DependencyObject d, IEnumerable value)
{
d.SetValue(SeriesSourceProperty, value);
}
#endregion
#region DependentValueBinding
public static readonly DependencyProperty DependentValueBindingProperty =
DependencyProperty.RegisterAttached("DependentValueBinding",
typeof(string),
typeof(ChartHelper),
null);
public static string GetDependentValueBinding(DependencyObject d)
{
return (string)d.GetValue(DependentValueBindingProperty);
}
public static void SetDependentValueBinding(DependencyObject d, string value)
{
d.SetValue(DependentValueBindingProperty, value);
}
#endregion
#region IndependentValueBinding
public static readonly DependencyProperty IndependentValueBindingProperty =
DependencyProperty.RegisterAttached("IndependentValueBinding",
typeof(string),
typeof(ChartHelper),
null);
public static string GetIndependentValueBinding(DependencyObject d)
{
return (string)d.GetValue(IndependentValueBindingProperty);
}
public static void SetIndependentValueBinding(DependencyObject d, string value)
{
d.SetValue(IndependentValueBindingProperty, value);
}
#endregion
#region Title
public static readonly DependencyProperty TitleProperty =
DependencyProperty.RegisterAttached("Title",
typeof(string),
typeof(ChartHelper),
null);
public static string GetTitle(DependencyObject d)
{
return (string)d.GetValue(TitleProperty);
}
public static void SetTitle(DependencyObject d, string value)
{
d.SetValue(TitleProperty, value);
}
#endregion
#region SeriesType
public static readonly DependencyProperty SeriesTypeProperty =
DependencyProperty.RegisterAttached("SeriesType",
typeof(SeriesType),
typeof(ChartHelper),
new PropertyMetadata(SeriesType.Bar));
public static SeriesType GetSeriesType(DependencyObject d)
{
return (SeriesType)d.GetValue(SeriesTypeProperty);
}
public static void SetSeriesType(DependencyObject d, SeriesType value)
{
d.SetValue(SeriesTypeProperty, value);
}
#endregion
#region SeriesStyle
public static readonly DependencyProperty SeriesStyleProperty =
DependencyProperty.RegisterAttached("SeriesStyle",
typeof(Style),
typeof(ChartHelper),
null);
public static Style GetSeriesStyle(DependencyObject d)
{
return (Style)d.GetValue(SeriesStyleProperty);
}
public static void SetSeriesStyle(DependencyObject d, Style value)
{
d.SetValue(SeriesStyleProperty, value);
}
#endregion
private static void SeriesSourceChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
if(!(d is Chart))
{
throw new Exception("Series attached property only works on a Chart type");
}
var chart = d as Chart;
/* Clear out any old series in the chart */
chart.Series.Clear();
/* Get our collection of data we need for each series */
var chartSeriesSource = e.NewValue as IEnumerable;
if(chartSeriesSource == null)
throw new Exception("The SeriesSource does not support IEnumerable");
/* Loop over each collection of data */
foreach(var dataSource in chartSeriesSource)
{
DynamicSeries series;
/* Find out what type of series we want to use */
var seriesType = GetSeriesType(chart);
switch(seriesType)
{
case SeriesType.Line:
series = new LineSeries();
break;
case SeriesType.Bar:
series = new BarSeries();
break;
case SeriesType.Column:
series = new ColumnSeries();
break;
case SeriesType.Pie:
series = new PieSeries();
break;
case SeriesType.Scatter:
series = new ScatterSeries();
break;
default:
throw new ArgumentOutOfRangeException();
}
/* Get and set the style of the newly created series */
var seriesStyle = GetSeriesStyle(chart);
series.Style = seriesStyle;
string titleBindingName = GetTitle(chart);
if (!string.IsNullOrEmpty(titleBindingName))
{
/* Do some binding of the Title property */
var titleBinding = new Binding(titleBindingName)
{
Source = series.Title, Mode = BindingMode.TwoWay
};
series.SetBinding(Series.TitleProperty, titleBinding);
}
/* Setup the bindings configured in the attached properties */
series.DependentValueBinding = new Binding(GetDependentValueBinding(chart));
series.IndependentValueBinding = new Binding(GetIndependentValueBinding(chart));
/*Set the ItemsSource property, which gives the data to the series to be rendered */
series.ItemsSource = dataSource as IEnumerable;
/* Add the series to the chart */
chart.Series.Add(series);
}
}
}
Tags:
14 comment(s) so far...
Re: Silverlight Charts: Binding multiple Series
Nice trick, Jer! Very cool. :)
By Josh Smith on
12/24/2008 8:10 AM
|
Re: Silverlight Charts: Binding multiple Series
Great example! Any chance uploading the sample source like you did for the Silverlight MVVM example?
Cheers, indy
P.S. - Your Silverlight MVVM is SUPERB! 'hope you will share more of your knowledge in the future :)
By indy on
12/28/2008 12:56 PM
|
Re: Silverlight Charts: Binding multiple Series
Cool stuff. What namespace is DynamicSeries in? I have using System.Windows.Controls.DataVisualization.Charting; referenced, but that isn't it.
By Bob Baker on
4/20/2009 10:47 PM
|
Re: Silverlight Charts: Binding multiple Series
Thank you for this helpful code - I've made some additions and posted the updates on my blog blog.therohrers.org).
By Doug Rohrer on
6/10/2009 5:51 PM
|
Re: Silverlight Charts: Binding multiple Series
Thank you! Like Bob, I don't find the DynamicSeries namespace. Could you give me some help? Thank you!
By Valeria on
8/24/2009 2:26 AM
|
Re: Silverlight Charts: Binding multiple Series
I found: with the new Toolkit version, I have to replace DynamicSeries with DataPointSeries. I hope this helps.
By Valeria on
8/24/2009 2:28 AM
|
Re: Silverlight Charts: Binding multiple Series
I tried to use the code you post; but, how can I set different ColumnSeries title? cause using the title property of your code, the title is the same for each column! Thank you
By Valeria on
8/24/2009 4:17 AM
|
Re: Silverlight Charts: Binding multiple Series
Thanks, your friend must be proud of you. I also find myself getting interested in Silverlight Charts. The FreeSilverlightChart Control uses a model to access the data for displaying a chart. The specific model class must be of type FreeSilverlight.ChartModel. The FreeSilverlightChart Control can be easily drawn on any canvas once a ChartModel is specified and a particular chart type is chosen. Don't you find it cognitive?
By torrent search engine on
12/17/2009 6:51 AM
|
Re: Silverlight Charts: Binding multiple Series
Can you please share the source code? I am not able attached series to the chart
By Mahendra Balu on
12/17/2009 10:40 PM
|
Re: Silverlight Charts: Binding multiple Series
this is something i have been very interested in lately. thanks.
By Burberry handbags Replica on
1/5/2010 10:56 PM
|
Re: Silverlight Charts: Binding multiple Series
this is interesting. Is it possible to share the source code? thanks
By julyjohn on
1/26/2010 12:06 AM
|
Re: Silverlight Charts: Binding multiple Series
Thanks a lot for making this available. However, I was trying to turn this into a "true" Behavior by deriving from the Silverlight3 Behavior class (inside the System.Windows.Interactivity). I figured, "Hey, the Behavior for MouseWheel support works great, so lets do the same with this"! No dice. When the project builds it just tells me that "Chart does not have a property 'Title'". I've even went as far as adding instance Properties that just update the static DependencyProperties and it still won't recognize that these are attached properties. Interestingly enough, I do get all the intellisense in Xaml and can bind it right up on the Chart (ex. chartingBehaviors:ChartSeriesBindingBehavior.Title="{Binding Title}"). Does anyone know why the compiler thinks I am trying to set a Property on the Chart instead of recognizing my Behavior?
By Tim on
2/8/2010 9:14 AM
|
Re: Silverlight Charts: Binding multiple Series
How would I be able to bind the SeriesSource to an IEnumerable, but be able to specify the "DataMember" inside each one of those items that needs bound to the Series.ItemSource? In the example below, I want to bind the Series.Title to "Parent.Name" but bind its ItemSource to "Parent.Children".
Example: public class Parent { public string Name { get; set; } public ObservableCollection Children { get; set; } }
By Tim on
2/10/2010 8:20 AM
|
Re: Silverlight Charts: Binding multiple Series
if you want to buyin 2010 change you image, here is some good Website for more: gucci shoes gucci handbags gucci belts air jordans chi flat iron chi hair straightener and so on.
By cheap jordan shoes on
3/7/2010 9:22 PM
|
|
|
|