WPF and Silverlight Chart: multiple series databinding

Recently I needed a chart with multiple series (legend items) which would be able to display data from an OLAP database, like this:

The standard Chart requires to define each legend item in XAML, which doesn’t satisfy me, because I don’t know the actual number of returned items from a data source. So I decided to extend this control. Fortunately, there was a little work: only 3 properties and 1 method.

And now I can write xaml in this way:

        <local:ExtendedChart ItemsSource="{Binding Series}">
            <local:ExtendedChart.ItemTemplate>
                <DataTemplate>
                    <chart:ColumnSeries ItemsSource="{Binding Items}" DependentValuePath="Value" IndependentValuePath="Month" Title="{Binding Title}" />
                </DataTemplate>
            </local:ExtendedChart.ItemTemplate>
        </local:ExtendedChart>

The ExtendedChart control doesn’t require to redefine its template and contains few lines of code:

    public class ExtendedChart : Chart
    {
        ///
<summary>
        /// List of CLR-objects which represent series of the chart
        /// </summary>

        public IEnumerable ItemsSource
        {
            get { return (IEnumerable)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(ExtendedChart), new PropertyMetadata(null, (s, e) => ((ExtendedChart)s).InitSeries()));

        ///
<summary>
        /// Template for an item, transforms a CLR-object to an ISeries object
        /// </summary>

        public DataTemplate ItemTemplate
        {
            get { return (DataTemplate)GetValue(ItemTemplateProperty); }
            set { SetValue(ItemTemplateProperty, value); }
        }

        public static readonly DependencyProperty ItemTemplateProperty =
            DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(ExtendedChart), new PropertyMetadata(null, (s, e) => ((ExtendedChart)s).InitSeries()));

        ///
<summary>
        /// This property is necessary for stacked charts
        /// </summary>

        public DataTemplate ItemsHostTemplate
        {
            get { return (DataTemplate)GetValue(ItemsHostTemplateProperty); }
            set { SetValue(ItemsHostTemplateProperty, value); }
        }

        public static readonly DependencyProperty ItemsHostTemplateProperty =
            DependencyProperty.Register("ItemsHostTemplate", typeof(DataTemplate), typeof(ExtendedChart), new PropertyMetadata(null, (s, e) => ((ExtendedChart)s).InitSeries()));

        private void InitSeries()
        {
            this.Series.Clear();
            if (this.ItemsSource == null || this.ItemTemplate == null)
                return;

            //From items to series
            var series = from item in this.ItemsSource.OfType<object>()
                        let seriesItem = this.ItemTemplate.LoadContent() as ISeries
                        where seriesItem != null && seriesItem is FrameworkElement
                        let dummy = ((FrameworkElement)seriesItem).DataContext = item
                        select seriesItem;

            //Generic series and stacked series are different, that's why I use this if-else
            var hostSeries = this.ItemsHostTemplate != null ? this.ItemsHostTemplate.LoadContent() as DefinitionSeries : null;
            if (hostSeries != null)
            {
                this.Series.Add(hostSeries);
                series.OfType<SeriesDefinition>().ToList().ForEach(hostSeries.SeriesDefinitions.Add);
            }
            else series.ToList().ForEach(this.Series.Add);
        }
    }

The code above will work in WPF as well if you use the new version of WPF Toolkit for WPF4.

Here is the completed solution for Silverlight: BindableSilverlightChart.zip | Download from Google Docs
For WPF use this link: WpfBindableChart.zip

Advertisements

7 Responses to WPF and Silverlight Chart: multiple series databinding

  1. Vivek A says:

    Hi, I am trying to download this source, but dropbox and other sites are blocked at work.
    Can you please upload it here if possible? Would be much appreciated.

  2. codea says:

    Very nice thanks works like a charm.

    I just copied the extended class and pasted it in my project.

  3. mkrain says:

    Is there a way to get this to work on Windows Phone?

  4. Arno says:

    Is there a way to change te style of the lines so you can change the tooltip or colors the lines have ?
    Is it possible to still make random colors for the lines ?

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

%d bloggers like this: