Draw line tool behaving strange

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
Nitin
Newbie
Newbie
Posts: 52
Joined: Fri Jun 30, 2006 12:00 am

Draw line tool behaving strange

Post by Nitin » Wed Aug 12, 2009 1:09 pm

Hi TeaChart Team,
I am using the nearest point tool to get the nearest point out of 100 fast line serieses. I am able to get the nearest point value correctly. Now i want to draw a vertical dashed line from that nearest point to my bottom axis with a circle at the point. For drawing the line i am using the DrawLine tool. I have 3000 data points in each series. Using the draw line tool i am able to draw the line also but after a certain value of x-axis (if the valueIndex > 2000 or so) - the line is not getting drawn. Please see the code below -

Code: Select all

       private void TeeChart_MouseMove(object sender, MouseEventArgs e)
        {
            if (TeeChart.Series.Count <= 0) return;

            CalCulateNearestPoint(e);
        }

       private void CalCulateNearestPoint(MouseEventArgs e)
        {
            int[] NearestPoints;
            int SeriesIndex, ValueIndex;
            double Dist, tmp;
            Point P1, P2;

            NearestPoints = new int[TeeChart.Series.Count];
            P1 = new Point(0, 0);
            P2 = new Point(TeeChart.Width, TeeChart.Height);
            SeriesIndex = 0;
            ValueIndex = 0;

            for (int i = 0; i < NearestPoints.Length; i++)
            {
                _NearestPointTool.Series = TeeChart.Series[i];
                NearestPoints[i] = _NearestPointTool.GetNearestPoint(new Point(e.X, e.Y));
            }

            _NearestPointTool.Series = null;

            Dist = Distance(P1, P2);
            int StartPt = -1;
            int EndPt = -1;
            for (int i = 0; i < NearestPoints.Length; i++)
            {
                P1.X = TeeChart.Series[i].CalcXPos(NearestPoints[i]);
                P1.Y = TeeChart.Series[i].CalcYPos(NearestPoints[i]);
                P2.X = e.X;
                P2.Y = e.Y;
                tmp = Distance(P1, P2);

                if ((i == 0) || (tmp < Dist))
                {
                    Dist = tmp;
                    SeriesIndex = i;
                    ValueIndex = NearestPoints[i];
                }
            }

            if (_DrawLine != null)
                TeeChart.Tools.Remove(_DrawLine);
            TeeChart.Tools.Add(_DrawLine = new DrawLine());


            _DrawLine.EnableDraw = false;
            _DrawLine.Button = MouseButtons.XButton2;
            _DrawLine.Series = TeeChart.Series[SeriesIndex];

            _DrawLine.Pen.Color = Color.Gray;
            _DrawLine.Pen.Width = 1;
            _DrawLine.Pen.DashPattern = new float[] { 4.0f, 4.0f, 2.0f, 2.0f, 4.0f };
            _DrawLine.Pen.Style = System.Drawing.Drawing2D.DashStyle.Custom;
            _DrawLine.Pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
            _DrawLine.Pen.DashCap = System.Drawing.Drawing2D.DashCap.Round;

            DrawLineItem _DrawLineItem = new DrawLineItem(_DrawLine);
            _DrawLineItem.StartPos = new Steema.TeeChart.Drawing.PointDouble((double)ValueIndex, 0);
            _DrawLineItem.EndPos = new Steema.TeeChart.Drawing.PointDouble((double)ValueIndex, TeeChart.Series[SeriesIndex].YValues[ValueIndex]);

            _DrawLine.Invalidate();

            if (_AnnotationTool != null)
                TeeChart.Tools.Remove(_AnnotationTool);

            _AnnotationTool = new Annotation(TeeChart.Chart);
            TeeChart.Tools.Add(_AnnotationTool);

            _AnnotationTool.Text = "Series: " + TeeChart.Series[SeriesIndex].Title + " - ValueIndex: " + TeeChart.Series[SeriesIndex].YValues[ValueIndex].ToString() + " - Label: " + lTimeStamps[ValueIndex];
            _AnnotationTool.Left = e.X + 5;
            _AnnotationTool.Top = e.Y - 25;
        }

        private double Distance(Point Pt1, Point Pt2)
        {
            int dx, dy;

            dx = Pt1.X - Pt2.X;
            dy = Pt1.Y - Pt2.Y;

            return Math.Sqrt((dx * dx) + (dy * dy));
        }

Once the 'ValueIndex' goes beyond 2000 or 2100, line is not getting drawn.
Please let me know if i am doing something wrong.

Nitin
Newbie
Newbie
Posts: 52
Joined: Fri Jun 30, 2006 12:00 am

Re: Draw line tool behaving strange

Post by Nitin » Thu Aug 13, 2009 10:42 am

Also, the same logic for calcualting the nearest point out of 100 serieses is not working when i have zoomed the chart. Please let me know how i can get the nearest point when my chart is in zoomed state.

Yeray
Site Admin
Site Admin
Posts: 9612
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Draw line tool behaving strange

Post by Yeray » Thu Aug 13, 2009 11:16 am

Hi Nitin,

Could you please take a look at this example? I've mixed the interpolation demo with your code and the result doesn't look too bad.
If there is any feature that still doesn't work as expected, please don't hesitate to let us know.

Code: Select all

        public Form1()
        {
            InitializeComponent();
            InitializeChart();
        }

        int SeriesIndex, ValueIndex;

        NearestPoint _NearestPointTool;
        Annotation _AnnotationTool;

        private void InitializeChart()
        {
            chartController1.Chart = tChart1;
            tChart1.Aspect.View3D = false;

            for (int i = 0; i < 10; i++)
            {
                new FastLine(tChart1.Chart);
                tChart1[i].FillSampleValues(1000);
            }

            _AnnotationTool = new Annotation(tChart1.Chart);
            _NearestPointTool = new NearestPoint(tChart1.Chart);

            tChart1.MouseMove += new MouseEventHandler(tChart1_MouseMove);
            tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(tChart1_AfterDraw);
        }

        void tChart1_MouseMove(object sender, MouseEventArgs e)
        {
            tChart1.Header.Text = "";
            CalculateNearestPoint(e);
            if (tChart1.Series[0] is Steema.TeeChart.Styles.FastLine)
            {
                _AnnotationTool.Text = "Series: " + tChart1.Series[SeriesIndex].Title + " - ValueIndex: " + tChart1.Series[SeriesIndex].YValues[ValueIndex].ToString();                
                _AnnotationTool.Left = e.X + 5;
                _AnnotationTool.Top = e.Y - 25;
            }
        }

        void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
        {
            double xval = tChart1.Series[SeriesIndex].XValues[ValueIndex];
            int xs = tChart1.Axes.Bottom.CalcXPosValue(xval);
            int ys;
            g.Brush.Visible = true;
            g.Brush.Solid = true;
            
            if (tChart1.Series[SeriesIndex] is Steema.TeeChart.Styles.FastLine)
            {
                ys = tChart1.Series[SeriesIndex].GetVertAxis.CalcYPosValue(InterpolateLineSeries(tChart1.Series[SeriesIndex] as Steema.TeeChart.Styles.FastLine, xval));
                g.Brush.Color = tChart1.Series[SeriesIndex].Color;
                g.Line(xs, tChart1.Axes.Left.CalcYPosValue(0), xs, ys);
                g.Ellipse(new Rectangle(xs - 4, ys - 4, 8, 8));
            }
        }

        private double InterpolateLineSeries(Steema.TeeChart.Styles.FastLine series, int firstindex, int lastindex, double xvalue)
        {
            int index;
            for (index = firstindex; index <= lastindex; index++)
            {
                if (index == -1 || series.XValues.Value[index] > xvalue) break;
            }
            // safeguard
            if (index < 1) index = 1;
            else if (index >= series.Count) index = series.Count - 1;
            double dx = series.XValues[index] - series.XValues[index - 1];
            double dy = series.YValues[index] - series.YValues[index - 1];
            if (dx != 0.0) return dy * (xvalue - series.XValues[index - 1]) / dx + series.YValues[index - 1];
            else return 0.0;
        }

        private double InterpolateLineSeries(Steema.TeeChart.Styles.FastLine series, double xvalue)
        {
            return InterpolateLineSeries(series, series.FirstVisibleIndex, series.LastVisibleIndex, xvalue);
        }

        private void CalculateNearestPoint(MouseEventArgs e)
        {
            int[] NearestPoints;
            double Dist, tmp;
            Point P1, P2;

            NearestPoints = new int[tChart1.Series.Count];
            P1 = new Point(0, 0);
            P2 = new Point(tChart1.Width, tChart1.Height);
            SeriesIndex = 0;
            ValueIndex = 0;

            for (int i = 0; i < NearestPoints.Length; i++)
            {
                _NearestPointTool.Series = tChart1.Series[i];
                NearestPoints[i] = _NearestPointTool.GetNearestPoint(new Point(e.X, e.Y));
            }

            _NearestPointTool.Series = null;

            Dist = Distance(P1, P2);
            for (int i = 0; i < NearestPoints.Length; i++)
            {
                if (NearestPoints[i] > -1)
                {
                    P1.X = tChart1.Series[i].CalcXPos(NearestPoints[i]);
                    P1.Y = tChart1.Series[i].CalcYPos(NearestPoints[i]);
                    P2.X = e.X;
                    P2.Y = e.Y;
                    tmp = Distance(P1, P2);

                    if ((i == 0) || (tmp < Dist))
                    {
                        Dist = tmp;
                        SeriesIndex = i;
                        ValueIndex = NearestPoints[i];
                    }
                }
            }
        }

        private double Distance(Point Pt1, Point Pt2)
        {
            int dx, dy;

            dx = Pt1.X - Pt2.X;
            dy = Pt1.Y - Pt2.Y;

            return Math.Sqrt((dx * dx) + (dy * dy));
        }
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Nitin
Newbie
Newbie
Posts: 52
Joined: Fri Jun 30, 2006 12:00 am

Re: Draw line tool behaving strange

Post by Nitin » Fri Aug 14, 2009 12:09 pm

Thanks for your reply Yeray. I have implemented the way you have suggested. It is working fine. But there is performance issue with it. If i have 2 serieses and each of the series is having 250000 data points in it then the below part of the code is becoming a performance issue.

Code: Select all

    
    private double InterpolateLineSeries(Steema.TeeChart.Styles.FastLine _Series, int FirstVisibleIndex, int LastVisibleIndex, double xvalue)
    {
            int index;
            for (index = FirstVisibleIndex; index <= LastVisibleIndex; index++)
            {
                if (index == -1 || _Series.XValues.Value[index] > xvalue) break;
            }
    }
Because if the mouse position goes to the end of X-axis then i have to iterate through the whole data series of 250000 data points to get the index value.

Yeray
Site Admin
Site Admin
Posts: 9612
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Draw line tool behaving strange

Post by Yeray » Fri Aug 14, 2009 12:52 pm

Hi Nitin,

Well, if your XValues are ordered you always can apply a searching algorithm to improve the performance considerably.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply