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) });
}
}
}
Public Class MyDateObject
Public Property Value1() As Double
Public Property Value2() As Double
Public Property Value3() As Double
Public Property Date As Date
End Class
Public Class MyDataContext
Public Const min As Integer = 21
Public Const max As Integer = 79
Public Property List() As ObservableCollection(Of MyDateObject)
Private r As New Random()
Private baseDate As Date = Date.Today
Public Sub New()
Me.CreateChartData()
End Sub
Private Sub CreateChartData()
List = New ObservableCollection(Of MyDateObject)()
For i As Integer = 0 To 14
List.Add(New MyDateObject() With {.Value1 = r.Next(min, max), .Value2 = r.Next(min, max), .Value3 = r.Next(min, max), .Date = baseDate.AddDays(i)})
Next i
End Sub
End Class
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);
}
Dim chartFilterDescriptorCol As New CompositeFilterDescriptor()
Private Sub GridView1_Filtered(ByVal sender As Object, ByVal e As Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs)
If e.Added.Count() > 0 Then
For Each filter As FilterDescriptor In e.Added
Dim gridFilterDescriptor As FilterDescriptor = filter
chartFilterDescriptorCol.FilterDescriptors.Add(gridFilterDescriptor)
chartFilterDescriptorCol.LogicalOperator = FilterCompositionLogicalOperator.Or
Next filter
End If
Me.RadChart1.FilterDescriptors.Add(chartFilterDescriptorCol)
End Sub
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) });
}
}
}
Imports Microsoft.VisualBasic
Private chartFilterDescriptorCol As New CompositeFilterDescriptor()
public MainPage()
Public Sub New()
InitializeComponent()
RadChart1.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "ddd" & vbLf & "dd.MM"
Dim context As New MyDataContext()
Me.DataContext = context
End Sub
Private Sub GridView1_Filtered(ByVal sender As Object, ByVal e As Telerik.Windows.Controls.GridView.GridViewFilteredEventArgs)
If e.Added.Count() > 0 Then
For Each filter As FilterDescriptor In e.Added
Dim gridFilterDescriptor As FilterDescriptor = filter
chartFilterDescriptorCol.FilterDescriptors.Add(gridFilterDescriptor)
chartFilterDescriptorCol.LogicalOperator = FilterCompositionLogicalOperator.Or
Next filter
End If
Me.RadChart1.FilterDescriptors.Add(chartFilterDescriptorCol)
End Sub
}
Public Class MyDateObject
Public Property Value1() As Double
Public Property Value2() As Double
Public Property Value3() As Double
Public Property Date As Date
End Class
Public Class MyDataContext
Public Const min As Integer = 21
Public Const max As Integer = 79
Public Property List() As ObservableCollection(Of MyDateObject)
Private r As New Random()
Private baseDate As Date = Date.Today
Public Sub New()
Me.CreateChartData()
End Sub
Private Sub CreateChartData()
List = New ObservableCollection(Of MyDateObject)()
For i As Integer = 0 To 14
List.Add(New MyDateObject() With {.Value1 = r.Next(min, max), .Value2 = r.Next(min, max), .Value3 = r.Next(min, max), .Date = baseDate.AddDays(i)})
Next i
End Sub
End Class
The 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: