Filter RadChart Using The GridView's CompositeFilterDescriptor
The RadChart allows you to programmatically filter its data as demonstrated in our help topic. However there are scenarios where you would like to have more complex filtering like the one presented by the GridView's ComplexFilterDescriptor object. It contains a collection of filter descriptors objects and the logical operator for that filters.
This help topic will demonstrate how to create a GridView and draw a Chart with the filtered data from the GridView.
1. Create a List of Business objects that will be used to populate the Chart and the GridView.
public class MyDateObject
{
public double Value1 { get; set; }
public double Value2 { get; set; }
public double Value3 { get; set; }
public DateTime Date { get; set; }
}
public class MyDataContext
{
public const int min = 21;
public const int max = 79;
public ObservableCollection<MyDateObject> List { get; set; }
Random r = new Random();
DateTime baseDate = DateTime.Today;
public MyDataContext()
{
this.CreateChartData();
}
private void CreateChartData()
{
List = new ObservableCollection<MyDateObject>();
for (int i = 0; i < 15; i++)
{
List.Add(new MyDateObject() { Value1 = r.Next(min, max), Value2 = r.Next(min, max), Value3 = r.Next(min, max), Date = baseDate.AddDays(i) });
}
}
}2. Create the GridView and the Chart in XAML:
<telerik:RadChart x:Name="RadChart1" ItemsSource="{Binding List}">
<telerik:RadChart.SeriesMappings>
<telerik:SeriesMapping LegendLabel="Lee Young">
<telerik:SeriesMapping.SeriesDefinition>
<telerik:BarSeriesDefinition/>
</telerik:SeriesMapping.SeriesDefinition>
<telerik:ItemMapping FieldName="Value1" DataPointMember="YValue"></telerik:ItemMapping>
<telerik:ItemMapping FieldName="Date" DataPointMember="XCategory"></telerik:ItemMapping>
</telerik:SeriesMapping>
<telerik:SeriesMapping LegendLabel="Linda Baker">
<telerik:SeriesMapping.SeriesDefinition>
<telerik:BarSeriesDefinition />
</telerik:SeriesMapping.SeriesDefinition>
<telerik:ItemMapping FieldName="Value2" DataPointMember="YValue"></telerik:ItemMapping>
<telerik:ItemMapping FieldName="Date" DataPointMember="XCategory"></telerik:ItemMapping>
</telerik:SeriesMapping>
<telerik:SeriesMapping LegendLabel="Martin Thompson">
<telerik:SeriesMapping.SeriesDefinition>
<telerik:BarSeriesDefinition />
</telerik:SeriesMapping.SeriesDefinition>
<telerik:ItemMapping FieldName="Value3" DataPointMember="YValue"></telerik:ItemMapping>
<telerik:ItemMapping FieldName="Date" DataPointMember="XCategory"></telerik:ItemMapping>
</telerik:SeriesMapping>
</telerik:RadChart.SeriesMappings>
<telerik:RadChart.DefaultView>
<telerik:ChartDefaultView ChartLegendPosition="Bottom">
<telerik:ChartDefaultView.ChartLegend>
<telerik:ChartLegend x:Name="legend" Visibility="Collapsed" />
</telerik:ChartDefaultView.ChartLegend>
<telerik:ChartDefaultView.ChartTitle>
<telerik:ChartTitle Content="Employee Productivity" HorizontalContentAlignment="Left"/>
</telerik:ChartDefaultView.ChartTitle>
<telerik:ChartDefaultView.ChartArea>
<telerik:ChartArea LegendName="legend" Padding="5,10,20,5">
<telerik:ChartArea.AxisY>
<telerik:AxisY ExtendDirection="None" />
</telerik:ChartArea.AxisY>
</telerik:ChartArea>
</telerik:ChartDefaultView.ChartArea>
</telerik:ChartDefaultView>
</telerik:RadChart.DefaultView>
</telerik:RadChart>
<telerik:RadGridView AutoGenerateColumns="True" Filtered="GridView1_Filtered" ItemsSource="{Binding List}"
Grid.Row="1"
Name="GridView1"
BorderThickness="0"
CanUserSortColumns="False"
IsFilteringAllowed="True"
ShowGroupPanel="False"
CanUserSelect="False"
RowIndicatorVisibility="Collapsed">
</telerik:RadGridView>
The Chart has 3 Bar Series and is populated using Manual Series Mappings. On the other side the GridView is bound by the ItemsSource property. Several properties are turned off so that we gain the needed filtering functionality only and nothing more (no grouping, selecting or sorting).
Note the Filtered event in the GridView's declaration:
CompositeFilterDescriptor chartFilterDescriptorCol = new CompositeFilterDescriptor();
private void GridView1_Filtered(object sender, Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs e)
{
if (e.Added.Count() > 0)
{
foreach (FilterDescriptor filter in e.Added)
{
FilterDescriptor gridFilterDescriptor = filter;
chartFilterDescriptorCol.FilterDescriptors.Add(gridFilterDescriptor);
chartFilterDescriptorCol.LogicalOperator = FilterCompositionLogicalOperator.Or;
}
}
this.RadChart1.FilterDescriptors.Add(chartFilterDescriptorCol);
}The RadChart's FilterDescriptors collection is populated with GridView's CompositeFilterDescriptor as shown above. The LogicalOperator chosen is "Or".
The full source code for the sample can be found here:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<telerik:RadChart x:Name="RadChart1" ItemsSource="{Binding List}">
<telerik:RadChart.SeriesMappings>
<telerik:SeriesMapping LegendLabel="Lee Young">
<telerik:SeriesMapping.SeriesDefinition>
<telerik:BarSeriesDefinition/>
</telerik:SeriesMapping.SeriesDefinition>
<telerik:ItemMapping FieldName="Value1" DataPointMember="YValue"></telerik:ItemMapping>
<telerik:ItemMapping FieldName="Date" DataPointMember="XCategory"></telerik:ItemMapping>
</telerik:SeriesMapping>
<telerik:SeriesMapping LegendLabel="Linda Baker">
<telerik:SeriesMapping.SeriesDefinition>
<telerik:BarSeriesDefinition />
</telerik:SeriesMapping.SeriesDefinition>
<telerik:ItemMapping FieldName="Value2" DataPointMember="YValue"></telerik:ItemMapping>
<telerik:ItemMapping FieldName="Date" DataPointMember="XCategory"></telerik:ItemMapping>
</telerik:SeriesMapping>
<telerik:SeriesMapping LegendLabel="Martin Thompson">
<telerik:SeriesMapping.SeriesDefinition>
<telerik:BarSeriesDefinition />
</telerik:SeriesMapping.SeriesDefinition>
<telerik:ItemMapping FieldName="Value3" DataPointMember="YValue"></telerik:ItemMapping>
<telerik:ItemMapping FieldName="Date" DataPointMember="XCategory"></telerik:ItemMapping>
</telerik:SeriesMapping>
</telerik:RadChart.SeriesMappings>
<telerik:RadChart.DefaultView>
<telerik:ChartDefaultView ChartLegendPosition="Bottom">
<telerik:ChartDefaultView.ChartLegend>
<telerik:ChartLegend x:Name="legend" Visibility="Collapsed" />
</telerik:ChartDefaultView.ChartLegend>
<telerik:ChartDefaultView.ChartTitle>
<telerik:ChartTitle Content="Employee Productivity" HorizontalContentAlignment="Left"/>
</telerik:ChartDefaultView.ChartTitle>
<telerik:ChartDefaultView.ChartArea>
<telerik:ChartArea LegendName="legend" Padding="5,10,20,5">
<telerik:ChartArea.AxisY>
<telerik:AxisY ExtendDirection="None" />
</telerik:ChartArea.AxisY>
</telerik:ChartArea>
</telerik:ChartDefaultView.ChartArea>
</telerik:ChartDefaultView>
</telerik:RadChart.DefaultView>
</telerik:RadChart>
<telerik:RadGridView AutoGenerateColumns="True" Filtered="GridView1_Filtered" ItemsSource="{Binding List}"
Grid.Row="1"
Name="GridView1"
BorderThickness="0"
CanUserSortColumns="False"
IsFilteringAllowed="True"
ShowGroupPanel="False"
CanUserSelect="False"
RowIndicatorVisibility="Collapsed">
</telerik:RadGridView>
</Grid>
The code-behind:
CompositeFilterDescriptor chartFilterDescriptorCol = new CompositeFilterDescriptor();
public MainPage()
{
InitializeComponent();
RadChart1.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "ddd\ndd.MM";
MyDataContext context = new MyDataContext();
this.DataContext = context;
}
private void GridView1_Filtered(object sender, Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs e)
{
if (e.Added.Count() > 0)
{
foreach (FilterDescriptor filter in e.Added)
{
FilterDescriptor gridFilterDescriptor = filter;
chartFilterDescriptorCol.FilterDescriptors.Add(gridFilterDescriptor);
chartFilterDescriptorCol.LogicalOperator = FilterCompositionLogicalOperator.Or;
}
}
this.RadChart1.FilterDescriptors.Add(chartFilterDescriptorCol);
}
}
public class MyDateObject
{
public double Value1 { get; set; }
public double Value2 { get; set; }
public double Value3 { get; set; }
public DateTime Date { get; set; }
}
public class MyDataContext
{
public const int min = 21;
public const int max = 79;
public ObservableCollection<MyDateObject> List { get; set; }
Random r = new Random();
DateTime baseDate = DateTime.Today;
public MyDataContext()
{
this.CreateChartData();
}
private void CreateChartData()
{
List = new ObservableCollection<MyDateObject>();
for (int i = 0; i < 15; i++)
{
List.Add(new MyDateObject() { Value1 = r.Next(min, max), Value2 = r.Next(min, max), Value3 = r.Next(min, max), Date = baseDate.AddDays(i) });
}
}
}he code snippets above were taken from a Silverlight project but are absolutely applicable for WPF scenarios.
The bound non-filtered data looks like this:

Filter the data by Value1 column:

The filtered data:
