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
8 Answers, 1 is accepted
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
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
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
Thank you very much for your support!
Best regards,
Henrique
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
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
Hi Hristo
It worked!
Thank you very much for your support!
Best regards,
Henrique

