HierarchicalDataAdapter Class
Namespace: DevExpress.Xpf.Charts
Assembly:
DevExpress.Xpf.Charts.v24.1.dll
NuGet Package:
DevExpress.Wpf.Charts
Declaration
public class HierarchicalDataAdapter :
HierarchicalDataAdapterBase
Public Class HierarchicalDataAdapter
Inherits HierarchicalDataAdapterBase
Example
This example demonstrates how to enable the Chart’s Drill Mode that allows end users to navigate between different detail levels:
public interface INameable {
string Name { get; }
}
public sealed class DevAVBranch: INameable {
public string Name { get; set; }
public List<DevAVProductCategory> Categories { get; set; }
public double TotalIncome { get => Categories.Sum(c => c.TotalIncome); }
}
public sealed class DevAVProductCategory: INameable {
public string Name { get; set; }
public List<DevAVProduct> Products { get; set; }
public double TotalIncome { get => Products.Sum(p => p.TotalIncome); }
}
public sealed class DevAVProduct: INameable {
public string Name { get; set; }
public List<DevAVMonthlyIncome> Sales { get; set; }
public double TotalIncome { get => Sales.Sum(s => s.Income); }
}
public class DevAVMonthlyIncome {
public DateTime Month { get; set; }
public double Income { get; set; }
}
Public Interface INameable
ReadOnly Property Name As String
End Interface
Public Class DevAVBranch
Implements INameable
Public Property Name As String Implements INameable.Name
Public Property Categories As List(Of DevAVProductCategory)
Public ReadOnly Property TotalIncome As Double
Get
Return Categories.Sum(Function(c) c.TotalIncome)
End Get
End Property
End Class
Public Class DevAVProductCategory
Implements INameable
Public Property Name As String Implements INameable.Name
Public Property Products As List(Of DevAVProduct)
Public ReadOnly Property TotalIncome As Double
Get
Return Products.Sum(Function(p) p.TotalIncome)
End Get
End Property
End Class
Public Class DevAVProduct
Implements INameable
Public Property Name As String Implements INameable.Name
Public Property Sales As List(Of DevAVMonthlyIncome)
Public ReadOnly Property TotalIncome As Double
Get
Return Sales.Sum(Function(s) s.Income)
End Get
End Property
End Class
Public Class DevAVMonthlyIncome
Public Property Month As DateTime
Public Property Income As Double
End Class
class MainViewModel {
public IReadOnlyList<DevAVBranch> Branches { get; }
public MainViewModel() {
Branches = new BranchDAO().GetBranches();
}
}
Class MainViewModel
Private _branches As IReadOnlyList(Of DevAVBranch)
Public ReadOnly Property Branches As IReadOnlyList(Of DevAVBranch)
Get
Return _branches
End Get
End Property
Public Sub New()
_branches = new BranchDAO().GetBranches();
End Sub
End Class
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<!-- Other resources are here. -->
<local:DevAVSeriesTemplateSelector
x:Key="seriesTemplateSelector"
AllCategoriesTemplate="{StaticResource stackedBarTemplate}"
BranchCategoriesTemplate="{StaticResource barTemplate}"
CategoryProductsTemplate="{StaticResource stackedSplineAreaTemplate}"
ProductTemplate="{StaticResource splineTemplate}">
</local:DevAVSeriesTemplateSelector>
<local:DevAVSeriesChildrenSelector x:Key="childrenSelector"/>
<local:DevAVBreadcrumbTextProvider x:Key="textProvider"/>
<Window.Resources>
<dxc:ChartControl>
<dxc:XYDiagram2D
x:Name="diagram"
SeriesItemTemplateSelector="{StaticResource seriesTemplateSelector}"
DrillDownStateChanged="XYDiagram2D_DrillDownStateChanged">
<dxc:XYDiagram.SeriesItemsSource>
<dxc:HierarchicalDataAdapter
DataSource="{Binding Branches}"
ChildrenSelector="{StaticResource childrenSelector}"
BreadcrumbTextProvider="{StaticResource textProvider}"/>
</dxc:XYDiagram.SeriesItemsSource>
</dxc:XYDiagram2D>
<!-- Other Chart Settings.-->
</dxc:ChartControl>
class MainWindow: Window {
public MainWindow() {
InitializeComponent()
}
private void OnDrillDownStateChanged(object sender, DrillDownStateChangedEventArgs e) {
diagram.Rotated = e.BreadcrumbItems.Last().IsHome;
}
}
private void OnDrillDownStateChanged(object sender, DrillDownStateChangedEventArgs e) {
diagram.Rotated = e.BreadcrumbItems.Last().IsHome;
}
class DevAVSeriesChildrenSelector : IChildrenSelector {
public IEnumerable SelectChildren(object item) {
if (item as DevAVBranch branch) return new List<DevAVBranch> { branch };
if (item as DevAVProductCategory category) return category.Products;
if (item as DevAVProduct product) return new List<DevAVProduct> { product };
return null;
}
}
class DevAVSeriesTemplateSelector : DataTemplateSelector {
public DataTemplate AllCategoriesTemplate { get; set; }
public DataTemplate BranchCategoriesTemplate { get; set; }
public DataTemplate CategoryProductsTemplate { get; set; }
public DataTemplate ProductTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container) {
Diagram diagram = (Diagram)container;
if (item is DevAVBranch && diagram.BreadcrumbItems.Count == 1)
return AllCategoriesTemplate;
if (item is DevAVBranch)
return BranchCategoriesTemplate;
if (item is DevAVProduct && diagram.BreadcrumbItems[diagram.BreadcrumbItems.Count - 1].SourceObject is DevAVProduct)
return ProductTemplate;
if (item is DevAVProduct)
return CategoryProductsTemplate;
return null;
}
}
class DevAVBreadcrumbTextProvider : IBreadcrumbTextProvider {
public string GetText(object seriesSourceObj, object pointSourceObj) {
StringBuilder sb = new StringBuilder("(");
if (seriesSourceObj != null) sb.Append(GetName(seriesSourceObj));
if (seriesSourceObj != null && pointSourceObj != null) sb.Append(", ");
if (pointSourceObj != null) sb.Append(GetName(pointSourceObj));
sb.Append(")");
return sb.ToString();
}
private string GetName(object obj) {
if (obj is INameable nameable) return nameable.Name;
return String.Empty;
}
}
Public Class MainWindow
Private Sub Diagram_DrillDownStateChanged(sender As Object, e As DrillDownStateChangedEventArgs)
diagram.Rotated = e.BreadcrumbItems.Last().IsHome
End Sub
End Class
Public Class DevAVSeriesChildrenSelector
Implements IChildrenSelector
Public Function SelectChildren(item As Object) As IEnumerable Implements IChildrenSelector.SelectChildren
Dim branch = TryCast(item, DevAVBranch)
If (branch IsNot Nothing) Then Return New List(Of DevAVBranch) From { branch }
Dim category = TryCast(item, DevAVProductCategory)
If (category IsNot Nothing) Then Return category.Products
Dim product = TryCast(item, DevAVProduct)
If (product IsNot Nothing) Then Return New List(Of DevAVProduct) From { product }
Return Nothing
End Function
End Class
Class DevAVSeriesTemplateSelector
Inherits DataTemplateSelector
Public Property AllCategoriesTemplate As DataTemplate
Public Property BranchCategoriesTemplate As DataTemplate
Public Property CategoryProductsTemplate As DataTemplate
Public Property ProductTemplate As DataTemplate
Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate
Dim diagram = CType(container, Diagram)
Dim branch = TryCast(item, DevAVBranch)
If (branch IsNot Nothing) And (diagram.BreadcrumbItems.Count = 1) Then Return AllCategoriesTemplate
If (branch IsNot Nothing) Then Return BranchCategoriesTemplate
Dim product = TryCast(item, DevAVProduct)
Dim lastLevelSourceProduct = TryCast(diagram.BreadcrumbItems(diagram.BreadcrumbItems.Count - 1).SourceObject, DevAVProduct)
If (product IsNot Nothing) And (lastLevelSourceProduct IsNot Nothing) Then Return ProductTemplate
If (product IsNot Nothing) Then Return CategoryProductsTemplate
Return Nothing
End Function
End Class
Public Class DevAVBreadcrumbTextProvider
Implements IBreadcrumbTextProvider
Public Function GetText(seriesSourceObj As Object, pointSourceObj As Object) As String Implements IBreadcrumbTextProvider.GetText
Dim sb = New StringBuilder("(")
If (seriesSourceObj IsNot Nothing) Then sb.Append(GetName(seriesSourceObj))
If (seriesSourceObj IsNot Nothing And pointSourceObj IsNot Nothing) Then sb.Append(", ")
If (pointSourceObj IsNot Nothing) Then sb.Append(GetName(pointSourceObj))
sb.Append(")")
Return sb.ToString()
End Function
Private Function GetName(obj As Object) As String
Dim nameable = TryCast(obj, INameable)
If (nameable IsNot Nothing) Then Return nameable.Name
Return String.Empty
End Function
End Class
The table below lists classes and properties the code above includes:
See Also