SFChart: Passing X Value to ContextMenu command

Hi,

I have an SfChart where I'm working with various annotations. The X axis is a DateTimeAxis, and I'm using VerticalLineAnnotations to represent points in time. I'm using MVVM, so each annotation has a simple backing object that contains a timestamp and a name. I need to add a context menu that allows the user to add a new annotation at the point in time (on the x-axis) where they clicked. It seems this is hard to achieve for a view reasons, including the fact that a ContextMenu lives in a separate visual tree. 

I also would like to attach a function to a left click that also uses the x-value of the clicked point. 

For both requirements, the trackball displays the value I need but I haven't found any way to access that - is it possible to access values from the Trackball somehow, or will I need to calculate the X value from the mouse's position? I've attempted this using logic seen on other threads (e.g. https://www.syncfusion.com/forums/119355/how-to-get-a-datapoint-on-mouse-click), but I've found the resulting values to be quite inaccurate.

Thanks,

Tim

7 Replies

TB Tim Barry-Woods March 23, 2020 07:26 AM UTC

A further question on the same topic: I've got a ChartTrackBallBehavior where LabelDisplayMode="FloatAllPoints" so the Trackball displays each series' value at the point where you hover the mouse. Is it possible to achieve a similar effect for annotations?


DD Devakumar Dhanapoosanam Syncfusion Team March 24, 2020 05:24 PM UTC

Hi Tim Barry-Woods, 
 
Greetings from Syncfusion. 
 
Query: Adding a new annotation using context menu at the point(on X-axis clicked)? 
 
We were not clear about your requirement, can you please explain in detail or share any pictorial representation of your exact requirement? And at which position on axis while clicking trying to add a new annotation(any pictorial example using the chart axis). 
 
Query: I also would like to attach a function to a left click that also uses the x-value of the clicked point? 
 
Can you please share the chart series and axis type using for your requirement which will be helpful for us to provide a solution based on your exact requirement? 
 
Query: Is it possible to achieve a similar effect for annotations? 
 
There is no direct way to achieve your requirement and we would like to let you know you can use the Tooltip feature in annotation by using the ShowTooltip and the TooltipContent property of annotation which shows tooltip when mouse hovered on the annotation. 
 
Please refer the below help document for more details, 
 
 
Regards, 
Devakumar D 



TB Tim Barry-Woods March 25, 2020 02:02 AM UTC

Hi Devakumar,

Thanks for your reply. Sorry if I wasn't clear enough. Here's a diagram of what I'm trying to achieve:

The tooltip won't solve the annotation labels requirement because the labels would be displayed at all times, not just on mouse hover. 

Regarding the axes and series I'm using: I'm using several FastLineSeries and ScatterSeries. My primary (X) axis is a DateTimeAxis, and I have multiple Y axes which are of type NumericAxis.

Please let me know if you have any further questions.

Thanks,

Tim



DD Devakumar Dhanapoosanam Syncfusion Team March 25, 2020 04:25 PM UTC

Hi Tim Barry-Woods, 
 
Thanks for providing the requested details. 
 
Currently we are working your requirement and will update you the details on or before March 27, 2020. 
 
Regards, 
Devakumar D 



DD Devakumar Dhanapoosanam Syncfusion Team March 28, 2020 06:42 PM UTC

Hi Tim, 
 
We have achieved your requirement “Displaying the trackball series label value in annotation” using the VerticalLineAnnotation ShowAxisLabel property and using the AxisLabelTemplate as per in the below code snippet, 
 
XAML: 
 
<syncfusion:SfChart.Resources> 
        …. 
        <local:LabelValueConverter x:Key="axisLabelConverter"/> 
        <DataTemplate x:Key="axisLabelTemplate"> 
                    <Border BorderBrush="Violet"  
                            BorderThickness="2" CornerRadius="5"  
                            Background="LightGray"> 
                        <TextBlock Foreground="Black"  
                                   FontSize="11" 
                                   Text="{Binding Converter={StaticResource axisLabelConverter}, 
                                                  Source={x:Reference lineSeries}}"/> 
                    </Border> 
         </DataTemplate> 
 
</syncfusion:SfChart.Resources> 
 
<syncfusion:SfChart.Annotations> 
                <syncfusion:VerticalLineAnnotation ShowAxisLabel="True" Stroke="#00e1cb" 
                                                   X1="{Binding VerLineAnnotaion1}" 
                                                   AxisLabelTemplate="{StaticResource axisLabelTemplate}"/> 
                  
</syncfusion:SfChart.Annotations> 
 
C#: 
public class LabelValueConverter : IValueConverter 
    { 
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
        { 
            string axisLabel = string.Empty; 
            var series = value; 
 
            if (series != null) 
            { 
                var ser = (series as ChartSeries); 
                var viewModel = (series as ChartSeries).DataContext as ViewModel; 
                var data = ser.ItemsSource as ObservableCollection<Model>; 
                var xDate = ser.Name == "lineSeries" ? viewModel.VerLineAnnotaion1 :  
                                                  viewModel.VerLineAnnotaion2; 
                foreach (var item in data) 
                { 
                    if (item.XValue == xDate) 
                    { 
                        axisLabel = SetAnnotationAxisLabel(ser.Name, item); 
                        break; 
                    } 
                } 
            } 
            return axisLabel; 
        } 
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
        { 
            throw new NotImplementedException(); 
        } 
 
        private string SetAnnotationAxisLabel(string seriesName, Model item) 
        { 
            switch (seriesName) 
            { 
                case "lineSeries": 
                    return "Dry Bulb Supply: " + item.YValue1.ToString(); 
                case "scatterSeries": 
                    return "Temperature Split: " + item.YValue2.ToString(); 
            } 
                 
            return "No data"; 
        } 
} 
 
Also, we have achieved your requirement “adding annotation by right click in chart axis using ContextMenu” by using the MouseDown event get the value of the x axis at the right clicked position in chart and using the ContextMenu Click event added a new VerticalLineAnnoation showing the axis label. Please refer the below code snippet for more details, 
 
XAML: 
<syncfusion:SfChart x:Name="chart" Header="System Overview" 
                            MouseDown="SfChart_MouseDownClick"> 
          <syncfusion:SfChart.ContextMenu> 
                <ContextMenu> 
                    <MenuItem Header="Add" > 
                        <MenuItem Header="Annotation" Click="AddChartAnnotation_Click"/> 
                    </MenuItem> 
                </ContextMenu> 
          </syncfusion:SfChart.ContextMenu> 
          ….. 
         <DataTemplate x:Key="showAxisLabelTemplate"> 
                    <Border BorderBrush="Violet"  
                            BorderThickness="2" CornerRadius="5"  
                            Background="LightGray"> 
                        <TextBlock Foreground="Black" FontSize="11" 
                                             Text="{Binding}"/> 
                    </Border> 
         </DataTemplate> 
          
</syncfusion:SfChart> 
 
C#: 
private void AddChartAnnotation_Click(object sender, RoutedEventArgs e) 
{ 
            chart.Annotations.Add(new VerticalLineAnnotation() { X1 = X1,  
                        CoordinateUnit = CoordinateUnit.Axis, 
                        ShowAxisLabel = true, 
                        StrokeThickness = 0, 
                        AxisLabelTemplate = chart.Resources["showAxisLabelTemplate"] as DataTemplate, 
                        }); 
} 
        
private void SfChart_MouseDownClick(object sender, MouseButtonEventArgs e) 
{ 
            Point position = new Point 
            { 
                X = e.GetPosition(chart).X - chart.SeriesClipRect.Left, 
                Y = e.GetPosition(chart).Y - chart.SeriesClipRect.Top 
            }; 
 
            //PointToValue converts window coordinates to chart X,Y coordinates 
            double xValue = chart.PointToValue(chart.PrimaryAxis, position); 
            double yValue = chart.PointToValue(chart.SecondaryAxis, position); 
 
            var date = DateTime.FromOADate(xValue); 
            X1 = date; 
} 
 
We have prepared a sample based on your requirement. Please download the sample from the below link, 
 
 
Screenshot: 
 
 
Please refer the below KB and UG for more details: 
 
 
Please let us know whether the above solution works for your requirement. 
 
Regards, 
Devakumar D 



TB Tim Barry-Woods April 2, 2020 04:19 AM UTC

Hi Devakumar,

Thanks for this - with your help I've managed to implement everything I needed here.

Cheers,

Tim


DD Devakumar Dhanapoosanam Syncfusion Team April 2, 2020 05:39 AM UTC

Hi Tim, 
 
Thanks for your update. 
 
We are glad to hear that you have achieved your requirement. 
 
If you need any further assistance, please don't hesitate to contact us. 
 
Regards, 
Devakumar D 


Loader.
Up arrow icon