Telerik blogs

While reviewing the daily portion of blog posts today one article at Delay’s blog here caught my attention – customizing the MS chart control via re-templating and the MVVM design pattern in order to achieve different colorization of the bar series items in a single series.

We have discussed similar functionality some time ago but it seemed like a very non-mainstream scenario and based on our experience with the ASP.NET / WinForms chart it was rarely requested feature so we decided we can go without it for the time being. However, once I read the article I started thinking what it would take for RadChart to produce matching level of customization – after all we already provide the option of retemplating that allows to easily swap the template for the chart series (via the respective SeriesDefinition.ItemStyle property) and also powerful databinding capabilities.

There was some bad news, however – the problem that prevented us from implementing this scenario right away was that internally RadChart control does not work with raw data but with data abstraction (we extract the “significant” data from the source and convert it to collections of DataPoints). We originally chose this approach as it simplifies handling of heterogeneous data sources and minimizes reflection calls but unfortunately its capabilities in custom scenarios like this proved to be insufficient (the problem is that the DataContext within the Bar template is not the original data object as in the MS chart implementation but our abstract DataPoint instance and we can bind only to strongly-typed DataPoint members).

Now the good news – I am pleased to inform you that we will extend the DataPoint class for the Q1 2009 release with one additional property that exposes the original piece of data bound to the respective series items (DataPoint.DataItem property). Once this property is in place, implementing the MVVM scenario with RadChart is very simple.

Define the custom bar series item template and bind the Rectangle.Fill property to {Binding DataItem.GradeColor} instead of the default {Binding ItemStyle}:

XAML

<Grid>
<Grid.Resources>
<Style x:Name="CustomStyle" TargetType="chart:Bar">
    <Setter Property
="Template">
        <Setter
.Value>
        <ControlTemplate TargetType
="chart:Bar">
        <Grid
>
            <Rectangle x
:Name="PART_DefiningGeometry" 
               RadiusX
="5" 
               RadiusY
="5" 
               StrokeThickness
="2"
               Fill
="{Binding DataItem.GradeColor}" />
            <chart
:SeriesItemLabel x:Name="PART_SeriesItemLabel"
               HorizontalAlignment
="Center"
               Content
="{TemplateBinding SeriesItemLabelText}"
               Visibility
="{TemplateBinding SeriesItemLabelVisibility}" />
            <Grid
.RenderTransform>
                <ScaleTransform x
:Name="PART_AnimationTransform" ScaleY="0" />
            <
/Grid.RenderTransform>
            <Grid
.Triggers>
                <EventTrigger RoutedEvent
="Rectangle.Loaded">
                    <EventTrigger
.Actions>
                        <BeginStoryboard
>
                            <Storyboard 
                                x
:Name="PART_Storyboard"
                                BeginTime
="00:00:00.5">
                                <DoubleAnimation 
                                    To
="1" 
                                    Storyboard
.TargetName="PART_AnimationTransform" 
                                    Storyboard
.TargetProperty="ScaleY"
                                    Duration
="00:00:00.25"
                                    BeginTime
="00:00:00.2">
                                <
/DoubleAnimation>
                            <
/Storyboard>
                        <
/BeginStoryboard>
                    <
/EventTrigger.Actions>
                <
/EventTrigger>
            <
/Grid.Triggers>
        <
/Grid>
        <
/ControlTemplate>
        <
/Setter.Value>
    <
/Setter>
</
Style>
</Grid.Resources>
<control:RadChart x:Name="RadChart1">
</control:RadChart>

 

Now databind the chart to the StudentViewModel datasource and do not forget to set the DefaultSeriesDefinition.ItemStyle property to the custom style defined in XAML:

C#

private void ExampleLoaded(object sender, System.Windows.RoutedEventArgs e)
{
   
List<Student> studentList = new List<Student>();
   
studentList.Add(new Student("Ivan Ivanov", new SolidColorBrush(Colors.Red), 30d));
   
studentList.Add(new Student("Peter Petrov", new SolidColorBrush(Colors.Green), 50d));
   
studentList.Add(new Student("Georgi Georgiev", new SolidColorBrush(Colors.Blue), 85d));
   
studentList.Add(new Student("Anton Antonov", new SolidColorBrush(Colors.DarkGray), 82d));
   
studentList.Add(new Student("Yordan Yordanov", new SolidColorBrush(Colors.Orange), 43d));

   
List<StudentViewModel> modelList = new List<StudentViewModel>();
   
foreach (Student student in studentList)
       
modelList.Add(new StudentViewModel(student));

   
RadChart1.DefaultSeriesDefinition = new BarSeriesDefinition() { ItemStyle = this.CustomStyle };

   
SeriesMapping seriesMapping = new SeriesMapping();
   
seriesMapping.ItemMappings.Add(new ItemMapping("Student.Grade", DataPointMember.YValue));
   
RadChart1.SeriesMappings.Add(seriesMapping);
   
RadChart1.ItemsSource = modelList;
}
 
 
Here is the result:
 
favoriteColor gradeColor

About the Author

Vladimir Milev

Vladimir Milev is a developer manager.

Comments

Comments are disabled in preview mode.