Hi,
I used the AnnotationXY function to show the annotation on selected series but I have an issue with it if the annotation is out of graphical area. See the picture. I must flip it vertically if hit on limit axis.
Thank you for helping
Gregory
How to detect the collision between annotation and axis ?
Moderator: Queue Moderators
-
- Posts: 141
- Joined: Wed Mar 27, 2019 1:05 pm
Re: How to detect the collision between annotation and axis
Hi,
One way to detect a collision between an annotation and an axis is to set the location of the annotation using AxisValuesBoudaries, and then compare the boundaries to axis ranges inside an event.
Setting the annotation to use AxisValuesBoundaries:
The event can be for example RangeChanged, which triggers every time the minimum and/or maximum values of the corresponding axis are changed. In this example, every time Y axis range is changed, we check if the bottom or the top of the annotation hits the bottom or the top of the visible graph area. If this happens, the annotation is moved up or down.
There are also other annotation properties, that can be useful in some cases. Setting KeepVisible true makes the annotation always stay inside the graph area, no matter how much the graph is moved.
Setting ClipInsideGraph to false allows the annotation to be drawn outside the axes. This can be combined with RenderBehindAxis, which controls if the annotation should be drawn over the axis ticks and labels.
One way to detect a collision between an annotation and an axis is to set the location of the annotation using AxisValuesBoudaries, and then compare the boundaries to axis ranges inside an event.
Setting the annotation to use AxisValuesBoundaries:
Code: Select all
AnnotationXY anno = new AnnotationXY(_chart.ViewXY, _chart.ViewXY.XAxes[0], _chart.ViewXY.YAxes[0]);
anno.Style = AnnotationStyle.Callout;
anno.TargetAxisValues.SetValues(4, 300); // Where the annotation points to
anno.Sizing = AnnotationXYSizing.AxisValuesBoundaries;
anno.AxisValuesBoundaries.SetValues(3.5, 4.2, 340, 400); // Set annotation size in axis values
_chart.ViewXY.Annotations.Add(anno);
Code: Select all
_chart.ViewXY.YAxes[0].RangeChanged += Axis_RangeChanged;
private void Axis_RangeChanged(object sender, RangeChangedEventArgs e)
{
if (_chart.ViewXY.YAxes[0].Minimum > _chart.ViewXY.Annotations[0].AxisValuesBoundaries.YMin)
{
_chart.ViewXY.Annotations[0].AxisValuesBoundaries.SetValues(3.5, 4.2, _chart.ViewXY.Annotations[0].AxisValuesBoundaries.YMin + 150, _chart.ViewXY.Annotations[0].AxisValuesBoundaries.YMax + 150);
}
else if (_chart.ViewXY.YAxes[0].Maximum < _chart.ViewXY.Annotations[0].AxisValuesBoundaries.YMax)
{
_chart.ViewXY.Annotations[0].AxisValuesBoundaries.SetValues(3.5, 4.2, _chart.ViewXY.Annotations[0].AxisValuesBoundaries.YMin - 150, _chart.ViewXY.Annotations[0].AxisValuesBoundaries.YMax - 150);
}
}
Setting ClipInsideGraph to false allows the annotation to be drawn outside the axes. This can be combined with RenderBehindAxis, which controls if the annotation should be drawn over the axis ticks and labels.
Re: How to detect the collision between annotation and axis
Hi,
Thank you for your support. This solution is not worked if I use dynamic annotation with tracking cursor. I now found the solution.
Gregory
Thank you for your support. This solution is not worked if I use dynamic annotation with tracking cursor. I now found the solution.
Gregory
Re: How to detect the collision between annotation and axis
hi gregory, i have same problem, how can you resolve it?gurubikes wrote:Hi,
Thank you for your support. This solution is not worked if I use dynamic annotation with tracking cursor. I now found the solution.
Gregory
Re: How to detect the collision between annotation and axis
Hi serhatc,
I use "Multi-channel tracking induvidually" demo with following modification :
I use "Multi-channel tracking induvidually" demo with following modification :
Code: Select all
void pls_MouseClick(object sender, MouseEventArgs e)
{
MyChart.BeginUpdate();
// Change previous series highlighting
if (seriesBeingTracked != null)
seriesBeingTracked.MouseHighlight = MouseOverHighlight.Simple;
//Set series being tracked
seriesBeingTracked = (PointLineSeries)sender;
seriesBeingTracked.MouseHighlight = MouseOverHighlight.None;
//Set correct Y axis for value display
valueDisplay.AssignYAxisIndex = seriesBeingTracked.AssignYAxisIndex;
//Change color for the value display
valueDisplay.Fill.Color = ChartTools.CalcGradient(seriesBeingTracked.LineStyle.Color, Colors.White, 90);
valueDisplay.Fill.GradientColor = ChartTools.CalcGradient(seriesBeingTracked.LineStyle.Color, Colors.White, 50);
UpdateNearestValue(e);
MyChart.EndUpdate();
}
void UpdateNearestValue(MouseEventArgs e)
{
MyChart.BeginUpdate();
if (seriesBeingTracked != null)
{
double x;
var position = e.GetPosition(MyChart);
MyChart.ViewXY.XAxes[0].CoordToValue((int)position.X, out x, false);
LineSeriesValueSolveResult res = seriesBeingTracked.SolveYValueAtXValue(x);
if (res.SolveStatus == LineSeriesSolveStatus.OK)
{
double nearestX = seriesBeingTracked.Points[res.NearestDataPointIndex].X;
double nearestY = seriesBeingTracked.Points[res.NearestDataPointIndex].Y;
valueDisplay.Visible = true;
valueDisplay.Text = "X: " + nearestX.ToString("0.0") + "\nY: " + nearestY.ToString("0.0");
valueDisplay.TargetAxisValues.SetValues(nearestX, nearestY);
double delta = MyChart.ViewXY.YAxes[seriesBeingTracked.AssignYAxisIndex].Maximum - MyChart.ViewXY.YAxes[seriesBeingTracked.AssignYAxisIndex].Minimum;
double ptY = MyChart.ViewXY.YAxes[seriesBeingTracked.AssignYAxisIndex].Maximum - nearestY;
double percentage = (ptY / delta) * 100;
if (percentage < 14 && percentage >= 0)
{
valueDisplay.LocationRelativeOffset = new PointFloatXY(0, 40); // Show annotation below series.
}
else
{
valueDisplay.LocationRelativeOffset = new PointFloatXY(0, -40); // Show annotation above series.
}
}
else
{
valueDisplay.Visible = false;
}
}
MyChart.EndUpdate();
}