C#으로 chart 컨트롤을 사용하는 기본적인 방법에 대해서 이전 포스트에서 알아보았는데 여기에서는 여러 개의 그래프를 하나의 창에 도시하는 방법과 축의 분리에 대해서 알아보도록 하겠다.


 Chart 객체는 여러 개의 Series 그리고 한 개 이상의 ChartArea 객체를 콜렉션 멤버로 가지고 있으며 chart1.Series 와 chart1.ChartArea 같이 접근할 수 있다.


  • Series 객체는 도시할 그래프를 구성하는 점의 집합

  • ChartArea 객체는 그래프를 보여줄 영역


ChartArea는 초기에 한 개가 미리 생성되어 있고 chart1.ChartArea[0] 혹은 chart1.ChartArea[“ChartArea1”]와 같이 인덱스나 이름(문자열)로 접근할 수 있다. Series 객체도 초기에 하나가 생성되어 있으며 ChartArea[0]에 연결되어 있다. 그리고 사용자가 새로 생성되는 Series 객체는 이 default ChartArea와 자동으로 연결이 된다.


private void Form1_Load(object sender, EventArgs e)
{
   chart1.Series.Clear(); //default series를 삭제한다.
   Series series1 = chart1.Series.Add("graph1");
   series1.ChartType = SeriesChartType.Line;
   for (double k=0;k<2*Math.PI;k+=0.1)
   {
       series1.Points.AddXY(k, Math.Sin(k));
   }

   Series series2 = chart1.Series.Add("graph2");
   series2.ChartType = SeriesChartType.Line;
   for (double k = 0; k < 2 * Math.PI; k += 0.1)
   {
       series2.Points.AddXY(k, Math.Cos(k) - 2.0);
   }
}


위와 같이 생성된 Series객체 두 개 모두 ChartArea[0]로 (자동으로) 연결되며 이전 포스트에서 보여준 바와 같이 x축과 y축이 모두 공유된다.


 그런데 같은 영역의 두 그래프의 축을 분리할 수도 있다. 예를 들어 y축 스케일이 다른 두 개의 그래프를 하나의 영역에 겹쳐서 도시하고 싶다면 다음과 같이 하면 된다.


series2.YAxisType = AxisType.Secondary;


이렇게 하면 두 개의 그래프의 x축은 공통이고 분리된 y축의 스케일이 그래프 우측에 표시된다.



이 결과를 보면 그래프영역 우측의 y축에 secondary 축의 단위가 표시됨을 알 수 있다. Series.XAxisType 이나 Seires.YAxisType 프로퍼티는 별도로 지정하지 않으면 AxisType.Primary 로 자동 지정된다.


여기서 한 가지 알아두어야 할 것은 series1과 series2는 y축만 분리되었고 x축은 공통이기 때문에 다음과 같이 x축의 범위를 변경하면 둘 다 영향을 받는다는 점이다.


chart1.ChartAreas[0].AxisX.Minimum = 2.0;
chart1.ChartAreas[0].AxisX.Maximum = 4.0;



하지만 AxisY의 범위를 조절하면 series1만 영향을 받는다.


chart1.ChartAreas[0].AxisY.Minimum = -0.5;
chart1.ChartAreas[0].AxisY.Maximum = 0.5;



series2의 y축 범위를 조절하려면 다음과 같이 하면 된다.


chart1.ChartAreas[0].AxisY2.Minimum = -2.5;
chart1.ChartAreas[0].AxisY2.Maximum = -1.5;



이번에는 series2의 y축 범위만 조정되었음을 알 수 있다.


이와 같이 하나의 ChartArea에 여러 개의 Series 들을 도시할 수 있는데 각 Series의 축을 분리할 수 있으며 x축만 분리할 수도 있고 y축만 분리할 수도 있으며 둘 다 분리할 수도 있다.





Posted by 살레시오
,

 윈도우스 폼프로그래밍에서 그래프나 차트를 그리기 위한 콘트롤로 chart 라는 것이 있다. (.net 4.5부터인가 지원하기 시작함) 이것을 이용하면 간단한 그래프를 작성하는데 외부 라이브러리(예를 들어 oxyplot)를 사용할 필요가 없다.


 비주얼 스튜디오로 winForm 프로젝트를 하나 생성하여 도구상자에서 chart를 끌어다가 적당히 위치시킨 후 docking 시킨다.



그러면 chart1이라는 인스턴스가 생성되는데 이것를 이용하여 그래프를 제어할 수 있다.



using System.Windows.Forms.DataVisualization.Charting;
private void Form1_Load(object sender, EventArgs e)
{
 chart1.Series.Clear(); //default series를 삭제한다.
 Series sSin = chart1.Series.Add("sin"); //새로운 series 생성
 sSin.ChartType = SeriesChartType.Line; //그래프 모양을 '선'으로 지정
 //데이터 포인트 저장
 for (double k=0;k<2*Math.PI;k+=0.1)
 {
      sSin.Points.AddXY(k, Math.Sin(k));
 }
}


결과 화면은 다음과 같다.



한 화면에 다수의 그래프를 그릴 수도 있는데 Series 객체만 추가시켜주면 된다.


private void Form1_Load(object sender, EventArgs e)
{
   chart1.Series.Clear(); //default series를 삭제한다.
   Series sSin = chart1.Series.Add("sin"); //새로운 series 생성
   sSin.ChartType = SeriesChartType.Line; //그래프를 '선'으로 지정
   //데이터 포인트 저장
   for (double k=0;k<2*Math.PI;k+=0.1)
   {
       sSin.Points.AddXY(k, Math.Sin(k));
   }
           
   // 같은 화면에 그래프 추가
   Series sCos = chart1.Series.Add("cos"); //새로운 series 생성
   sCos.ChartType = SeriesChartType.Line;
   for (double k = 0; k < 2 * Math.PI; k += 0.1)
   {
       sCos.Points.AddXY(k, Math.Cos(k));
   }
}


그러면 다음과 같이 두개의 그래프가 그려진다.



chart콘트롤은 Series객체가 갱신될 때마다(즉, 데이터 포인트가 추가될때마다) 자동으로 그래프 영역을 갱신시켜 준다.




Posted by 살레시오
,

 C# 6.0은 이전 버전의 메이져 업그레이드가 아니라 사용자 편의성을 높일 자잘한 기능들이 추가되었는데 문자열 보간도 그 중 하나이다. 예를 들어서 문자열의 중간에 변수의 값을 넣고 싶다면 String.Format()함수를 이용하였다.


str = String.Format(“da is {0}.\r\n”, da);


또는 Console.Writeln함수에서도 이런 형식을 입력할 수 있다.


Console.Writeln(“da is {0}.\r\n”, da);


C# 6.0에서는 이것보다 더 간단한 표현식을 제공한다.


str = $“da is {da}.\r\n”;
Console.Writeln($“da is {da}.\r\n”);


위와 같이 문자열 앞에 $를 붙이면 문자열 내부의 {...}안에 변수가 바로 올 수 있다. 이것을 문자열 보간(string interpolation)이라고 하고 컴파일 시에 내부적으로 String.Format() 함수를 이용한 코드로 적절하게 해석이 된다. 이 새로운 문법이 보기에 훨씬 더 간결하다.


 이 방법으로 정렬과 표시 방법도 옵션으로 지정할 수 있다. 예를 들어서 이전에는 다음과 같이 코딩했던 것을

 

for (int ctr = 0; ctr < names.Length; ctr++)
{
 Console.WriteLine("{0,-20} {1,5:N1}", names[ctr], hours[ctr]);
}

유사하게 문자열 앞에 ‘$’를 붙이고 {...} 안에서는 번호(인덱스) 대신 변수명으로 대신하여 사용할 수 있다.


for (int ctr = 0; ctr < names.Length; ctr++)
{
  Console.WriteLine($"{names[ctr],-20} {hours[ctr],5:N1}");
}

여기에서 첫 번째 변수는 20칸 좌정렬이 되고 두 번째 변수는 5칸 우정렬에  N1형식으로 표시된다.



Posted by 살레시오
,

 비주얼 스튜디오 (Visual Studio, 이하 VS) 는 마이크로소프트(MS) 사의 대표적인 개발툴이다. MS가 2000년대 초반에 .NET framework을 발표하면서 비주얼 베이직, 비쥬얼 C++ 등과 같은 기존의 프로그래밍 언어 외에 C#이라는 새로운 언어를 발표했는데 이것이 .NET의 핵심 언어로서 현재는 버젼이 4.x이다. 이름에서 유추할 수 있듯이 C#은 C/C++에 뿌리를 둔 객체 지향 언어인데 C++과 JAVA의 장점을 계승한 최신의 개념이 들어간 언어이다. 실제 사용해 보면 JAVA보다도 더 편리한 문법과 무엇보다도 비주얼 스튜디오라는 최고의 개발툴 때문에 쾌적하게 코딩을 할 수 있다. JAVA를 시작할 때는 어느 IDE를 사용해야 하는가부터 고민해야 하지만 C#의 경우는 (윈도를 사용한다면) 그럴 필요가 없다.



C언어 정도만 어느 정도 알고서 C#을 공부하면서 감탄을 많이 했던 기억이 난다. 이런 것도 있구나. ('포인터가 없어!'하고 놀랐던 기억도) 무엇보다도 어렵게만 느껴졌던 윈도우 프로그래밍이 폼(form)이라는 객체들을 이용하여 이용하여 직관적으로(드래그 & 드랍) 디자인하고 개별 폼 뒤에 동작하는 코드 조각을 작성하여 전체를 짜맞추어 나가는 과정이 상대적으로 쉽게 느껴졌다. 지금은 또 WPF라는 차세대 개발 방법까지 나와 있지만 내 경우에는  {윈도우 프로그래밍 == 폼 프로그래밍} 으로  인식되어 있다.


그런데 아무리 좋은 언어라도 개발 환경이 고가라면 역시 쉽게 접근하기 어려울 것이다. 하지만 VS Express라는 이름으로 MS사는 개발툴을 무료로 배포하고 있었는데 요즈음에는 아예 .net framework 를 오픈소스로 공개하고 개발툴도 무료로 배포하고 있다. 심지어 이 무료툴로 상용 프로그램을 개발해서 판매를 하더라도 아무런 제약이 없다. 앞으로는 C#으로 맥용 뿐만 아니라 (자바와 같이) 리눅스 앱도 만들 수 있게 될 것이라고 한다. 또한 윈도우에서만 쓸 수 있던 개발 환경이 멀티 플랫폼으로 옮겨가고 있으니 전에는 상상도 못 했던 일이다.




Posted by 살레시오
,

생성된 plot  control 에 축을 추가했다면 그림을 도시할 데이터를 등록해야 되는데 이것을LineSeries라고 한다.


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

      plot1.Model.PlotType = PlotType.XY;

      LineSeries s1 = new LineSeries { Title = "Data1",                         StrokeThickness = 1 };

      plot1.Model.Series.Add(s1);

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


이제 실제 데이터를 추가해야 하는데 다음과 같이 한다.


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

       s1.Points.Add(new DataPoint(dTm, dAngle));

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


이런식으로 DataPoint를 추가시키면 이 점들을 선으로 이어주는 그래프를 생성한다. 현재까지 등록된 점들을 이용해서 그래프를 갱신시키려면 RefreshPlot()함수를 호출한다.


    ------------------------------------------------------------------       plot1.Model.RefreshPlot(true);

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


이것이 가장 기본적인 사용법이다.


  만약 실시간으로 데이터가 들어온다면 그 데이터를 DataPoint로 추가시킨 다음 갱신시키면 된다.


Posted by 살레시오
,

오랜만에 다시 oxyplot 라이브러리를 사용하려하니 사용법이 잘 생각나지 않아서 여기에 정리하려고 한다. 일단 Visual Studio 2012 (Express)에서 windows form 을 하나 생성한다.


1. 솔루션탐색기에서 Reference(참조)에서 오른클릭하여 [NuGet 패키지관리] 라는 항목을 선택한다. 이 창에서 oxyplot.WindowsForms 을 검색한 후 설치한다. (전에는 일일이 인터넷으로 다운로드 해서 dll을 추가했었는데 참 편리해졌다.)




그러면 Reference에 다음과 같이 OxyPlot 과 OxyPlot.WindowsForms 가 생성된다.




2. 이제 tool box(툴박스)에 plot control을 추가해야 한다. 그러기 위해서는 다음 단계를 따른다.


  • 도구상자 안에서 오른클릭하여 [항목 선택(choose item..)]을 선택한다.
  • [.NET framework 구성요소] 탭에서 [찾아보기] 버튼을 클릭한다
  • 솔루션 폴더에 보면 packages라는 폴더가 생성되었을 것이다. 여기서 OxyPlotWindowsForms.dll 파일을 찾아서 [열기]버튼을 누른다. 그러면 [.NET framework 구성요소] 탭에 Plot 이라는 항목이 생긴다. [확인]버튼을 누른다.
  • 이제 도구상자에 Plot이라는 control이 생겼다. 이것을 원하는 영역으로 끌어서 놓으면 된다.



3. 다음과 같은 namespace를 추가한다.

     using OxyPlot;

     using OxyPlot.Axes;

그리고 다음 코드는 PlotModel 객체를 생성한 후 여기에 x축과 y축을 추가하고 control에 붙이는 예제이다.


        private void Form1_Load(object sender, EventArgs e)

        {

            PlotModel pm = new PlotModel();

            var lnrAxsX = new LinearAxis(AxisPosition.Bottom, 0, 60, 10, 5);

            lnrAxsX.MajorGridlineStyle = LineStyle.Dash;

            lnrAxsX.MinorGridlineStyle = LineStyle.Dot;

            var lnrAxsY = new LinearAxis(AxisPosition.Left, -300, 300, 60, 10);

            lnrAxsY.MajorGridlineStyle = LineStyle.Dash;

            lnrAxsY.MinorGridlineStyle = LineStyle.Dot;

            pm.Axes.Add(lnrAxsX);

            pm.Axes.Add(lnrAxsY);

            plot1.Model = pm;

        }


이것을 실행하면 다음과 같은 그래프창이 생성된다.




Posted by 살레시오
,