[TeeChart] 데이터 추적하기!!

2012. 1. 30. 12:56C#/TeeChart

 public Point ChartPoint;
        public struct Rect
        {
            public int Left;
            public int Right;
            public int Top;
            public int Bottom;
        };
        private void TrendChart_OnMouseMove(object sender, AxTeeChart.ITChartEvents_OnMouseMoveEvent e)
        {
            ((AxTChart)sender).Refresh();
            ChartPoint = new Point(e.x, e.y);
            LineChartValue(sender);
        }
     
        private int ChartSeriesValueIndexByXValue(double axvalue,object sender)
        {
            int i;
            double lastvalue;
            double dMindiff, dMaxDiff;
            AxTChart Chart = (AxTChart)(sender);
            int result = -1;
            if (Chart.Series(0).XValues.Count > 0)
            {
                lastvalue = Chart.Series(0).XValues.get_Value(Chart.Series(0).XValues.Count - 1);
                if (axvalue > lastvalue)
                {
                    result = Chart.Series(0).XValues.Count - 1;
                    return result;
                }

                for (i = 1; i < Chart.Series(0).XValues.Count - 1; i++)
                {
                    if (axvalue == Chart.Series(0).XValues.get_Value(i))
                    {
                        result = i;
                        return result;
                    }
                    else if (axvalue > lastvalue && axvalue < Chart.Series(0).XValues.get_Value(i))
                    {
                        dMindiff = Math.Abs(axvalue - lastvalue);
                        dMaxDiff = Math.Abs(axvalue - Chart.Series(0).XValues.get_Value(i));
                        if (dMindiff < dMaxDiff)
                        {
                            result = i - 1;

                        }
                        else
                        {
                            result = i;
                        }
                        return result;
                    }
                    lastvalue = Chart.Series(0).XValues.get_Value(i);

                }
            }
            return 0;
        }
        private void LineChartValue(object sender)
        {
            int x, y, i, v;
            DateTime dtTime;
            string sText;
            Rect rT;
            AxTChart ChartTocken = (AxTChart)(sender);
            double dValue;
            if (ChartTocken != null)
            {
                //1. 마우스 X좌표
                x = ChartPoint.X;
                //2. X좌표가 Chart의 영역일때만 수행
                if (x >= ChartTocken.ClientRectangle.Left && x <= ChartTocken.ClientRectangle.Right)
                {
                    //3. 마우스 X축에 해당하는 세로선 긋기
                    ChartTocken.Canvas.Pen.Color = (uint)ColorTranslator.ToOle(Color.Red);
                    ChartTocken.Canvas.MoveTo(x, ChartTocken.ClientRectangle.Bottom);
                    ChartTocken.Canvas.LineTo(x, ChartTocken.ClientRectangle.Top);
                }
                //4. Chart의 모든 Series를 검사하여 현재 X축에 해당하는 값 추출
                for (i = 0; i < ChartTocken.SeriesCount; i++)
                {
                    if(!ChartTocken.Series(i).Active)
                    {
                        continue;
                    }
                    //6. X축의 현재 값 추출
                    dtTime = DateTime.FromOADate(ChartTocken.Series(i).XScreenToValue(x));
                    //7. X축 현재 값의 순서 추출
                    //정확한 순서를 구해야 Y 축에 해당하는 값을 얻을수 있음
                    //실제 6번으로 추출된 값은 단순한 Lable값
                    v = ChartSeriesValueIndexByXValue(ChartTocken.Series(i).XScreenToValue(x), sender);
                    //8. 순서를 제대로 찾았는지 검사
                    if (v >= 0)
                    {
                        //8-1 실제 입력된 데이터의 Y값, X값, 시간, 실제값을 구한다.
                        x = ChartTocken.Series(i).CalcXPos(v);

                        dtTime = DateTime.FromOADate(ChartTocken.Series(i).XValues.get_Value(v));
                        y = ChartTocken.Series(i).CalcYPos(v);
                        dValue = ChartTocken.Series(i).YValues.get_Value(v);
                        //9. 값 위치에 표시될 Mark 크기, 위치 설정
                        rT.Left = x - 2;
                        rT.Right = x + 2;
                        rT.Top = y - 2;
                        rT.Bottom = y + 2;
                        //10 값 위치에 Mark 표시
                        ChartTocken.Canvas.Pen.Color = ChartTocken.Series(i).Color;
                        ChartTocken.Canvas.Brush.Style = 0;
                        ChartTocken.Canvas.Brush.Color = ChartTocken.Series(i).Color;
                        ChartTocken.Canvas.Rectangle(rT.Left, rT.Top, rT.Right, rT.Bottom);

                        //10-1 값 주변에 정보 표시
                        ChartTocken.Canvas.Pen.Color = ChartTocken.Series(i).Color;
                        ChartTocken.Canvas.Brush.Color = ChartTocken.Series(i).Color;
                        ChartTocken.Canvas.Font.Size = 8;
                        //10-2 텍스트출력
                        ChartTocken.Canvas.Font.Name = "Arial";
                        ChartTocken.Canvas.Font.Color = (uint)ColorTranslator.ToOle(Color.White);
                        ChartTocken.Canvas.Font.Size = 8;
                        //10-2 텍스트출력
                        sText = ChartTocken.Series(i).Title + ":" + dtTime.ToString("dd HH:mm") +":"+ dValue.ToString();
                        ChartTocken.Canvas.TextOut(x + 10, y - 25, sText);
                        //11 텍스트에 언더바 밑줄 그리기
                        ChartTocken.Canvas.Pen.Color = (uint)ColorTranslator.ToOle(Color.Red);
                        ChartTocken.Canvas.MoveTo(x + 7, y - 10);
                        ChartTocken.Canvas.LineTo(x + 7 + (int)(Math.Truncate(sText.Length * 5.5)), y - 10);
                        //12 언더바와 값 Mark 사이에 선긋기
                        ChartTocken.Canvas.Pen.Color = (uint)ColorTranslator.ToOle(Color.Red);
                        ChartTocken.Canvas.MoveTo(x, y);
                        ChartTocken.Canvas.LineTo(x + 7, y - 10);

                    }
                }
            }
        }