SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and iOS Chart & Android Chart Components

1 vote
2k views

Hello,
I have a polar chart in my wpf application and I want to get data value from pixel coordinates, once the user has
clicked on scichart surface. This is what I tried:

   mouseClick = (s, arg) =>
        {
            var mousePoint = arg.GetPosition((UIElement)this.sciChartSurface.GridLinesPanel);

    //From cartesian to polar conversion
            double xpolar = Math.Atan(mousePoint2.Y / mousePoint2.X);
            double ypolar = Math.Sqrt(Math.Pow(mousePoint2.X, 2) + Math.Pow(mousePoint2.Y, 2));

            double a = sciChartSurface.RenderableSeries[_trace_index].XAxis.GetCurrentCoordinateCalculator().GetDataValue(xpolar);
            double b = sciChartSurface.RenderableSeries[_trace_index].YAxis.GetCurrentCoordinateCalculator().GetDataValue(ypolar);
};

This code gets mouse point coordinates, then it converts pixel coordinates to polar, and then (a,b) data are obtained with
GetCurrentCoordinateCalculator().GetDataValue(), but a and b have some strange values. I’ve tried just the opposite (from data value to pixel coordinate using GetCoordinate()), but it still doesn’t work. Any ideas? Is it possible to get data from pixel coordinates in polar chart?

Thanks in advance,
Juan

0 votes
3k views

Dear All:

I have been looking for a good way to obtain data from a multi-line chart (more than 1 y-value/y-axis) by either clicking an area that’s highlighted with a vertical line rollover, or selected with a vertical slice.

Basically I would like to take the data that I see in the Series Vertical Slices example, and extract the X-Axis values, as well as the Curve A, Curve B, and Curve C values that are shown on the vertical slice, so that I can insert that in something like a TextBox in a WPF.

Any idea how to do this, as well as with MVVM? (Will use MVC if necessary).

Thanks kindly!

— A

  • Ari Sagiv asked 3 years ago
  • last active 3 years ago
0 votes
3k views

I’m in the process of evaluating SCIChart for purchase and have encountered what appears to be a bug in the Axis.GetDataValue method when a Title or Legend is present on the chart.

I am placing an annotation on the chart surface at the exact point a right mouse click raises a context menu. The annotation position is set as follows:

var newLabel = (LabelViewModel) e.NewItems[0];
newLabel.X1 = (DateTime) XAxis.GetDataValue(LastRightClickPoint.X);
newLabel.Y1 = (double) YAxis.GetDataValue(LastRightClickPoint.Y);
AddAnnotations(newLabel);

When there is no title, or legend on the chart surface this works exactly as expected and the annotation is placed exactly where the mouse click occurred.

When a title or legend is present on the surface, the annotation placement is shifted exactly the height of the title + the height of legend down from the spot of the mouse click coordinates.

Is this behavior expected? Is there something I’m not taking into account? Is there any easy way to get the pixel offset created by the title or legend?

I obtain the mouse cursor position by overiding the OnModifierMouseDown in a CustomAnnotation chart modifier class:

  /// <summary>
/// The CustomAnnotationChartModifiers provides a bridge between ViewModel and SciChartSurface, where we can 
/// access the Labels (via data binding) as well as the SciChart API to add, remove and manipulate annotations
/// </summary>
public class CustomAnnotationChartModifier : ChartModifierBase
{

    public Point LastRightClickPoint { get; set; }

    public static readonly DependencyProperty LabelsSourceProperty =
        DependencyProperty.Register(
            "LabelsSource",
            typeof (ObservableCollection<LabelViewModel>),
            typeof (CustomAnnotationChartModifier),
            new PropertyMetadata(OnLabelsSourceChanged));


    // Here LabelsSource is IEnumerable, but you could easily make it ObservableCollection<LabelViewModel> 
    // in order to get changed notifications when items are added to, or removed from the collection
    public ObservableCollection<LabelViewModel> LabelsSource
    {
        get
        {
            var labels =  (ObservableCollection<LabelViewModel>)GetValue(LabelsSourceProperty);
            return labels;
    }
        set { SetValue(LabelsSourceProperty, value); }
    }

    // Get a notification when new labels are set.
    private static void OnLabelsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var modifier = (CustomAnnotationChartModifier) d;
        var oldLabels = e.OldValue as INotifyCollectionChanged;
        var newLabels = e.NewValue as INotifyCollectionChanged;


        IEnumerable newValue = e.NewValue as IEnumerable;
        if (newValue != null)
        {
            if (oldLabels != null)
            {
                oldLabels.CollectionChanged -= modifier.OnLabelsCollectionChanged;
            }
            if (newLabels != null)
            {
                newLabels.CollectionChanged += modifier.OnLabelsCollectionChanged;
            }
            modifier.RebuildAnnotations();
        }

    }

    private  void OnLabelsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {

        if (e.NewItems  != null)
        {
            var newLabel = (LabelViewModel) e.NewItems[0];
            newLabel.X1 = (DateTime) XAxis.GetDataValue(LastRightClickPoint.X);
            newLabel.Y1 = (double) YAxis.GetDataValue(LastRightClickPoint.Y);
            AddAnnotations(newLabel);
        }

        if (e.OldItems != null)
        {
           RemoveAnnotations(e.OldItems);
        }
    }


    private void RemoveAnnotations(IList annotationViewModels)
    {
        if (base.ParentSurface != null)
        {
            foreach (var annotationViewModel in annotationViewModels)
            {
                var annotation = base.ParentSurface.Annotations.FirstOrDefault(a => a.DataContext == (annotationViewModel as LabelViewModel)) ;
                base.ParentSurface.Annotations.Remove(annotation);
            }
        }
    }

    private void AddAnnotations(LabelViewModel annotationViewModel)
    {
        if (base.ParentSurface != null)
        {
            base.ParentSurface.Annotations.Add( new CustomTextAnnotation() {DataContext = annotationViewModel});
        }
    }


    // Recreate all annotations
    private void RebuildAnnotations()
    {
        if (base.ParentSurface != null && LabelsSource != null)
        {
            // Take a look at the base class, ChartModifierBase for a wealth of API 
            // methods and properties to manipulate the SciChartSurface
            var annotationCollection = base.ParentSurface.Annotations;
            annotationCollection.Clear();

            foreach (var item in LabelsSource)
            {
                annotationCollection.Add(new CustomTextAnnotation() { DataContext = item });
            }
        }
    }

    /// <summary>
    /// Called when the Chart Modifier is attached to the Chart Surface
    /// </summary>
    public override void OnAttached()
    {
        base.OnAttached();

        // Catch the condition where LabelsSource binds before chart is shown. Rebuild annotations
        if (LabelsSource != null && base.ParentSurface.Annotations.Count == 0)
        {
            RebuildAnnotations();
        }

        //var mainWindow = FindLogicalParent<Window>();

        //mainWindow.PreviewKeyDown -= Annotation_PreviewKeyDown;
    }


    public override void OnModifierMouseDown(ModifierMouseArgs e)
    {
        base.OnModifierMouseDown(e);
        if (e.MouseButtons == MouseButtons.Right)
        {
            //  AddAnnotation(e.MousePoint);
            LastRightClickPoint = e.MousePoint;
        }
    }
Showing 3 results
This template supports the sidebar's widgets. Add one or use Full Width layout.