Back to Devexpress

How to: Provide a Custom Tooltip for a Series Point

wpf-11901-controls-and-libraries-charts-suite-chart-control-examples-appearance-customization-how-to-provide-a-custom-tooltip-for-a-series-point.md

latest14.6 KB
Original Source

How to: Provide a Custom Tooltip for a Series Point

  • Jun 07, 2019
  • 6 minutes to read

This example shows how to implement a custom tooltip that displays another chart with a GDP history for the selected country when hovering over a bar.

To accomplish this, it is necessary to create the DataTemplate object that specifies the custom tooltip appearance, and assign it to the Series.ToolTipPointTemplate property.

You also need to bind both charts to the GDP datasource and write the GetDataSource() and GetGDPs() methods. These methods allow you to get the GDP data from a datasource for each selected country to display it on a chart tooltip.

View Example

xaml
<Window x:Class="ToolTipPointTemplate.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts"
        Title="MainWindow" Height="500" Width="800" >
    <Grid>
        <dxc:ChartControl Name="chart" Width="758" Height="440"  
                          ToolTipEnabled="True" CrosshairEnabled="False">
            <dxc:ChartControl.ToolTipController>
                <dxc:ChartToolTipController ToolTipOpening="ChartToolTipController_ToolTipOpening" />
            </dxc:ChartControl.ToolTipController>
            <dxc:XYDiagram2D>
                <dxc:BarSideBySideSeries2D ColorEach="True" DisplayName="G8 GDP in 2010"
                                           ArgumentDataMember="CountryName"
                                           ValueDataMember="GDPin2010"                                              
                                           ValueScaleType="Numerical"
                                           ToolTipHintDataMember="ToolTipData">

                    <dxc:BarSideBySideSeries2D.ToolTipPointTemplate>
                        <DataTemplate>
                            <dxc:ChartControl Width="300" Height="150" EnableAnimation="True" 
                                              DataSource="{Binding Hint.GDPs}">
                                <dxc:XYDiagram2D>
                                    <dxc:LineSeries2D ArgumentDataMember="Year"
                                                      ValueDataMember="Product"
                                                      ArgumentScaleType="Numerical"
                                                      ValueScaleType="Numerical"
                                                      Brush="{Binding Hint.SeriesBrush}"
                                                      MarkerSize="5">
                                    </dxc:LineSeries2D>
                                    <dxc:XYDiagram2D.AxisX>
                                        <dxc:AxisX2D>
                                            <dxc:AxisX2D.Range>
                                                <dxc:AxisRange MinValue="2000" MaxValue="2011"/>
                                            </dxc:AxisX2D.Range>
                                        </dxc:AxisX2D>
                                    </dxc:XYDiagram2D.AxisX>
                                    <dxc:XYDiagram2D.AxisY>
                                        <dxc:AxisY2D MinorCount="1">
                                            <dxc:AxisY2D.Range >
                                                <dxc:AxisRange />
                                            </dxc:AxisY2D.Range>
                                        </dxc:AxisY2D>
                                    </dxc:XYDiagram2D.AxisY>
                                </dxc:XYDiagram2D>
                                <dxc:ChartControl.Titles>
                                    <dxc:Title Margin="0" Padding="0" Dock="Top" FontSize="14"
                                               HorizontalAlignment="Center" VerticalAlignment="Top" 
                                               Content="{Binding Hint.Title}" />
                                </dxc:ChartControl.Titles>
                            </dxc:ChartControl>
                        </DataTemplate>
                    </dxc:BarSideBySideSeries2D.ToolTipPointTemplate>
                </dxc:BarSideBySideSeries2D>
            </dxc:XYDiagram2D>
        </dxc:ChartControl>
    </Grid>
</Window>
csharp
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml.Linq;
using System.Windows.Resources;
using System.Globalization;

namespace ToolTipPointTemplate {

    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            chart.DataSource = GetDataSource();
        }
   List<G8Member> GetDataSource() {
            List<GDP> GDPs = GetGDPs();
            List<G8Member> countries = new List<G8Member>();
            const int yearsInDecade = 10;
            for (int countryCounter = 0; countryCounter < 8; countryCounter++) {
                List<GDP> countryGDPs = new List<GDP>();
                for (int countryValuesCounter = 0; countryValuesCounter < yearsInDecade; countryValuesCounter++) {
                    countryGDPs.Add(GDPs[countryCounter * yearsInDecade + countryValuesCounter]);
                }
                countries.Add(new G8Member(countryGDPs));
            }
            return countries;
        }

   List<GDP> GetGDPs() {
            XDocument document = DataLoader.LoadXmlFromResources("/Data/GDPofG8.xml");
            List<GDP> result = new List<GDP>();
            if (document != null) {
                foreach (XElement element in document.Element("G8GDPs").Elements()) {
                    string country = element.Element("Country").Value;
                    int year = int.Parse(element.Element("Year").Value);
                    decimal product = Convert.ToDecimal(element.Element("Product").Value, CultureInfo.InvariantCulture);
                    result.Add(new GDP(country, year, product));
                }
            }
            return result;
        }
        public static class DataLoader {
            public static XDocument LoadXmlFromResources(string fileName) {
                try {
                    fileName = "/ToolTipPointTemplate;component" + fileName;
                    Uri uri = new Uri(fileName, UriKind.RelativeOrAbsolute);
                    StreamResourceInfo info = Application.GetResourceStream(uri);
                    return XDocument.Load(info.Stream);
                }
                catch {
                    return null;
                }
            }
        }  

        private void ChartToolTipController_ToolTipOpening(object sender, DevExpress.Xpf.Charts.ChartToolTipEventArgs e) {
           ToolTipData toolTipData = e.Hint as ToolTipData;
           int colorNumber = e.Series.Points.IndexOf(e.SeriesPoint);
           Color seriesColor = e.ChartControl.Palette[colorNumber];
           toolTipData.SeriesBrush = new SolidColorBrush(seriesColor);
        }
    }

    public class GDP {
        public string Country { get; private set; }
        public int Year { get; private set; }
        public decimal Product { get; private set; }

        public GDP(string country, int year, decimal product) {
            Country = country;
            Year = year;
            Product = product;
        }
    }

    public class G8Member {
        public decimal GDPin2010 { get; private set; }
        public string CountryName { get; private set; }
        public ToolTipData ToolTipData { get; set; }

        public G8Member(List<GDP> GDPs) {
            ToolTipData = new ToolTipData(GDPs, GDPs[0].Country);
            CountryName = GDPs[0].Country;
            GDPin2010 = GDPs[9].Product;
        }
    }

    public class ToolTipData {
        public List<GDP> GDPs { get; private set; }
        public SolidColorBrush SeriesBrush { get; set; }
        public string Title { get; private set; }

        public ToolTipData(List<GDP> gdps, string countryName) {
            GDPs = gdps;
            Title = countryName + " GDP History";
        }
    }
}
vb
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Windows
Imports System.Windows.Documents
Imports System.Windows.Media
Imports System.Xml.Linq
Imports System.Windows.Resources
Imports System.Globalization

Namespace ToolTipPointTemplate

    Partial Public Class MainWindow
        Inherits Window
        Public Sub New()
            InitializeComponent()
            chart.DataSource = GetDataSource()
        End Sub
   Private Function GetDataSource() As List(Of G8Member)
            Dim GDPs As List(Of GDP) = GetGDPs()
            Dim countries As New List(Of G8Member)()
            Const yearsInDecade As Integer = 10
            For countryCounter As Integer = 0 To 7
                Dim countryGDPs As New List(Of GDP)()
                For countryValuesCounter As Integer = 0 To yearsInDecade - 1
                    countryGDPs.Add(GDPs(countryCounter * yearsInDecade + countryValuesCounter))
                Next countryValuesCounter
                countries.Add(New G8Member(countryGDPs))
            Next countryCounter
            Return countries
   End Function

   Private Function GetGDPs() As List(Of GDP)
            Dim document As XDocument = DataLoader.LoadXmlFromResources("/Data/GDPofG8.xml")
            Dim result As New List(Of GDP)()
            If document IsNot Nothing Then
                For Each element As XElement In document.Element("G8GDPs").Elements()
                    Dim country As String = element.Element("Country").Value
                    Dim year As Integer = Integer.Parse(element.Element("Year").Value)
                    Dim product As Decimal = Convert.ToDecimal(element.Element("Product").Value, CultureInfo.InvariantCulture)
                    result.Add(New GDP(country, year, product))
                Next element
            End If
            Return result
   End Function
        Public NotInheritable Class DataLoader
            Private Sub New()
            End Sub
            Public Shared Function LoadXmlFromResources(ByVal fileName As String) As XDocument
                Try
                    fileName = "/ToolTipPointTemplate;component" & fileName
                    Dim uri As New Uri(fileName, UriKind.RelativeOrAbsolute)
                    Dim info As StreamResourceInfo = Application.GetResourceStream(uri)
                    Return XDocument.Load(info.Stream)
                Catch
                    Return Nothing
                End Try
            End Function
        End Class

        Private Sub ChartToolTipController_ToolTipOpening(ByVal sender As Object, ByVal e As DevExpress.Xpf.Charts.ChartToolTipEventArgs)
           Dim toolTipData As ToolTipData = TryCast(e.Hint, ToolTipData)
           Dim colorNumber As Integer = e.Series.Points.IndexOf(e.SeriesPoint)
           Dim seriesColor As Color = e.ChartControl.Palette(colorNumber)
           toolTipData.SeriesBrush = New SolidColorBrush(seriesColor)
        End Sub
    End Class

    Public Class GDP
        Private privateCountry As String
        Public Property Country() As String
            Get
                Return privateCountry
            End Get
            Private Set(ByVal value As String)
                privateCountry = value
            End Set
        End Property
        Private privateYear As Integer
        Public Property Year() As Integer
            Get
                Return privateYear
            End Get
            Private Set(ByVal value As Integer)
                privateYear = value
            End Set
        End Property
        Private privateProduct As Decimal
        Public Property Product() As Decimal
            Get
                Return privateProduct
            End Get
            Private Set(ByVal value As Decimal)
                privateProduct = value
            End Set
        End Property

        Public Sub New(ByVal country As String, ByVal year As Integer, ByVal product As Decimal)
            Country = country
            Year = year
            Product = product
        End Sub
    End Class

    Public Class G8Member
        Private privateGDPin2010 As Decimal
        Public Property GDPin2010() As Decimal
            Get
                Return privateGDPin2010
            End Get
            Private Set(ByVal value As Decimal)
                privateGDPin2010 = value
            End Set
        End Property
        Private privateCountryName As String
        Public Property CountryName() As String
            Get
                Return privateCountryName
            End Get
            Private Set(ByVal value As String)
                privateCountryName = value
            End Set
        End Property
        Private privateToolTipData As ToolTipData
        Public Property ToolTipData() As ToolTipData
            Get
                Return privateToolTipData
            End Get
            Set(ByVal value As ToolTipData)
                privateToolTipData = value
            End Set
        End Property

        Public Sub New(ByVal GDPs As List(Of GDP))
            ToolTipData = New ToolTipData(GDPs, GDPs(0).Country)
            CountryName = GDPs(0).Country
            GDPin2010 = GDPs(9).Product
        End Sub
    End Class

    Public Class ToolTipData
        Private privateGDPs As List(Of GDP)
        Public Property GDPs() As List(Of GDP)
            Get
                Return privateGDPs
            End Get
            Private Set(ByVal value As List(Of GDP))
                privateGDPs = value
            End Set
        End Property
        Private privateSeriesBrush As SolidColorBrush
        Public Property SeriesBrush() As SolidColorBrush
            Get
                Return privateSeriesBrush
            End Get
            Set(ByVal value As SolidColorBrush)
                privateSeriesBrush = value
            End Set
        End Property
        Private privateTitle As String
        Public Property Title() As String
            Get
                Return privateTitle
            End Get
            Private Set(ByVal value As String)
                privateTitle = value
            End Set
        End Property

        Public Sub New(ByVal gdps As List(Of GDP), ByVal countryName As String)
            GDPs = gdps
            Title = countryName & " GDP History"
        End Sub
    End Class
End Namespace