, 스크롤

실제 통계자료는 데이터가 너무 방대해 한 화면에 다 보여줄 수 없다. 많은 데이터를 차트에 표시해 보자.

 

private void Form1_Load(object sender, EventArgs e)

{

       chart1.Legends[0].Enabled = false;

       Random R = new Random(100);

       double value = 10;

       for (int i = 0;i<200;i++)

       {

                  value += R.Next(-4, 5);

                  chart1.Series[0].Points.AddY(value);

       }

       Axis ax = chart1.ChartAreas[0].AxisX;

       Axis ay = chart1.ChartAreas[0].AxisY;

       chart1.Series[0].ChartType = SeriesChartType.Area;

}

 

10에서 시작하여 +-4만큼 오르락내리락거리는 200개의 무작위 데이터를 생성했으며 차트 타입은 Area로 지정하였다. X축은 0 ~ 199까지의 순서값이다.

대충의 증감 정도는 파악할 수 있지만 특정 시점의 값이 얼마인지 한눈에 가늠하기 어렵다. 데이터가 많을수록 자세히 보기 어렵다. 이럴 때는 줌, 스크롤 등의 기법을 사용하여 원하는 부분만 확대하고 스크롤해서 봐야 한다. 다음 코드 한줄을 추가해 보자.

 

ax.ScaleView.Zoom(50, 70);

 

ScaleViewZoom 메서드로 범위를 지정하면 이 범위만 확대해서 보여준다. X축을 50 ~ 70까지의 범위만 보인다.

범위 바깥은 잘려서 보이지 않지만 아래쪽에 스크롤 바가 생겨 이동할 수 있다. Y축도 마찬가지로 일정 범위로 제한하면 전체 차트의 한 부분만 보게 된다.

메서드가 아닌 실행중에 사용자가 선택한 부분만 확대해서 보려면 Cursor, ScaleView, ScrollBar 세 개의 객체를 다 알아야 한다. 하나씩 연구해 보자.

Cursor는 축의 현재 위치를 알려 주는 선이다. X축의 커서는 수직선이고 Y축의 커서는 수평선이며 두 선이 만나는 곳이 사용자가 관심을 가지는 부분이다. 커서는 ChartAreaCursorX, CursorY 속성으로 제어하며 둘 다 Cursor 타입이다. 주요 속성은 다음과 같다.

 

속성

설명

Is​User​Enabled

사용자가 커서를 제어할 수 있는지를 지정한다. 디폴트는 false여서 사용자가 클릭해서 커서를 표시할 수 없다. 이 속성과 상관없이 코드에서 Position 속성을 통해 커스를 표시할 수는 있다.

Position

커서의 현재 위치이다. 코드에서 이 속성을 변경할 수 있으며 커서를 숨길 때는 이 속성을 NaN으로 지정한다.

Is​User​Selection​Enabled

사용자가 영역을 드래그하여 일정 범위를 선택할 수 있는지를 지정한다. 디폴트는 false이다.

Auto​Scroll

영역 선택중에 경계 밖으로 커서가 이동하면 자동으로 스크롤할 것인지를 지정한다. 자동 스크롤이 가능하려면 스크롤하는 방향으로 데이터가 더 있어야 한다. 디폴트는 false이다.

Selection​Color

선택 영역의 색상이다. 디폴트는 알파값이 120LightGray이며 반투명하다. 양축을 다 지정할 경우 Y축 색상을 사용한다.

Selection​Start

Selection​End

선택영역의 시작과 끝, 즉 선택 범위이다. 사용자가 드래그하여 범위를 설정하면 이 값이 변경되며 코드에서 Set​Selection​Position 메서드로 선택 영역을 지정한다. 선택을 해제하려면 둘 다 NaN으로 지정한다.

LineColor

LineDashStyle

LineWidth

선의 색상, 모양, 굵기이다. 디폴트는 1픽셀 굵기의 빨간 실선이다.

Interval

IntervalType

IntervalOffset

IntervalOffsetType

커서가 나타날 수 있는 간격이다. 디폴트는 0이며 차트의 어느 위치에나 커서를 배치할 수 있다. 간격을 5로 지정하면 5의 배수 위치에만 커서가 표시되며 영역을 선택할 때도 같은 방식으로 적용된다. Position 속성을 직접 지정할 때는 이 간격을 무시한다.

Axis​Type

커서가 부착된 축이 주축인지, 부축인지를 지정한다.

 

Zoom 메서드 호출문은 제거하고 다음 코드를 작성한다. 사용자가 커서를 다룰 수 있도록 했으며 선은 3픽셀 두께로 하여 잘 보이도록 했다. 간격은 X축은 20, Y축은 10으로 지정했다.

 

chart1.ChartAreas[0].CursorX.IsUserEnabled = Enabled;

chart1.ChartAreas[0].CursorY.IsUserEnabled = Enabled;

chart1.ChartAreas[0].CursorX.LineWidth = 3;

chart1.ChartAreas[0].CursorY.LineWidth = 3;

chart1.ChartAreas[0].CursorX.Interval = 20;

chart1.ChartAreas[0].CursorY.Interval = 10;

 

실행 후 차트의 한 지점을 클릭하면 빨간색 수평, 수직선이 나타나며 두 점이 만나는 곳이 사용자가 클릭한 곳이다.

, 간격을 지정해 놓았기 때문에 정확히 클릭한 곳이 아닌 간격의 배수 위치에만 커서가 나타난다. Interval0으로 지정하면 임의 위치에 커서를 놓을 수 있다. 다음 코드는 사용자가 드래그하여 영역을 선택한다.

 

chart1.ChartAreas[0].CursorX.IsUserSelectionEnabled = Enabled;

chart1.ChartAreas[0].CursorX.AutoScroll = true;

chart1.ChartAreas[0].CursorY.IsUserSelectionEnabled = Enabled;

 

X축에 대해서만 자동 스크롤 기능을 켰다. 차트의 임의 영역을 드래그하면 반투명한 회색 영역이 나타난다.

이 상태에서 마우스를 놓으면 선택한 영역이 확대되며 스크롤 바가 나타난다. 스크롤바를 드래그하거나 양쪽의 버튼 또는 몸통을 클릭하여 임의의 위치로 이동할 수 있다.

확대한 상태에서 수평으로 영역을 확장할 때는 자동으로 스크롤된다. 수직쪽으로는 AutoScroll 속성을 주지 않아 자동 스크롤되지 않는다. 확대한 상태에서 영역을 다시 선택하여 더 좁은 범위를 확대할 수 있으며 제한은 없다. 스크롤 바 왼쪽과 위의 리셋 버튼을 누르면 직전 줌 상태로 복귀한다.

차트를 확장하면 전체 영역중 일부만 보이는데 이 일부만 표시하는 주체가 스케일뷰이다. 축의 ScaleView 속성으로 되어 있으며 AxisScaleView 클래스 타입의 객체이다. 이 객체의 속성을 통해 확대, 스크롤의 여러 정보를 조사하거나 설정한다.

 

속성

설명

Zoomable

사용자에 의해 줌 가능한 상태인지를 정의한다. 디폴트는 true이다.

Is​Zoomed

현재 줌 상태인가 아닌가를 조사하는 읽기 전용 속성이다. 최초 false이다가 사용자가 영역을 선택해 확대하면 true가 된다.

Min​Size

Min​Size​Type

스케일뷰의 최소 크기를 지정한다. 이 크기 이상으로는 더 확대되지 않는다.

Position

스케일뷰의 현재 위치이다.

Size

Size​Type

스케일뷰의 현재 크기이다.

View​Minimum

View​Maximum

축의 최소값과 최대값이다. 현재 표시하는 범위를 보여 주는 읽기 전용 속성이다.

Small​Scroll​Size

Small​Scroll​Size​Type

스크롤 바의 화살표 버튼을 클릭할 때 스크롤될 양인 작은 스크롤값이다. 디폴트는 NaN이며 자동으로 결정한다.

Small​Scroll​Min​Size

Small​Scroll​Min​Size​Type

작은 스크롤의 최소값이다. 작은 스크롤 크기를 지정하지 않았을 때 이 값을 사용한다.

 

스케일뷰를 디폴트 설정대로 두면 얼마든지 확대 가능하다. 그러나 MinSize를 지정하면 이 이상은 확대되지 않는다. 다음과 같이 설정하면 X, Y 양쪽으로 최소한 50 이상의 뷰를 확보한다. 값의 변화를 충분히 확인할 수 있다면 굳이 더 확대할 필요는 없다.

 

ax.ScaleView.MinSize = 50;

ay.ScaleView.MinSize = 50;

 

나머지 정보는 스케일뷰의 현재 상태를 조사 또는 설정하는 값이다. 줌 상태 변화에 의해 이 값이 어떻게 바뀌는지 찍어 보자. 차트의 Click 이벤트 핸들러를 작성하고 속성값을 조사한 후 타이틀바에 찍어 보면 된다.

 

private void chart1_Click(object sender, EventArgs e)

{

       Text = String.Format("Pos = {0}, Size = {1}, Min = {2}, Max = {3}",

                  chart1.ChartAreas[0].AxisX.ScaleView.Position,

                  chart1.ChartAreas[0].AxisX.ScaleView.Size,

                  chart1.ChartAreas[0].AxisX.ScaleView.ViewMinimum,

                  chart1.ChartAreas[0].AxisX.ScaleView.ViewMaximum);

}

 

편의상 X축만 찍어 봤는데 Y축도 마찬가지이다. 최초 실행시, 즉 확대하지 않았을 때는 PosSizeNaN이고 Min = 0, Max = 201로 조사된다. 드래그하여 영역을 적당히 확대해 보자.

X축의 현재 위치가 37이고 폭은 83이며 36 ~ 121까지의 범위를 보여 주고 있다는 뜻이다. 위치는 Zero Base여서 36번째 X좌표가 37번째 값인데 비해 Min, Max는 축의 X값을 그대로 보여준다. PositionSize는 쓰기도 가능해서 이 값을 변경하면 줌 위치와 크기가 즉시 바뀐다. 클릭 이벤트 끝에 다음 코드를 작성해 보자.

 

chart1.ChartAreas[0].AxisX.ScaleView.Position = 50;

chart1.ChartAreas[0].AxisX.ScaleView.Size = 80;

 

폭이 80이 되도록 즉시 확대되며 왼쪽 위치는 50에 맞추어진다. 코드에서 확대나 스크롤을 할 때는 속성을 직접 변경하는 것보다는 메서드를 사용하는 것이 더 편리하다.

 

void Zoom (double viewStart, double viewEnd);

void Zoom (double viewPosition, double viewSize, DateTimeIntervalType viewSizeType, bool saveState);

void Scroll (double newPosition);

void Scroll (DateTime newPosition);

void ZoomReset ();

void ZoomReset (int numberOfViews);

 

시작과 끝 범위를 지정하거나 위치와 크기를 지정하는 방식으로 확대한다. saveState 인수를 true로 지정하면 각 확대 상태를 내부적으로 저장해 둔다. Scroll 메서드는 이동할 지점을 지정하되 double 타입과 DateTime을 둘 다 지원한다. Click 메서드의 앞쪽에 다음 코드를 작성해 보자.

 

chart1.ChartAreas[0].AxisX.ScaleView.Zoom(50, 100);

chart1.ChartAreas[0].AxisX.ScaleView.Scroll(70);

 

50 ~ 100까지를 표시할 크기로 확대하고 스크롤 위치는 70에 맞춘다. 차트를 클릭하면 즉시 확대하고 위치 이동까지 완료한다.

ZoomReset 메서드는 한 단계만 줌을 리셋한다. 여러 단계로 확대했다면 바로 직전 단계로 돌아가는 식이어서 확대한 횟수만큼 ZoomReset 메서드를 호출해야 한다. ZoomReset(0)는 모든 줌을 즉시 취소한다. 폼에 버튼을 하나 배치해 놓고 클릭 이벤트에서 Zoom 메서드를 호출해 보면 어떤 식으로 동작하는지 금방 알 수 있다.

차트를 확대하면 스크롤 바가 나타나며 사용자는 스크롤 바를 통해 원하는 곳으로 즉시 이동할 수 있다. 이 스크롤 바는 축의 ScrollBar 속성으로 관리하며 AxisScrollBar 클래스의 객체이다. 스크롤 바는 상태를 보여 주는 것이 주 임무여서 속성은 주로 스크롤 바의 모양을 정의할 뿐 동작을 제어하는 속성은 별로 없다.

 

속성

설명

Enabled

스크롤 바의 표시 여부를 지정한다. 디폴트는 true이며 확대하면 자동으로 나타난다.

Is​Visible

스크롤 바가 현재 보이는 상태인가를 조사하는 읽기 전용 속성이다.

Back​Color

스크롤 바의 배경 색상이다.

Button​Color

버튼의 색상이다.

Button​Style

어떤 버튼을 표시할 것인가를 지정한다. None은 버튼 없음, SmallScroll은 양쪽 버튼, ResetZoom은 리셋 줌 버튼이며 All은 모든 버튼을 다 표시한다.

Is​Positioned​Inside

스크롤 바를 에리어의 안에 둘 것인지 밖에 둘 것인지를 지정한다. 디폴트는 true여서 에리어 안쪽에 표시된다.

Line​Color

선의 색상이다.

Size

스크롤 바의 크기이다. 5~20까지 지정할 수 있다.

 

디폴트가 무난하게 되어 있지만 필요하다면 속성을 자유롭게 조정할 수 있다. 다음 코드를 작성하여 처음부터 확대해 놓고 Y축은 디폴트 속성대로, X축은 디폴트와 다른 속성을 주어 보자.

 

ax.ScaleView.Zoom(50, 100);

ay.ScaleView.Zoom(10, 50);

 

ax.ScrollBar.BackColor = Color.Red;

ax.ScrollBar.ButtonColor = Color.Green;

ax.ScrollBar.LineColor = Color.Blue;

ax.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;

ax.ScrollBar.IsPositionedInside = false;

ax.ScrollBar.Size = 20;

X축 스크롤바를 보면 어떤 색상이 어디에 적용되었는지 알 수 있다. 속성을 연구할 때는 이런 식으로 값을 지정해 보고 어디가 어떻게 바뀌는지 관찰해 보면 된다.