📁 [4] 개발자 정보 & 코드 노트/C#

C# Windows Forms 강의 89편: 그래프 그리기 애플리케이션 제작 - 실시간 데이터 시각화

wawManager 2025. 5. 3. 12:00

 

1. 강의 개요

이번 강의에서는 실시간 데이터를 그래프로 시각화하는 애플리케이션을 제작합니다.
Windows Forms의 Chart 컨트롤을 활용하여
시간에 따라 변화하는 데이터를 그래프로 나타내는 기능을 구현합니다.
이 강의에서는 센서 데이터, 주식 가격, CPU 사용량과 같은 데이터를
실시간으로 업데이트하고 시각화하는 방법을 배웁니다.


2. 학습 목표

  • Chart 컨트롤을 사용하여 데이터 시각화
  • 실시간 데이터 업데이트 구현
  • 데이터 시뮬레이션으로 그래프 업데이트 테스트
  • 사용자 친화적인 그래프 UI 제작

3. 기능 요구사항

필수 기능

1️⃣ 그래프 생성 및 시각화:

  • Chart 컨트롤을 사용하여 데이터를 시각화

2️⃣ 실시간 데이터 업데이트:

  • 타이머를 활용하여 일정 간격으로 그래프 데이터 추가

3️⃣ 데이터 리셋 및 저장:

  • 그래프 데이터를 초기화하거나 CSV 파일로 저장

4️⃣ UI 구성 및 동작:

  • 직관적인 그래프 UI와 데이터 관리 버튼 제공

4. 실습: 실시간 데이터 그래프 애플리케이션 제작

1️⃣ 폼 구성

  • 폼(Form) 이름: Form1
  • 컨트롤 배치:

컨트롤 타입 이름 위치 크기

Chart chart 폼 상단 전체 (600 x 400)
Button btnStart 폼 하단 왼쪽 (100 x 30)
Button btnReset 폼 하단 중앙 (100 x 30)
Button btnSave 폼 하단 오른쪽 (100 x 30)

📌 폼 디자인 예시:

--------------------------------------------------
|          [Chart - 실시간 데이터 그래프]        |
--------------------------------------------------
| [Start 버튼] [Reset 버튼] [Save 버튼]          |
--------------------------------------------------

2️⃣ 코드 작성

(1) Chart 초기화

using System;
using System.IO;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace WindowsFormsApp_Graph
{
    public partial class Form1 : Form
    {
        private Timer _timer;
        private Random _random;

        public Form1()
        {
            InitializeComponent();
            InitializeChart();
        }

        // Chart 초기화
        private void InitializeChart()
        {
            chart.Series.Clear();

            // 데이터 시리즈 추가
            var series = new Series("Sensor Data")
            {
                ChartType = SeriesChartType.Line,
                BorderWidth = 2
            };

            chart.Series.Add(series);

            // X축, Y축 설정
            chart.ChartAreas[0].AxisX.Title = "Time (s)";
            chart.ChartAreas[0].AxisY.Title = "Value";
            chart.ChartAreas[0].AxisY.Minimum = 0;
            chart.ChartAreas[0].AxisY.Maximum = 100;

            _random = new Random();
        }
    }
}

(2) 실시간 데이터 업데이트

        // 실시간 데이터 추가
        private void StartUpdatingData()
        {
            _timer = new Timer { Interval = 1000 }; // 1초 간격
            _timer.Tick += (s, e) =>
            {
                var series = chart.Series[0];
                double newValue = _random.Next(0, 100);

                // X축 시간 값 계산
                double time = series.Points.Count;

                series.Points.AddXY(time, newValue);

                // X축 범위 업데이트
                if (series.Points.Count > 20)
                {
                    chart.ChartAreas[0].AxisX.Minimum = series.Points.Count - 20;
                    chart.ChartAreas[0].AxisX.Maximum = series.Points.Count;
                }
            };
            _timer.Start();
        }

        // 데이터 업데이트 시작
        private void btnStart_Click(object sender, EventArgs e)
        {
            StartUpdatingData();
            btnStart.Enabled = false; // 시작 버튼 비활성화
        }

(3) 데이터 리셋 및 저장

        // 데이터 리셋
        private void btnReset_Click(object sender, EventArgs e)
        {
            chart.Series[0].Points.Clear();
            chart.ChartAreas[0].AxisX.Minimum = 0;
            chart.ChartAreas[0].AxisX.Maximum = 20;

            if (_timer != null)
            {
                _timer.Stop();
                btnStart.Enabled = true; // 시작 버튼 활성화
            }
        }

        // 데이터 저장
        private void btnSave_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "CSV 파일 (*.csv)|*.csv";

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    using (var writer = new StreamWriter(saveFileDialog.FileName))
                    {
                        var series = chart.Series[0];
                        writer.WriteLine("Time,Value");

                        foreach (var point in series.Points)
                        {
                            writer.WriteLine($"{point.XValue},{point.YValues[0]}");
                        }
                    }

                    MessageBox.Show("데이터가 저장되었습니다.", "완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

(4) Designer 코드

        private void InitializeComponent()
        {
            this.chart = new Chart();
            this.btnStart = new Button();
            this.btnReset = new Button();
            this.btnSave = new Button();

            // Chart 설정
            ChartArea chartArea = new ChartArea();
            this.chart.ChartAreas.Add(chartArea);
            this.chart.Location = new System.Drawing.Point(10, 10);
            this.chart.Size = new System.Drawing.Size(600, 400);

            // Start Button 설정
            this.btnStart.Location = new System.Drawing.Point(10, 420);
            this.btnStart.Size = new System.Drawing.Size(100, 30);
            this.btnStart.Text = "Start";
            this.btnStart.Click += new EventHandler(this.btnStart_Click);

            // Reset Button 설정
            this.btnReset.Location = new System.Drawing.Point(120, 420);
            this.btnReset.Size = new System.Drawing.Size(100, 30);
            this.btnReset.Text = "Reset";
            this.btnReset.Click += new EventHandler(this.btnReset_Click);

            // Save Button 설정
            this.btnSave.Location = new System.Drawing.Point(230, 420);
            this.btnSave.Size = new System.Drawing.Size(100, 30);
            this.btnSave.Text = "Save";
            this.btnSave.Click += new EventHandler(this.btnSave_Click);

            // Form 설정
            this.ClientSize = new System.Drawing.Size(640, 480);
            this.Controls.Add(this.chart);
            this.Controls.Add(this.btnStart);
            this.Controls.Add(this.btnReset);
            this.Controls.Add(this.btnSave);
            this.Text = "실시간 데이터 그래프";
        }

3️⃣ 실행 결과

1️⃣ 실시간 데이터 업데이트

  • "Start" 버튼 클릭 → 1초마다 새로운 데이터가 추가되어 그래프 업데이트

2️⃣ 데이터 리셋

  • "Reset" 버튼 클릭 → 그래프 데이터 초기화

3️⃣ 데이터 저장

  • "Save" 버튼 클릭 → CSV 파일로 그래프 데이터 저장

5. 주요 개념 요약

  • Chart: 데이터 시각화를 위한 기본 제공 컨트롤
  • Series: 그래프에 데이터 포인트를 추가하는 객체
  • Timer: 주기적으로 데이터 추가를 실행
  • SaveFileDialog: 데이터를 저장할 파일을 선택하는 UI

 

📌 #CSharp #WindowsForms #Chart #실시간데이터 #데이터시각화 #Timer