본문 바로가기

개 발코딩

[C#] DevExpress로 실시간 그래프(차트) 만들기

(움직이는)실시간 그래프 다양한 차트 라이브러리를 통해 작성이 가능하다.

그 중에서 가장 대중적인 것은 MS에서 기본적으로 제공해주는 MS Chart를 이용하는 것이다.

그러나 이번 글은 DevExpress를 사용하여 실시간 그래프를 만들어 보겠다.

DevExpress의 control 중에서도 chart control을 사용하겠다.

(DevExpress 설치에 관련된 내용은 홈페이지에 가면 친절하게 안내되어 있으므로 생략합니다.)


아래와 같이 프로젝트를 생성한다.




winforms common 카테고리에서 Blank application을 선택하고 프로젝트를 생성한다.





다음으로 toolbox를 열고,  아래와 같이 chart control을 윈폼 창으로 드래그 한다.




그럼 아래와 같은 차트 디자이너 창이 뜨는데 그냥 ok 버튼을 누른다.



그러면 차트 윈폼 안에 차트 영역이 생성되는데, 만약에 차트 영역이 윈폼에 가득 차기를 원한다면, 아래와 같이 Smart tag 라고 부르는 그림의 버튼을 누르고, Dock in parent Container를 클릭한다.




그러면 아래와 같이 윈폼에 꽉 차게 된다.

우측에 속성을 보면 chartControl1 이라는 이름으로 객체가 생성되었다. 여기서 이 값은 변경하지 않겠다.




다음으로 timer control을 추가하겠다. 

아래에 소스에서 다시 언급할 것이지만, 간단히 설명하자면 주기적으로 차트의 데이터를 갱신하는데 사용된다.





timer도 속성에 대해서 수정하지 않겠다.




그리고 F7을 눌러서 Form.cs 소스 에디터로 넘어간다.

그리고 아래와 같이 소스를 작성한다.



using System; using System.Drawing; using DevExpress.XtraCharts; using System.Windows.Forms; using DevExpress.Utils; namespace DXApplication2 {     public partial class Form1 : DevExpress.XtraEditors.XtraForm     {         int i = 0;         Random r = new Random();         Series[] series = new Series[2];         public Form1()         {             InitializeComponent();         }         private void Form1_Load(object sender, EventArgs e)         {             series[0= new Series("time1"ViewType.Line);             series[1= new Series("time2"ViewType.Line);             //ChartControl에 Series 추가             chartControl1.Series.Add(series[0]);             chartControl1.Series.Add(series[1]);             chartControl1.CrosshairEnabled = DefaultBoolean.False;             XYDiagram diagram = (XYDiagram)chartControl1.Diagram;             diagram.AxisY.WholeRange.MaxValue = 200;    // y축 최대값             diagram.AxisY.WholeRange.MinValue = -100;   // y축 최소값             diagram.AxisY.WholeRange.Auto = false;      // y축 범위 자동변경 설정             diagram.AxisX.WholeRange.SideMarginsValue = 0;                                      ConstantLine zeroLine = new ConstantLine();             zeroLine.Color = Color.LightYellow;                      zeroLine.AxisValue = 0;                                  zeroLine.ShowInLegend = false;             diagram.AxisY.ConstantLines.Add(zeroLine);  // y값 0인 x축 생성                                                   //diagram.EnableAxisXScrolling = true;   //스크롤과 줌은 절대              //diagram.EnableAxisXZooming = true; //true로 하지않도록 한다.                                      timer1.Interval = 400;      // 0.4초              timer1.Tick += new EventHandler(timer1_Tick);             timer1.Start();         }         private void timer1_Tick(object sender, EventArgs e)         {             if (series[0].Points.Count > 10) // x축은 10개까지만 값을 출력하게 한다.             {                 series[0].Points.RemoveAt(0);                 series[1].Points.RemoveAt(0);             }             series[0].Points.Add(new SeriesPoint(i, r.Next(-100200)));             series[1].Points.Add(new SeriesPoint(i++, r.Next(-50100)));         }     } }


지금부터 소스에 대해 설명하겠다. 

Series 객체는 그래프 그려지는 객체라고 보면 되겠다. 소스상에 배열로 선언하여 두개를 입력했으니, 두개의 라인이 표시된다. 그래프 타입은 ViewType.Line 구문에서 알수 있듯이 라인 형태이다.

chartControl1.Series.Add(series[0]);

구문을 통해 chartcontrol에 그래프를 추가한다.

XYDiagram 객체를 통해 다이어그램의 속성을 변경한다. 주석과 같이 Y축의 범위를 정하고, SideMarginValue는 X축과 선그래프와의 공백을 의미하는데, 설정하지 않으면, 아래와 같이 Y축과 공백이 생긴다.




contantLine은 X축 혹은, Y축에 선을 추가하는 것이다. 소스에서는 Y축 0의 위치에 X축과 평행하게 LightYellow 컬러의 줄을 만든다.

그리고 윈폼에서 제공되는 timer을 이용하여 주기적으로 그래프의 값을 업데이트 시킨다. 소스에서는 0.4초에 한번씩 업데이트 한다.

timer가 실행하는 timer1_Tick 메소드에는 데이터가 변경되는 내용을 넣주면 된다.

소스에서는 x축은 최고 10개까지만 찍도록 하고, 10개가 넘어가면 첫번째 찍었던 값을 지운다. 그러면 그래프가 왼쪽으로 이동한다. 값은 랜덤으로 하나는 -100에서 200사이 값으로, 다른하나는 -50에서 100 사이 값을 찍게 했다.


그럼 이제 설명은 정리하고, F5를 눌러서 잘 작동하는지 보자.

잘 동작하면 아래와 같을 것이다.





소스에서 보면, 스크롤링과 줌잉을 주석을 달아놓았다. 기본값은 false이다. 

왜 true로 변경하지 말라고 했냐면, 변경해보니 실시간의 경우, true로 설정하고 마우스로 한번만이라도 스크롤링을 하면, 새로 들어오는 데이터에 대해 현재 화면에 제대로 보여주지 못하고, 현재 시점의 데이터가 삭제 될때까지 스크롤링을 하다가 전체 그래프를 보여주고 다시 가로 스크롤을 생성하고를 반복하는 증상이 있었다.

여튼 무슨 말인지 이해 안갈수 있는데(나도 설명하는게 참 힘들다.), 아래 화면을 보면 이해가 갈 것이다.






이상으로 실시간 그래프 그리기를 마치겠다. 끗~~~~!