Page 1 of 1

Draw line tool behaving strange

Posted: Wed Aug 12, 2009 1:09 pm
by 9346725
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.

Re: Draw line tool behaving strange

Posted: Thu Aug 13, 2009 10:42 am
by 9346725
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.

Re: Draw line tool behaving strange

Posted: Thu Aug 13, 2009 11:16 am
by yeray
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));
        }

Re: Draw line tool behaving strange

Posted: Fri Aug 14, 2009 12:09 pm
by 9346725
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.

Re: Draw line tool behaving strange

Posted: Fri Aug 14, 2009 12:52 pm
by yeray
Hi Nitin,

Well, if your XValues are ordered you always can apply a searching algorithm to improve the performance considerably.