wpf-116571-controls-and-libraries-charts-suite-chart-control-filter-chart-data.md
This document describes how to filter chart data at the chart control level, and create a filter UI.
Note
If you use large data sources and users should not change filtering and sorting parameters, we recommend that you filter and sort your data source at the data source level before it is visualized.
The Series.FilterString property defines an expression used to filter series data. Use Criteria Language Syntax to create the filter expression.
The following example displays only data points whose ProductCategory is Automation:
<dxc:ChartControl x:Name="chart">
<dxc:XYDiagram2D>
<dxc:BarSideBySideSeries2D DisplayName="Sales"
x:Name="series"
DataSource="{DXBinding 'new $local:DevAVSales().GetSalesByRegion()'}"
ArgumentDataMember="Region"
ValueDataMember="Sales"
FilterString="[ProductCategory]='Automation'"
LabelsVisibility="True"/>
<dxc:XYDiagram2D.AxisX>
<dxc:AxisX2D TickmarksMinorVisible="False">
<dxc:AxisX2D.QualitativeScaleOptions>
<dxc:QualitativeScaleOptions GridLayoutMode="GridShiftedLabelCentered"/>
</dxc:AxisX2D.QualitativeScaleOptions>
</dxc:AxisX2D>
</dxc:XYDiagram2D.AxisX>
</dxc:XYDiagram2D>
</dxc:ChartControl>
Code-Behind (a data source):
Show code
using System.Data;
using System.Windows;
namespace FilterStringExample {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
}
public class DevAVSales {
public DataTable GetSalesByRegion() {
DataTable table = new DataTable();
table.Columns.AddRange(new DataColumn[] { new DataColumn("ProductCategory", typeof(string)),
new DataColumn("Region", typeof(string)),
new DataColumn("Sales", typeof(decimal)) });
table.Rows.Add("Video players", "Asia", 853D);
table.Rows.Add("Video players", "Australia", 321D);
table.Rows.Add("Video players", "Europe", 655D);
table.Rows.Add("Video players", "North America", 1325D);
table.Rows.Add("Video players", "South America", 653D);
table.Rows.Add("Automation", "Asia", 172D);
table.Rows.Add("Automation", "Australia", 255D);
table.Rows.Add("Automation", "Europe", 981D);
table.Rows.Add("Automation", "North America", 963D);
table.Rows.Add("Automation", "South America", 123D);
table.Rows.Add("Monitors", "Asia", 1011D);
table.Rows.Add("Monitors", "Australia", 359D);
table.Rows.Add("Monitors", "Europe", 721D);
table.Rows.Add("Monitors", "North America", 565D);
table.Rows.Add("Monitors", "South America", 532D);
table.Rows.Add("Projectors", "Asia", 998D);
table.Rows.Add("Projectors", "Australia", 222D);
table.Rows.Add("Projectors", "Europe", 865D);
table.Rows.Add("Projectors", "North America", 787D);
table.Rows.Add("Projectors", "South America", 332D);
table.Rows.Add("Televisions", "Asia", 1356D);
table.Rows.Add("Televisions", "Australia", 232D);
table.Rows.Add("Televisions", "Europe", 1323D);
table.Rows.Add("Televisions", "North America", 1125D);
table.Rows.Add("Televisions", "South America", 865D);
return table;
}
}
}
Imports System.Data
Imports System.Windows
Namespace FilterStringExample
Public Partial Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
End Sub
End Class
Public Class DevAVSales
Public Function GetSalesByRegion() As DataTable
Dim table As DataTable = New DataTable()
table.Columns.AddRange(New DataColumn() {New DataColumn("ProductCategory", GetType(String)), New DataColumn("Region", GetType(String)), New DataColumn("Sales", GetType(Decimal))})
table.Rows.Add("Video players", "Asia", 853R)
table.Rows.Add("Video players", "Australia", 321R)
table.Rows.Add("Video players", "Europe", 655R)
table.Rows.Add("Video players", "North America", 1325R)
table.Rows.Add("Video players", "South America", 653R)
table.Rows.Add("Automation", "Asia", 172R)
table.Rows.Add("Automation", "Australia", 255R)
table.Rows.Add("Automation", "Europe", 981R)
table.Rows.Add("Automation", "North America", 963R)
table.Rows.Add("Automation", "South America", 123R)
table.Rows.Add("Monitors", "Asia", 1011R)
table.Rows.Add("Monitors", "Australia", 359R)
table.Rows.Add("Monitors", "Europe", 721R)
table.Rows.Add("Monitors", "North America", 565R)
table.Rows.Add("Monitors", "South America", 532R)
table.Rows.Add("Projectors", "Asia", 998R)
table.Rows.Add("Projectors", "Australia", 222R)
table.Rows.Add("Projectors", "Europe", 865R)
table.Rows.Add("Projectors", "North America", 787R)
table.Rows.Add("Projectors", "South America", 332R)
table.Rows.Add("Televisions", "Asia", 1356R)
table.Rows.Add("Televisions", "Australia", 232R)
table.Rows.Add("Televisions", "Europe", 1323R)
table.Rows.Add("Televisions", "North America", 1125R)
table.Rows.Add("Televisions", "South America", 865R)
Return table
End Function
End Class
End Namespace
You can use the following code to set the FilterString property at runtime:
series.FilterString = "[ProductCategory]='Automation'";
series.FilterString = "[ProductCategory]='Automation'"
You can use the Series.FilterCriteria property instead of Series.FilterString to build and pass a filter expression. Use Criteria Operators to construct the filter expression.
Use CriteriaOperator‘s descendants to specify the FilterCriteria property. Refer to Criteria Operators for more information.
<dxc:ChartControl x:Name="chart">
<dxc:XYDiagram2D>
<dxc:BarSideBySideSeries2D x:Name="series"
DisplayName="Sales"
DataSource="{DXBinding 'new $local:DevAVSales().GetSalesByRegion()'}"
ArgumentDataMember="Region"
ValueDataMember="Sales">
</dxc:BarSideBySideSeries2D>
</dxc:XYDiagram2D>
</dxc:ChartControl>
Code-Behind:
using DevExpress.Data.Filtering;
using DevExpress.Xpf.Charts;
using DevExpress.Xpf.Core;
using System.Data;
using System.Windows;
namespace FilterStringExample {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
series.FilterCriteria = new BinaryOperator("ProductCategory", "Automation", BinaryOperatorType.Equal);
}
}
public class DevAVSales {
public DataTable GetSalesByRegion() {
DataTable table = new DataTable();
table.Columns.AddRange(new DataColumn[] { new DataColumn("ProductCategory", typeof(string)),
new DataColumn("Region", typeof(string)),
new DataColumn("Sales", typeof(decimal)) });
table.Rows.Add("Video players", "Asia", 853D);
table.Rows.Add("Video players", "Australia", 321D);
table.Rows.Add("Video players", "Europe", 655D);
table.Rows.Add("Video players", "North America", 1325D);
table.Rows.Add("Video players", "South America", 653D);
table.Rows.Add("Automation", "Asia", 172D);
table.Rows.Add("Automation", "Australia", 255D);
table.Rows.Add("Automation", "Europe", 981D);
table.Rows.Add("Automation", "North America", 963D);
table.Rows.Add("Automation", "South America", 123D);
table.Rows.Add("Monitors", "Asia", 1011D);
table.Rows.Add("Monitors", "Australia", 359D);
table.Rows.Add("Monitors", "Europe", 721D);
table.Rows.Add("Monitors", "North America", 565D);
table.Rows.Add("Monitors", "South America", 532D);
table.Rows.Add("Projectors", "Asia", 998D);
table.Rows.Add("Projectors", "Australia", 222D);
table.Rows.Add("Projectors", "Europe", 865D);
table.Rows.Add("Projectors", "North America", 787D);
table.Rows.Add("Projectors", "South America", 332D);
table.Rows.Add("Televisions", "Asia", 1356D);
table.Rows.Add("Televisions", "Australia", 232D);
table.Rows.Add("Televisions", "Europe", 1323D);
table.Rows.Add("Televisions", "North America", 1125D);
table.Rows.Add("Televisions", "South America", 865D);
return table;
}
}
}
Imports DevExpress.Data.Filtering
Imports DevExpress.Xpf.Charts
Imports DevExpress.Xpf.Core
Imports System.Data
Namespace FilterStringExample
Public Partial Class MainWindow
Inherits Window
Public Sub New()
InitializeComponent()
series.FilterCriteria = New BinaryOperator("ProductCategory", "Automation", BinaryOperatorType.Equal)
End Sub
End Class
Public Class DevAVSales
Public Function GetSalesByRegion() As DataTable
Dim table As DataTable = New DataTable()
table.Columns.AddRange(New DataColumn() {New DataColumn("ProductCategory", GetType(String)), New DataColumn("Region", GetType(String)), New DataColumn("Sales", GetType(Decimal))})
table.Rows.Add("Video players", "Asia", 853R)
table.Rows.Add("Video players", "Australia", 321R)
table.Rows.Add("Video players", "Europe", 655R)
table.Rows.Add("Video players", "North America", 1325R)
table.Rows.Add("Video players", "South America", 653R)
table.Rows.Add("Automation", "Asia", 172R)
table.Rows.Add("Automation", "Australia", 255R)
table.Rows.Add("Automation", "Europe", 981R)
table.Rows.Add("Automation", "North America", 963R)
table.Rows.Add("Automation", "South America", 123R)
table.Rows.Add("Monitors", "Asia", 1011R)
table.Rows.Add("Monitors", "Australia", 359R)
table.Rows.Add("Monitors", "Europe", 721R)
table.Rows.Add("Monitors", "North America", 565R)
table.Rows.Add("Monitors", "South America", 532R)
table.Rows.Add("Projectors", "Asia", 998R)
table.Rows.Add("Projectors", "Australia", 222R)
table.Rows.Add("Projectors", "Europe", 865R)
table.Rows.Add("Projectors", "North America", 787R)
table.Rows.Add("Projectors", "South America", 332R)
table.Rows.Add("Televisions", "Asia", 1356R)
table.Rows.Add("Televisions", "Australia", 232R)
table.Rows.Add("Televisions", "Europe", 1323R)
table.Rows.Add("Televisions", "North America", 1125R)
table.Rows.Add("Televisions", "South America", 865R)
Return table
End Function
End Class
End Namespace
Call the CriteriaOperator.Parse method to convert a filter string to its CriteriaOperator equivalent as follows:
series.FilterCriteria = CriteriaOperator.Parse("[ProductCategory] = 'Automation'");
series.FilterCriteria = CriteriaOperator.Parse("[ProductCategory] = 'Automation'")
A series contains only filtered points after a filter is applied to the series. Handle the ChartControl.BoundDataChanged event to access the chart diagram’s series collection.
<dxc:ChartControl x:Name="chart" BoundDataChanged="chart_BoundDataChanged">
using DevExpress.Xpf.Charts;
private void chart_BoundDataChanged(object sender, RoutedEventArgs e) {
SeriesPointCollection filteredPoints = chart.Diagram.Series[0].Points;
}
Imports DevExpress.Xpf.Charts
Private Sub chart_BoundDataChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim filteredPoints As SeriesPointCollection = chart.Diagram.Series(0).Points
End Sub
The following example shows how to use FilterBehavior and AccordionControl to create a UI that allows you to filter chart series data. To apply a filter, bind a series’ Series.FilterCriteria to the FilterBehavior.ActualFilterCriteria property value.
<dx:ThemedWindow xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
<!-- ... -->
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:dxfui="http://schemas.devexpress.com/winfx/2008/xaml/core/filteringui"
xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts"
xmlns:dxa="http://schemas.devexpress.com/winfx/2008/xaml/accordion"
<!-- ... -->
<dxc:ChartControl Grid.Column="0" DataSource="{Binding GdpValues}" x:Name="chart">
<!-- ... -->
<dxc:XYDiagram2D SeriesDataMember="CountryName" >
<dxc:XYDiagram2D.SeriesTemplate>
<dxc:BarSideBySideSeries2D ArgumentDataMember="Year" ValueDataMember="Value"
FilterCriteria="{Binding ElementName=filterBehavior, Path=ActualFilterCriteria}"/>
</dxc:XYDiagram2D.SeriesTemplate>
<!-- ... -->
</dxc:XYDiagram2D>
</dxc:ChartControl>
<dxa:AccordionControl Grid.Column="1" x:Name="accordion">
<dxmvvm:Interaction.Behaviors>
<dxfui:FilterBehavior x:Name="filterBehavior" ItemsSource="{Binding ElementName=chart, Path=DataSource}" />
</dxmvvm:Interaction.Behaviors>
<dxa:AccordionItem Header="Continent" IsExpanded="True">
<dxfui:CheckedListFilterElement FieldName="ContinentName"
ShowCounts="False"/>
</dxa:AccordionItem>
<dxa:AccordionItem Header="Country" IsExpanded="True">
<dxfui:CheckedListFilterElement FieldName="CountryName"
Height="200"
ShowCounts="False"/>
</dxa:AccordionItem>
<dxa:AccordionItem Header="Year" IsExpanded="True">
<dxfui:RangeFilterElement FieldName="Year"/>
</dxa:AccordionItem>
<dxa:AccordionItem Header="Value" IsExpanded="True">
<dxfui:RangeFilterElement FieldName="Value"/>
</dxa:AccordionItem>
</dxa:AccordionControl>
</Grid>
</dx:ThemedWindow>
using DevExpress.Xpf.Core;
// ...
public class MainViewModel {
public IEnumerable<GdpValue> GdpValues { get; private set; }
public MainViewModel(XmlGdpValueProvider valueProvider) {
GdpValues = valueProvider.GetValues();
}
}
// ...
public class GdpValue {
public string ContinentName { get; set; }
public string CountryName { get; set; }
public double Value { get; set; }
public int Year { get; set; }
}
Imports DevExpress.Xpf.Core
' ...
Public Sub New()
Me.InitializeComponent()
Dim dataStreamInfo As System.Windows.Resources.StreamResourceInfo = System.Windows.Application.GetResourceStream(New System.Uri("Data/GDPStatistic.xml", System.UriKind.RelativeOrAbsolute))
Dim valueProvider As ChartFiltering.XmlGdpValueProvider = New ChartFiltering.XmlGdpValueProvider(dataStreamInfo.Stream)
Me.DataContext = New ChartFiltering.MainViewModel(valueProvider)
End Sub
' ...
Public Class GdpValue
Public Property ContinentName As String
Public Property CountryName As String
Public Property Value As Double
Public Property Year As Integer
End Class
Refer to the following section for more information: FilterBehavior - Filter Elements and ChartControl.
See Also