Obtaining the cartesian grid line annotation value exact based in mouse position

9 posts, 2 answers
  1. Maurer
    Maurer avatar
    11 posts
    Member since:
    Jan 2015

    Posted 30 May 2017 Link to this post

    Dear Support Team,

    How we obtain the cartesian grid line annotation value exact based in mouse position  to plot vertical or horizontal grid line annotations using mouse click without insert the exact value manually?

    Thanks in advance!

    Best regards,

    Henrique
  2. Maurer
    Maurer avatar
    11 posts
    Member since:
    Jan 2015

    Posted 30 May 2017 in reply to Maurer Link to this post

    Other image 
  3. Answer
    Dimitar
    Admin
    Dimitar avatar
    2907 posts

    Posted 31 May 2017 Link to this post

    Hi Maurer,

    Here is how you can achieve this:
    private void RadChartView1_MouseDown(object sender, MouseEventArgs e)
    {
        var mousePos = e.Location.Y;
        var verticalAxis = radChartView1.Axes[1] as LinearAxis;
        double currentDistance = double.MaxValue;
        double minDistance = double.MaxValue;
        double value = double.NaN;
        double step = (verticalAxis.ActualRange.Maximum - verticalAxis.ActualRange.Minimum) / verticalAxis.Model.LayoutSlot.Height;
     
        for (double i = verticalAxis.ActualRange.Minimum; i < verticalAxis.ActualRange.Maximum; i += step)
        {
            var loc1 = verticalAxis.GetLocationOfValue(i) + radChartView1.View.Margin.Top;
     
            currentDistance = Math.Abs(loc1 - mousePos);
     
            if (currentDistance < minDistance)
            {
                minDistance = currentDistance;
            }
            else
            {
                value = i;
                break;
            }
     
        }
     
        CartesianGridLineAnnotation annotation1 = new CartesianGridLineAnnotation();
        annotation1.Axis = this.radChartView1.Axes[1] as CartesianAxis;
        annotation1.Value = value;
        annotation1.BorderColor = Color.Red;
        annotation1.BorderDashStyle = DashStyle.Solid;
        annotation1.BorderWidth = 1;
        this.radChartView1.Annotations.Add(annotation1);
    }

    I hope this will be useful. Let me know if you have additional questions.

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  4. Maurer
    Maurer avatar
    11 posts
    Member since:
    Jan 2015

    Posted 31 May 2017 in reply to Dimitar Link to this post

    Hi Dimitar,

    Thank you very much for your support!

    The first issue is about the 'RadChartView.Annotations.Add(annotationToAdd)' method ,
    when we add annotations using this method to create vertical and horizontal annotations with one mouse click the vertical line is created but the position is incorrect,  the behavior is strange.

    The same does not ocurres when we using 'RadChartView.Annotations.AddRange(annotations.ToArray())'.

    Please see the attached images and the code below:

     

      private void RadChartView1_MouseDown(object sender, MouseEventArgs e)

            {
                CreateHorizontalAnnotation(e);

                CreateVerticalAnnotation(e);

                //1 Works correctly
                //radChartView1.Annotations.AddRange(annotations.ToArray());
            }
      
      
      #region Create Cartesian Annotations Methods

            private void CreateHorizontalAnnotation(MouseEventArgs e)
            {
                var mousePos = e.Location.Y;
                var verticalAxis = radChartView1.Axes[1] as LinearAxis;
                var minDistance = double.MaxValue;
                var value = double.NaN;
                var step = (verticalAxis.ActualRange.Maximum - verticalAxis.ActualRange.Minimum) / verticalAxis.Model.LayoutSlot.Height;

                for (var i = verticalAxis.ActualRange.Minimum; i < verticalAxis.ActualRange.Maximum; i += step)
                {
                    var loc1 = verticalAxis.GetLocationOfValue(i) + radChartView1.View.Margin.Top;

                    var currentDistance = Math.Abs(loc1 - mousePos);

                    if (currentDistance < minDistance)
                    {
                        minDistance = currentDistance;
                    }
                    else
                    {
                        value = i;
                        break;
                    }

                }

                var annotation1 = new CartesianGridLineAnnotation
                {
                    Axis = radChartView1.Axes[1] as CartesianAxis,
                    Value = value,
                    BorderColor = Color.Red,
                    BorderDashStyle = DashStyle.Solid,
                    BorderWidth = 1
                };

                //1 Works correctly
                //annotations.Add(annotation1);

                //2 It doesn't work.
                this.radChartView1.Annotations.Add(annotation1);
            }

            private void CreateVerticalAnnotation(MouseEventArgs e)
            {
                var mousePos = e.Location.X;

                var horizontalAxis = radChartView1.Axes[0] as DateTimeContinuousAxis;

                DateTime? value = null;

                var referenceDate = horizontalAxis.ActualRange.Minimum;

                var referencePosition = mousePos;

                do
                {
                    var loc1 = horizontalAxis.GetLocationOfValue(referenceDate) + radChartView1.View.Margin.Right;

                    if (loc1 > referencePosition)
                        break;

                    value = referenceDate;

                    referenceDate = referenceDate.AddSeconds(1);

                } while (referenceDate <= horizontalAxis.ActualRange.Maximum);


                if (!value.HasValue)
                    return;

                var annotation = new CartesianGridLineAnnotation
                {
                    Axis = radChartView1.Axes[0] as DateTimeContinuousAxis,
                    Value = value,
                    BorderColor = Color.Blue,
                    BorderDashStyle = DashStyle.Solid,
                    BorderWidth = 1
                };

                //1 Works correctly
                //annotations.Add(annotation);

                //2 It doesn't work.
                this.radChartView1.Annotations.Add(annotation);
            }

            #endregion


    I would like to know if my method to create the vertical line in mouse click position when the data is of type DateTimeContinuousAxis is correct or exist some the advice to this solution,

    Can I use the mouse move event to automatically show the cartesian grid line annotation and display the values between the ticks in a label? Exists a advice about this question,

    Thanks in advanced,
    Henrique

  5. Answer
    Dimitar
    Admin
    Dimitar avatar
    2907 posts

    Posted 01 Jun 2017 Link to this post

    Hi Henrique,

    I was able to reproduce the observed behavior. It is caused because after adding of the chart elements are marked for update. This can be avoided by forcing the layout with the following code:
    this.radChartView1.ChartElement.View.Layout();

    Actually, there is a better way to calculate value:
    private void RadChartView1_MouseDown(object sender, MouseEventArgs e)
    {
        object hValue = this.GetVerticalAxisValueFromMouse(e);
        object vValue = this.GetHorizontalAxisValueFromMouse(e);
     
        CreateVerticalAnnotation(vValue);
        CreateHorizontalAnnotation(hValue);
    }
     
    private object GetVerticalAxisValueFromMouse(MouseEventArgs e)
    {
        LinearAxis axis = radChartView1.Axes[1] as LinearAxis;
        double delta = axis.ActualRange.Maximum - axis.ActualRange.Minimum;           
        double totalHeight = axis.Model.LayoutSlot.Height;
        double ratio = 1 - (e.Location.Y - this.radChartView1.Area.View.Viewport.Y - axis.Model.LayoutSlot.Y) / totalHeight;
        double value = axis.ActualRange.Minimum + delta * ratio;
     
        return value;
    }
     
    private object GetHorizontalAxisValueFromMouse(MouseEventArgs e)
    {
        DateTimeContinuousAxis axis = radChartView1.Axes[0] as DateTimeContinuousAxis;
        long delta = axis.ActualRange.Maximum.Ticks - axis.ActualRange.Minimum.Ticks;
        double totalWidth = axis.Model.LayoutSlot.Width;
        double ratio = (e.Location.X - this.radChartView1.View.Viewport.X - axis.Model.LayoutSlot.X) / totalWidth;
        double value = axis.ActualRange.Minimum.Ticks + delta * ratio;
     
        return new DateTime((long)value);
    }
     
    private void CreateHorizontalAnnotation(object value)
    {
        var annotation = new CartesianGridLineAnnotation
        {
            Axis = radChartView1.Axes[1] as CartesianAxis,
            Value = value,
            BorderColor = Color.Red,
            BorderDashStyle = DashStyle.Solid,
            BorderWidth = 1
        };
     
        this.radChartView1.Annotations.Add(annotation);
    }
     
    private void CreateVerticalAnnotation(object value)
    {
        var annotation = new CartesianGridLineAnnotation
        {
            Axis = radChartView1.Axes[0] as DateTimeContinuousAxis,
            Value = value,
            BorderColor = Color.Blue,
            BorderDashStyle = DashStyle.Solid,
            BorderWidth = 1
        };
     
        this.radChartView1.Annotations.Add(annotation);
    }

    I hope this will be useful.

    Regards,
    Dimitar
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  6. Maurer
    Maurer avatar
    11 posts
    Member since:
    Jan 2015

    Posted 05 Jun 2017 in reply to Dimitar Link to this post

    Hi Dimitar,

    Thank you very much for your support!

    Best regards,
    Henrique
  7. Maurer
    Maurer avatar
    11 posts
    Member since:
    Jan 2015

    Posted 06 Jul 2017 Link to this post

    Hi Dimitar,

    The methods works ok but when the zoom is aplicatted the position does not correctly. How we get the exact position when i have zoom applied?

    Thanks in advance!

    Best regards,
    Henrique

  8. Hristo
    Admin
    Hristo avatar
    1519 posts

    Posted 07 Jul 2017 Link to this post

    Hi Henrique,

    Thank you for writing.

    Indeed, the current zoom factors are not taken into consideration. You need to change the GetVerticalAxisValueFromMouse and GetHorizontalAxisValueFromMouse methods this way: 
    private object GetVerticalAxisValueFromMouse(MouseEventArgs e)
    {
        LinearAxis axis = radChartView1.Axes[1] as LinearAxis;
        IChartView view = (IChartView)axis.View;
     
        double delta = axis.ActualRange.Maximum - axis.ActualRange.Minimum;
        double totalHeight = axis.Model.LayoutSlot.Height;
        double ratio = 1 - (e.Location.Y - this.radChartView1.Area.View.Viewport.Y - view.PlotOriginY - axis.Model.LayoutSlot.Y) / (totalHeight * view.ZoomHeight);
        double value = axis.ActualRange.Minimum + delta * ratio;
     
        return value;
    }
     
    private object GetHorizontalAxisValueFromMouse(MouseEventArgs e)
    {
        DateTimeContinuousAxis axis = radChartView1.Axes[0] as DateTimeContinuousAxis;
        IChartView view = (IChartView)axis.View;
     
        long delta = axis.ActualRange.Maximum.Ticks - axis.ActualRange.Minimum.Ticks;
        double totalWidth = axis.Model.LayoutSlot.Width;
        double ratio = (e.Location.X - this.radChartView1.View.Viewport.X - view.PlotOriginX - axis.Model.LayoutSlot.X) / (totalWidth * view.ZoomWidth);
        double value = axis.ActualRange.Minimum.Ticks + delta * ratio;
     
        return new DateTime((long)value);
    }

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  9. Maurer
    Maurer avatar
    11 posts
    Member since:
    Jan 2015

    Posted 07 Jul 2017 in reply to Hristo Link to this post

    Hi Hristo

    It worked!
    Thank you very much for your support!

    Best regards,

    Henrique

Back to Top