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