FrankGarica
FrankGarica

Reputation: 13

How to integrate custom tooltips into line chart in LiveCharts

References

  1. To produce line chart: https://lvcharts.net/App/examples/v1/Wpf/Line
  2. To produce tooltip: https://lvcharts.net/App/examples/v1/Wpf/Tooltips%20and%20Legends

What I want to do

I want to make a custom tooltip like the like the bar example in Reference 2, but in Reference 1

What I did

I copy pasted the tooltip in Reference 2, changed it to accommodate different variables

What went wrong

Tooltip on displays up to the box color, no variable values are shown.

Grey box with words expected, but only grey box shows up.

My Code

For both xaml and xaml.cs data for MainWindow, and Tooltip (called HITooltop)

MainWindow.xaml

<UserControl x:Class="NeoSpace.MainWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:NeoSpace"
             xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Right" >
            <lvc:CartesianChart.AxisY>
                <lvc:Axis Title="Sales" LabelFormatter="{Binding YFormatter}"></lvc:Axis>
            </lvc:CartesianChart.AxisY>
            <lvc:CartesianChart.AxisX>
                <lvc:Axis Title="Month" Labels="{Binding Labels}"></lvc:Axis>
            </lvc:CartesianChart.AxisX>
            <lvc:CartesianChart.DataTooltip>
                <local:HITooltip/>
            </lvc:CartesianChart.DataTooltip>
        </lvc:CartesianChart>
    </Grid>
</UserControl>

MainWindow.xaml.cs

using System;
using System.Windows.Controls;
using LiveCharts;
using LiveCharts.Wpf;

namespace NeoSpace
{
    public partial class MainWindow : UserControl
    {
        public MainWindow()
        {
            InitializeComponent();
            GraphicOutput HI01 = new GraphicOutput("Device01", "01-02-03-40-50-12", "Idle", 
                new ChartValues<double> { 3, 6, 9, 12, 15 }, new ChartValues<double> { 3, 6, 9, 12, 15 });
            GraphicOutput HI02 = new GraphicOutput("Device02", "01-02-03-40-50-12", "Idle");
            GraphicOutput HI03 = new GraphicOutput(
                new ChartValues<double> { 5, 10, 15, 20, 25 }, new ChartValues<double> { 5, 10, 15, 20, 25 });
            SeriesCollection = new SeriesCollection
            {
                new LineSeries
                {
                    Title = HI01.Device,
                    Values = HI01.Thoroughput
                },
                new LineSeries
                {
                    Title = HI02.Device,
                    Values = HI02.Thoroughput,
                    PointGeometry = null
                },
                new LineSeries
                {
                    Title = HI03.Device,
                    Values = HI03.Thoroughput,
                    PointGeometry = DefaultGeometries.Square,
                    PointGeometrySize = 15
                }
            };

            Labels = new[] { "Time 01", "Time 02", "Time 03", "Time 04", "Time 05" };
            YFormatter = value => value.ToString();
            DataContext = this;
        }
        public SeriesCollection SeriesCollection { get; set; }
        public string[] Labels { get; set; }
        public Func<double, string> YFormatter { get; set; }
    }
}

HITooltip.xaml

<UserControl x:Class="NeoSpace.HITooltip"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:wpf="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
             xmlns:local="clr-namespace:NeoSpace"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             d:DataContext="{d:DesignInstance local:HITooltip}"
             Background="#E4555555" Padding="20 10" BorderThickness="2" BorderBrush="Orange">
    <ItemsControl ItemsSource="{Binding Data.Points}" Grid.IsSharedSizeScope="True">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type wpf:DataPointViewModel}">
                <Grid Margin="2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Device"/>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="BDAddress"/>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="State"/>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="Thoroughput"/>
                    </Grid.ColumnDefinitions>
                    <Rectangle Grid.Column="0" Stroke="{Binding Series.Stroke}" Fill="{Binding Series.Fill}"
                               Height="15" Width="15"></Rectangle>
                    <TextBlock Grid.Column="1" Text="{Binding ChartPoint.Instance.(local:GraphicOutput.Device)}" 
                               Margin="5 0 0 0" VerticalAlignment="Center" Foreground="White"/>
                    <TextBlock Grid.Column="2" Text="{Binding ChartPoint.Instance.(local:GraphicOutput.BDAddress)}" 
                               Margin="5 0 0 0" VerticalAlignment="Center" Foreground="White"/>
                    <TextBlock Grid.Column="3" Text="{Binding ChartPoint.Instance.(local:GraphicOutput.State)}" 
                               Margin="5 0 0 0" VerticalAlignment="Center" Foreground="White"/>
                    <TextBlock Grid.Column="3" Text="{Binding ChartPoint.Instance.(local:GraphicOutput.Thoroughput)}" 
                               Margin="5 0 0 0" VerticalAlignment="Center" Foreground="White"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>

HITooltip.xaml.cs

using System.ComponentModel;
using LiveCharts;
using LiveCharts.Wpf;

namespace NeoSpace
{
    public partial class HITooltip : IChartTooltip
    {
        private TooltipData _data;

        public HITooltip()
        {
            InitializeComponent();
            DataContext = this;
        }

        public TooltipData Data
        {
            get { return _data; }
            set
            {
                _data = value;
                OnPropertyChanged("TooltipData");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public TooltipSelectionMode? SelectionMode { get; set; }

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            if (PropertyChanged != null)
            { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
        }
    }
}

The class GraphicOutput which is to be graphed and values revealed on the tooltip

using LiveCharts;

namespace NeoSpace
{
    public class GraphicOutput
    {
        public string Device { get; set; }
        public string BDAddress { get; set; }
        public string State { get; set; }
        public ChartValues<double> FrameSize { get; set; }
        public ChartValues<double> Thoroughput { get; set; }

        public GraphicOutput(string a, string b, string c, ChartValues<double> d1, ChartValues<double> d2)
        {
            Device = a;
            BDAddress = b;
            State = c;
            FrameSize = d1;
            Thoroughput = d2;
        }

        public GraphicOutput(string a, string b, string c)
        {
            Device = a;
            BDAddress = b;
            State = c;
            FrameSize = new ChartValues<double> { 1, 2, 3, 4, 5 };
            Thoroughput = new ChartValues<double> { 1, 2, 3, 4, 5 };
        }

        public GraphicOutput(ChartValues<double> d1, ChartValues<double> d2)
        {
            Device = "A Device";
            BDAddress = "11:22:33:44:55:66";
            State = "Too Idle";
            FrameSize = d1;
            Thoroughput = d2;
        }
    }
}

Upvotes: 1

Views: 2740

Answers (2)

FrankGarica
FrankGarica

Reputation: 13

How I got the answer

  • Tooltip.cs
using System.Windows.Controls;
using System.ComponentModel;
using LiveCharts;
using LiveCharts.Wpf;

namespace BraGraphHybridWithCustomTooltips
{
    /// <summary>
    /// Interaction logic for HybridTooltip.xaml
    /// </summary>
    public partial class HybridTooltip : IChartTooltip
    {
        private TooltipData _data;
        public HybridTooltip()
        {
            InitializeComponent();
            DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public TooltipData Data
        {
            get { return _data; }
            set
            {
                _data = value;
                OnPropertyChanged("Data");
            }
        }

        public TooltipSelectionMode? SelectionMode { get; set; }

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
  • Tooltip.xaml
<UserControl x:Class="BraGraphHybridWithCustomTooltips.HybridTooltip"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:wpf="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
             xmlns:local="clr-namespace:BraGraphHybridWithCustomTooltips"
             xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             d:DataContext="{d:DesignInstance local:HybridTooltip}">
    <ItemsControl ItemsSource="{Binding Data.Points}" Grid.IsSharedSizeScope="True">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type wpf:DataPointViewModel}">
                <Grid Margin="2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*" SharedSizeGroup="State"/>
                        <ColumnDefinition Width="*" SharedSizeGroup="Framesize"/>
                    </Grid.ColumnDefinitions>
                    <Rectangle Grid.Column="0" Stroke="{Binding Series.Stroke}" Fill="{Binding Series.Fill}"
                               Height="15" Width="15" VerticalAlignment="Center" Margin="5 0 5 0"/>
                    <WrapPanel Grid.Column="1" >
                        <TextBlock Text="State:" Margin="5 0 0 0"/>
                        <TextBlock Text="{Binding ChartPoint.Instance.(local:InputClass.State)}" 
                                Margin="5 0 0 0" VerticalAlignment="Center"/>
                    </WrapPanel>
                    <WrapPanel Grid.Column="3" >
                        <TextBlock Text="Framesize:" Margin="5 0 0 0"/>
                        <TextBlock Text="{Binding ChartPoint.Instance.(local:InputClass.Framesize)}" 
                                Margin="5 0 0 0" VerticalAlignment="Center"/>
                    </WrapPanel>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>

Apply it to Main Window as such

<Window x:Class="BraGraphHybridWithCustomTooltips.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BraGraphHybridWithCustomTooltips"
        xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <local:HybridTooltip/>
    </Grid>
</Window>

And voila (as far as LiveCharts is concerned)

Upvotes: 0

user2250152
user2250152

Reputation: 20625

In HITooltip class the property name should be Data instead of TooltipData.

public TooltipData Data
{
    get { return _data; }
    set
    {
        _data = value;
        OnPropertyChanged("Data");
    }
}

Upvotes: 0

Related Questions