How to detect the collision between annotation and axis ?

A forum dedicated to WPF version of LightningChart Ultimate.

How to detect the collision between annotation and axis ?

Postby 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 315 times


Thank you for helping

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

Re: How to detect the collision between annotation and axis

Postby 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.
Arction_LasseP
 
Posts: 21
Joined: Wed Mar 27, 2019 1:05 pm

Re: How to detect the collision between annotation and axis

Postby 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
gurubikes
 
Posts: 3
Joined: Tue May 14, 2019 7:00 pm

Re: How to detect the collision between annotation and axis

Postby 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?
serhatc
 
Posts: 1
Joined: Thu May 23, 2019 1:02 pm

Re: How to detect the collision between annotation and axis

Postby 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();
        }
gurubikes
 
Posts: 3
Joined: Tue May 14, 2019 7:00 pm


Return to LightningChart Ultimate WPF

Who is online

Users browsing this forum: No registered users and 9 guests

cron