How to detect the collision between annotation and axis ?

A forum dedicated to WPF version of LightningChart Ultimate.

Moderator: Queue Moderators

Post Reply
gurubikes
Posts: 3
Joined: Tue May 14, 2019 7:00 pm

How to detect the collision between annotation and axis ?

Post by gurubikes » Tue May 14, 2019 7:12 pm

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.
Annotation.png
Annotation.png (13.68 KiB) Viewed 6042 times
Thank you for helping

Gregory

Arction_LasseP
Posts: 141
Joined: Wed Mar 27, 2019 1:05 pm

Re: How to detect the collision between annotation and axis

Post by Arction_LasseP » Wed May 15, 2019 8:06 am

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:

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);
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.

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);
            }
        }
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.

gurubikes
Posts: 3
Joined: Tue May 14, 2019 7:00 pm

Re: How to detect the collision between annotation and axis

Post by gurubikes » Wed May 15, 2019 5:44 pm

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

serhatc
Posts: 1
Joined: Thu May 23, 2019 1:02 pm

Re: How to detect the collision between annotation and axis

Post by serhatc » Thu May 23, 2019 1:05 pm

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
hi gregory, i have same problem, how can you resolve it?

gurubikes
Posts: 3
Joined: Tue May 14, 2019 7:00 pm

Re: How to detect the collision between annotation and axis

Post by gurubikes » Fri May 24, 2019 1:58 pm

Hi serhatc,

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();
        }

Post Reply