본문 바로가기

work/vb

[강좌 - 3] 깔끔한 차트(CHART)가 필요하십니까.(마지막 회)

출처: 데브피아/금명식(kgmoss)

[강좌 - 3] 깔끔한 차트(CHART)가 필요하십니까.(마지막 회)

부제 - 막대그래프 그리기, 그래프 보조선 나타내기



 chart7.gif


(글을 편하게 쓰겠습니다.)

이번 강좌도 전과 마찬가지로 설명을 위해 코드 중간중간에 주석 형식으로 설명을 달도록 하겠다.


A. 막대 그래프 그리기

차트를 완전히 표시 하기 위해서 MaxValue 값을 조금 크게 하였다.

아래는 막대 그래프를 그리는 코드 이다.


    If Option1.Value = True Then

    'chart 그리기

        '라인그래프

        For i = 0 To totCnt - 2            '1번

            pBox.Line ((blankValue + YgubunTxt + (i * unitWidth)) + (unitWidth * (2 / 4)), _            '2번

                        totHeight + blankValue - ((ChartData(i, 1) - MinValue) / unitHeight)) _            '3번

                        -(blankValue + YgubunTxt + ((i + 1) * unitWidth) + (unitWidth * (2 / 4)), _        '4번, 5번

                        totHeight + blankValue - ((ChartData(i + 1, 1) - MinValue) / unitHeight)), RGB(255, 0, 0)    '6번

           Next i

   

    ElseIf Option2.Value = True Then

        '막대그래프

        For i = 0 To totCnt - 1            '1번

            pBox.Line ((blankValue + YgubunTxt + (i * unitWidth)) + (unitWidth * (1 / 4)), _            '2번

                        totHeight + blankValue) _                                                                            '3번

                        -(blankValue + YgubunTxt + ((i) * unitWidth) + (unitWidth * (3 / 4)), _              '4번, 5번

                        totHeight + blankValue - ((ChartData(i, 1) - MinValue) / unitHeight)), RGB(100, 100, 255), BF    '6번, 7번

        Next i

    End If


그래프를 구분하기 위해 먼저 옵션 버튼을 2개 만들고,

Option1.Value = True 이면 라인 그래프,

Option2.Value = True 이면 막대 그래프를 그리도록 코드를 만들었다.


위의 코드에서 라인 그래프 와의 차이를 위해서 라인 그래프와 함께 있는 모습을 그대로 가져 왔다.


* 코드 설명

1번, 3번, 4번, 6번 :

        for 문의 갯수가 서로 다르다.

        막대그래프가 라인그래프 보다 하나 더 갯수가 많다.

        똑같은 그래프를 그리는데, 데이터의 갯수가 차이가 난다.  두개의 그래프 중 어느것이 틀린 것인가?

       

        아니다.  둘 다 정확한 데이터가 표시 되었다.

        왜 데이터의 갯수가 차이가 날까?  그래프의 특성 때문이다.

       

        라인 그래프는 (X1,Y1)-(X2,Y2)의 두 점이 반드시 있어야만 하나의 데이터(라인)이 표시 된다.

        막대 그래프도 물론 2개의 데이터가 있어야만 하나의 데이터(막대)를 그릴 수 잇다.

        그런데, 막대 그래프의 Y1좌표는 항상 일정하다.(번호3번)  그래서 막대 그래프는 하나의 데이터 만으로도 완전한 막대 모양이 나올 수 있다.

        그러므로 for 문의 갯수가 서로 다른 것이다.


2번, 5번 :

        막대의 넓이를 결정하는 부분이다.

        막대의 넓이는  (  1/4  <  unitWidth  <  3/4  )  즉 하나의 데이터를 표시하는 넓이(unitWidth)의 2/4 가 될 것이다.


7번 :

        라인 그래프와 다른 점이다.

        강좌 1에서 설명하였듯이 B옵션으로 사각형을 그리고, F옵션으로 그 사각형의 모양을 채운다.




B. 그래프 보조선 그리기 (먼저 예제를 실행을 해보면 이해가 쉬울 것이다.)

여기서는 마우스가 움직일때마다 그래프에서 마우스를 따라 움직이는 X,Y보조선이 나오게 할 것이다.

pBox의 MouseMove이벤트를 이용한다.


보조선을 보이기 위해서 Line컨트롤을 이용한다.

왼쪽 버튼등이 있는 구성 요소의 탭에 라인 컨트롤이 있다.


*Line컨트롤을 이용한 이유

  마우스가 움직일때 마다 그 좌표에 Line메서드를 사용하여 직접 선을 그릴 수도 있다.

  하지만, 마우스가 움직일때마다 보조선을 그리고, 지우는 작업을 반복해야 한다.

  또한 아래 원래 그래프의 모양을 복원 시켜야만 한다.

  이런 번거로운 작업을 없애기 위해 Line컨트롤을 이용한 팁이다.


아래는 해당 코드이다.


'MouseMove이벤트에서 X,Y의 값이 넘어 오는데, 이는 마우스가 현재 위치한 X,Y의 값이다.

Private Sub pBox_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

'차트 그릴때의 값들을 이용하기 위해 차트 그릴때의 모든 변수를 전역 변수로 선언하였다.

    If (totCnt <= 3) Then Exit Sub


    '현재 X좌표와 관련해서 값을 저장시켜 둔다.

    mouseX1 = ((X - blankValue - YgubunTxt) - (unitWidth / 2)) / unitWidth '전역변수로 선언된 Double 값

    mouseX2 = CInt(mouseX1)                                                                '전역변수로 선언된 Integer 값

   

    If Option2.Value = True Then    '막대 그래프일때

        '그래프가 표시될 전체 영역일 경우(보조선 안쪽) 일때만 표시한다.

        If (0 < X - blankValue - YgubunTxt) And (pBox.ScaleWidth - blankValue > X) And (0 < Y - blankValue) And (pBox.ScaleHeight - blankValue - XgubunTxt > Y) Then '데이터 표시


            '막대 그래프일 경우 막대 모양안에서만 움직이게 하기 위해 다음과 같은 IF문을 사용하였다.

            '예제 프로그램을 실행시키고, 마우스를 조금씩 움직여 보면 막대 모양이 아닌 곳에는 보조선이 움직이지 않을 것이다.

            If (mouseX2 - (1 / 4) <= mouseX1) And (mouseX2 + (1 / 4) >= mouseX1) Then


                '마땅히 차트의 값을 보여줄 곳을 만들지 않아서

                'Label 2개를 적당한 위치에 그냥 올려 놓았다.

                Label1.Caption = "일자 : " & ChartData((mouseX2), 0)

                Label2.Caption = "값 : " & ChartData((mouseX2), 1)

               

                '아래는 Line컨트롤 2개가 보일 위치이다.

                ChartLine1.Y1 = blankValue                                                    'Y값은 항상 고정이다.

                ChartLine1.Y2 = pBox.ScaleHeight - blankValue - XgubunTxt     'Y값은 항상 고정이다.

                ChartLine1.X1 = X                                                                  'MouseMove에서 넘어온 X(현재 마우스가 위치한 X 좌표)

                ChartLine1.X2 = X

               

                ChartLine2.Y1 = Y                                                                  'MouseMove에서 넘어온 Y(현재 마우스가 위치한 Y 좌표)

                ChartLine2.Y2 = Y

                ChartLine2.X1 = blankValue + YgubunTxt                                  'X값은 항상 고정이다.

                ChartLine2.X2 = pBox.ScaleWidth - blankValue                         'X값은 항상 고정이다.

            End If

        Else

            '라인 숨기기

            '모든 컨트롤은 사용자의 눈에 보이지 않으면 사용자는 없다고 느끼게 된다.

            'Visible속성을 이용할 수도 있고, 동적으로 생성하는것을 이용할 수도 있으나, 아래처럼 할 수도 있다는것을 보이기 위해 사용해 보았다.

            ChartLine1.Y1 = -1

            ChartLine1.Y2 = -1

            ChartLine1.X1 = -1

            ChartLine1.X2 = -1

           

            ChartLine2.Y1 = -1

            ChartLine2.Y2 = -1

            ChartLine2.X1 = -1

            ChartLine2.X2 = -1

           

        End If


    ElseIf Option1.Value = True Then    '라인 그래프일때

        If (0 < X - blankValue - YgubunTxt) And (pBox.ScaleWidth - blankValue > X) And (0 < Y - blankValue) And (pBox.ScaleHeight - blankValue - XgubunTxt > Y) Then '데이터 표시

               

                Label1.Caption = "일자 : " & ChartData((mouseX2), 0)

                Label2.Caption = "값 : " & ChartData((mouseX2), 1)

               

                ChartLine1.Y1 = blankValue

                ChartLine1.Y2 = pBox.ScaleHeight - blankValue - XgubunTxt

                ChartLine1.X1 = X

                ChartLine1.X2 = X

               

                ChartLine2.Y1 = Y

                ChartLine2.Y2 = Y

                ChartLine2.X1 = blankValue + YgubunTxt

                ChartLine2.X2 = pBox.ScaleWidth - blankValue

           

        Else

            '라인 숨기기

            ChartLine1.Y1 = -1

            ChartLine1.Y2 = -1

            ChartLine1.X1 = -1

            ChartLine1.X2 = -1

           

            ChartLine2.Y1 = -1

            ChartLine2.Y2 = -1

            ChartLine2.X1 = -1

            ChartLine2.X2 = -1

           

        End If

    End If

End Sub



---------------------------------------------------------------------------------------------------------------

이것으로 저의 차트 그리기 강좌는 모두 끝났습니다.

가장 간단한 형태의 기본 모형을 기준으로 설명을 했기 때문에, 실무에 직접 적용하려면 어려움을 격으실 것입니다.

저 또한 많은 모양의 차트를 그려 봤지만, 강좌에 설명된 라인, 막대 그래프를 참고하면 거의가 해결이 되었습니다.


API로 직접 작업을 해야 한다면, DC와 LineTo, MoveTo를 사용하면 별 무리 없이 사용 하실 수 있을 것입니다.


부족하지만, 이것으로 그래프 강좌는 끝마칩니다.

다음 기회에 다른 강좌로 오겠습니다. (예전에 ActiveX 도 강좌를 한다고는 혔는디...)


모두 멋진 차트를 그리시기 바랍니다~