ScottPlot (Growing Data - #1)

Software/C#|2023. 2. 16. 11:40
반응형

C# 으로 개발툴을 변경하면서 고민중에 하나가 자주 사용하는 차트 컴포넌트를 어떻게 할 것인가 였는데 ScottPlot 컴포넌트를 발견하고는 유레카를 외쳤습니다.. 무료인데다 기능도 아주 뛰어나고 사용성에 있어서도 만족사용 하게 되었습니다.. 무엇보다도 Multi Axis 을 많이 사용하는 제 입장에서는 너무 반가운 컴포넌트 였습니다. 

하지만 딱 한가지 아쉬운 부분이 시간의 경과에 따라 데이타가 늘어나는 그래프를 그릴 경우가 많이 있는데 특히 번인장비의 경우 시간에 따른 샘플의 특성 변화를 그래프로 실시간 보여주게 되는데 이게 ScottPlot 에서는 좀 간단하지가 않습니다. 

이번 장에서는 기본적으로 ScottPlot 에서 Growing Data를 그리는 방법을 코딩합니다. ScottPlot 예제에서 나오는 방법을 조금 수정해서 코딩하였습니다. 

 

 

1. 먼제 아래와 같이 측정데이타를 저장할 Class를 하나 만들어 줍니다.

public class MeasuredData
{
    public readonly double[] YAxis;    // 실제 측정데이타가 저장될 배열
    public int index { get; set; } = 0;    // 측정된 데이타의 갯수에 대한 index

    public MeasuredData()
    {
        YAxis = new double[10000];  // 배열의 갯수는 측정될 데이타의 최대 갯수보다 크게 설정 합니다. ( 이부분이 좀 문제)
    }
}

 

2. 타이머를 이용하여 주기적으로 데이타가 랜덤으로 생성되도록 코드를 작성하여 테스트 했습니다.

public partial class Form1 : Form
{
    private readonly  MeasuredData measuredData = new MeasuredData();
    private Random random = new Random();
    private readonly ScottPlot.Plottable.SignalPlot SignalPlot;  // 출력 데이타의 시그날 위치를 제어하게 됩니다. 
    //---------------------------------------------------------------------------------------------------
    public Form1()
    {
        InitializeComponent();
        SignalPlot = formsPlot1.Plot.AddSignal(measuredData.YAxis);  // 실제 화면에 표시될 시그날 정보와 생성된 시스날을 맵핑합니다. 
        SignalPlot.MaxRenderIndex = 0;                                                  // 출력될 시그날의 초기 위치를 설정(이걸 안하면 10000개의 데이타가 다 보입니다.)
        formsPlot1.Plot.SetAxisLimits(0, 10, -2, 2);     // 그래프 출력 Limit 설정  

        formsPlot1.Refresh();   // 이 부분을 안하면 ScottPlot 그래프 화면에 오류메시지가 보입니다. 
    }
   //---------------------------------------------------------------------------------------------------
    private void timer1_Tick(object sender, EventArgs e)      // 타이머 이벤트( 1초에 한번씩 데이타 생성하도록 했습니다.)
    {
        double currentRightEdge = formsPlot1.Plot.GetAxisLimits().XMax;   // 현재 그래프의 최대 X축의 값을 가져 옵니다. 
        if (measuredData.index > currentRightEdge)           // X축의 최대값이 데이타 갯수보다 작으면
        {
            formsPlot1.Plot.SetAxisLimits(xMax: currentRightEdge + 10);    // X 축의 최대값을 측정데이타 보다 10 step 많게 설정합니다. 
        }

        measuredData.YAxis[measuredData.index] = random.NextDouble();    // 랜덤으로 만들어진 값을 측정 버퍼에 넣습니다. 
        SignalPlot.MaxRenderIndex = measuredData.index++ ;                        // 그래프 화면에서 측정된 데이타 갯수 만큼만 그려 줍니다.  

        formsPlot1.Render();                                                                               // 그래프 화면 갱신 
    }
   //---------------------------------------------------------------------------------------------------
    private void button1_Click(object sender, EventArgs e)
    {
        timer1.Enabled = true;    // 타이머 시작 
    }
}

 

3. 실제 화면 에서는 아래와 같이 출력이 됩니다. 

Growing Data 출력 결과
Growing Data 출력 결과

Growing Data 출력 결과

4. 이 Growing Data 츨력은 아쉬운 부분이 좀 있습니다.

 

  (1) 이것저것 사용이 좀 번거롭다

  (2)  X 축의 증감부분을 선택할 수 없다는 것입니다. (이 부분이  가장 아쉽네요.)  무조건 1씩 증가 입니다.

  (3) 버퍼의 크기를 미리 설정해 놓아야 하는데 이게 잘못해서 실제 데이타 보다 적게 설정해 놓으면 overflow 문제가 발생할 수 있습니다.        ScottPlot 매뉴얼에도 이 부분이 명시되어 있는데 overflow 문제에 대한 오류처리를 잘 설계하거나 또는 버퍼를 충분히 설정해야 합니다.

 

 

반응형

댓글()