-
C# 그래프를 이용한 ECG/PPG 그리기C#/WindowForm 2022. 6. 9. 02:21
디자인 시작하기에 앞서 ecg와 ppg의 데이터 파일을 넣어준다. 드래그해서 넣으면 간편히 넣을 수 있다.
public partial class Form1 : Form { double[] ecg = new double[100000]; double[] ppg = new double[100000]; private int ecgCount; private int ppgCount; Timer t = new Timer(); public Form1() { InitializeComponent(); this.Text = "ECG/PPG"; this.WindowState = FormWindowState.Maximized; EcgRead(); PpgRead(); ChartSetting(); t.Interval = 10; // 0.01초 설정 t.Tick += T_Tick; }
ecg, ppg배열은 방금 넣어준 데이터 파일의 값을 저장해준다.
private void PpgRead() { string fileName = "../../Data/ppg.txt"; string[] lines = File.ReadAllLines(fileName); double min = double.MaxValue; double max = double.MinValue; int i = 0; foreach (var line in lines) { ppg[i] = double.Parse(line); if (min > ppg[i]) min = ppg[i]; if (max < ppg[i]) max = ppg[i]; i++; } ppgCount = i; string s = string.Format("PPG: count={0}, min={1}, max={2}", ppgCount, min, max); MessageBox.Show(s); }
foreach문을 사용하여 ppg배열에 저장하면서 최대값 최솟값을 비교한다. 또한 int i를 선언하여 데이터 값이 총 몇게인지 카운트한다. fileName 저장된 파일의 경로이다.
private void EcgRead() { string fileName = "../../Data/ecg.txt"; string[] lines = File.ReadAllLines(fileName); double min = double.MaxValue; double max = double.MinValue; int i = 0; foreach(var line in lines) { ecg[i] = double.Parse(line) + 3; if(min > ecg[i]) min = ecg[i]; if(max < ecg[i]) max = ecg[i]; i++; } ecgCount = i; string s = string.Format("ECG: count={0}, min={1}, max={2}", ecgCount, min, max); MessageBox.Show(s); }
EcgRead 또한 같은 방식으로 작성하였다.
private void ChartSetting() { c.ChartAreas[0].CursorX.IsUserEnabled = true; // 커서 사용가능 c.ChartAreas[0].CursorX.IsUserSelectionEnabled = true; // zoom c.ChartAreas[0].BackColor = Color.Black; c.ChartAreas[0].AxisX.Minimum = 0; c.ChartAreas[0].AxisX.Maximum = ecgCount; c.ChartAreas[0].AxisX.Interval = 50; c.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray; c.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dash; c.ChartAreas[0].AxisY.Minimum = -2; c.ChartAreas[0].AxisY.Maximum = 6; c.ChartAreas[0].AxisY.Interval = 0.5; c.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray; c.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dash; c.Series.Clear(); // 시리즈를 다 지운다 c.Series.Add("ECG"); c.Series.Add("PPG"); c.Series[0].ChartType = SeriesChartType.Line; c.Series[0].Color = Color.LightGreen; c.Series[0].BorderWidth = 2; c.Series[0].LegendText = "ECG"; c.Series[1].ChartType = SeriesChartType.Line; c.Series[1].Color = Color.Orange; c.Series[1].BorderWidth = 2; c.Series[1].LegendText = "PGG"; // 데이터를 시리즈에 넣는 작업 foreach(var v in ecg) { c.Series["ECG"].Points.Add(v); } foreach (var v in ppg) { c.Series["PPG"].Points.Add(v); } }
ChartSetting은 (c.ChartAreas[0].CursorX.IsUserEnabled = true; // 커서 사용가능
c.ChartAreas[0].CursorX.IsUserSelectionEnabled = true; // zoom) 부분을 제외하면 전 시간에 사용했던 방법과 동일하다.private int cursorX = 0; // 차트에 표시되는 첫번째 데이터 private bool scrolling = false; // true: 스크롤, false이면 정지 private int dataCount = 500; // 한 화면에 표시되는 데이터 private int speed = 2; // 데이터 표시 속도 private void T_Tick(object sender, EventArgs e) { if (cursorX + dataCount <= ecgCount) c.ChartAreas[0].AxisX.ScaleView.Zoom( cursorX, cursorX + dataCount); else t.Stop(); cursorX += speed; }
시간에 따라 스코롤 하기 위해 사용한다.
private void dataCountToolStripMenuItem1_Click(object sender, EventArgs e) { dataCount *= 2; } private void dataCountToolStripMenuItem2_Click(object sender, EventArgs e) { dataCount /= 2; } private void speedUpToolStripMenuItem_Click(object sender, EventArgs e) { speed *= 2; } private void speedDownToolStripMenuItem_Click(object sender, EventArgs e) { speed /= 2; }
위 두 번의 코드이다 그래프의 속도와 데이터 카운트를 조절한다.
private void viewAllToolStripMenuItem_Click(object sender, EventArgs e) { c.ChartAreas[0].AxisX.ScaleView.Zoom(0, ecgCount); t.Stop(); scrolling = false; }
View All 버튼의 코드이며 ECG/PPG의 전체 값을 보여준다.
private void autoScrollToolStripMenuItem_Click(object sender, EventArgs e) { t.Start(); scrolling = true; }
Auto Scroll 버튼이다.
private void c_MouseClick(object sender, MouseEventArgs e) { HitTestResult htr = c.HitTest(e.X, e.Y); if(htr.ChartElementType == ChartElementType.DataPoint) { t.Stop(); string s = string.Format( "Count : {0}, ECG : {1}, PPG : {2}", htr.PointIndex, c.Series["ECG"].Points[htr.PointIndex].YValues[0], c.Series["PPG"].Points[htr.PointIndex].YValues[0]); MessageBox.Show(s); } }
데이터를 클릭하면 그 데이터의 정확한 값을 메세지 박스를 사용해 출력한다.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; namespace _039_EcgPpg { public partial class Form1 : Form { double[] ecg = new double[100000]; double[] ppg = new double[100000]; private int ecgCount; private int ppgCount; Timer t = new Timer(); public Form1() { InitializeComponent(); this.Text = "ECG/PPG"; this.WindowState = FormWindowState.Maximized; EcgRead(); PpgRead(); ChartSetting(); t.Interval = 10; // 0.01초 t.Tick += T_Tick; } private int cursorX = 0; // 차트에 표시되는 첫번째 데이터 private bool scrolling = false; // true: 스크롤, false이면 정지 private int dataCount = 500; // 한 화면에 표시되는 데이터 private int speed = 2; // 데이터 표시 속도 private void T_Tick(object sender, EventArgs e) { if (cursorX + dataCount <= ecgCount) c.ChartAreas[0].AxisX.ScaleView.Zoom( cursorX, cursorX + dataCount); else t.Stop(); cursorX += speed; } private void ChartSetting() { c.ChartAreas[0].CursorX.IsUserEnabled = true; // 커서 사용가능 c.ChartAreas[0].CursorX.IsUserSelectionEnabled = true; // zoom c.ChartAreas[0].BackColor = Color.Black; c.ChartAreas[0].AxisX.Minimum = 0; c.ChartAreas[0].AxisX.Maximum = ecgCount; c.ChartAreas[0].AxisX.Interval = 50; c.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Gray; c.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dash; c.ChartAreas[0].AxisY.Minimum = -2; c.ChartAreas[0].AxisY.Maximum = 6; c.ChartAreas[0].AxisY.Interval = 0.5; c.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Gray; c.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dash; c.Series.Clear(); // 시리즈를 다 지운다 c.Series.Add("ECG"); c.Series.Add("PPG"); c.Series[0].ChartType = SeriesChartType.Line; c.Series[0].Color = Color.LightGreen; c.Series[0].BorderWidth = 2; c.Series[0].LegendText = "ECG"; c.Series[1].ChartType = SeriesChartType.Line; c.Series[1].Color = Color.Orange; c.Series[1].BorderWidth = 2; c.Series[1].LegendText = "PGG"; // 데이터를 시리즈에 넣는 작업 foreach(var v in ecg) { c.Series["ECG"].Points.Add(v); } foreach (var v in ppg) { c.Series["PPG"].Points.Add(v); } } private void PpgRead() { string fileName = "../../Data/ppg.txt"; string[] lines = File.ReadAllLines(fileName); double min = double.MaxValue; double max = double.MinValue; int i = 0; foreach (var line in lines) { ppg[i] = double.Parse(line); if (min > ppg[i]) min = ppg[i]; if (max < ppg[i]) max = ppg[i]; i++; } ppgCount = i; string s = string.Format("PPG: count={0}, min={1}, max={2}", ppgCount, min, max); MessageBox.Show(s); } private void EcgRead() { string fileName = "../../Data/ecg.txt"; string[] lines = File.ReadAllLines(fileName); double min = double.MaxValue; double max = double.MinValue; int i = 0; foreach(var line in lines) { ecg[i] = double.Parse(line) + 3; if(min > ecg[i]) min = ecg[i]; if(max < ecg[i]) max = ecg[i]; i++; } ecgCount = i; string s = string.Format("ECG: count={0}, min={1}, max={2}", ecgCount, min, max); MessageBox.Show(s); } private void autoScrollToolStripMenuItem_Click(object sender, EventArgs e) { t.Start(); scrolling = true; } bool scrollFlag = true; // 차트를 클릭했을 때 처리 메소드 private void c_Click(object sender, EventArgs e) { if(scrollFlag == true) { t.Stop(); scrollFlag = false; } else { t.Start(); scrollFlag = true; } } private void viewAllToolStripMenuItem_Click(object sender, EventArgs e) { c.ChartAreas[0].AxisX.ScaleView.Zoom(0, ecgCount); t.Stop(); scrolling = false; } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } private void c_SelectionRangeChanged(object sender, CursorEventArgs e) { int min = (int)(c.ChartAreas[0].AxisX.ScaleView.ViewMinimum); int max = (int)(c.ChartAreas[0].AxisX.ScaleView.ViewMaximum); cursorX = min; dataCount = max - min; } private void dataCountToolStripMenuItem1_Click(object sender, EventArgs e) { dataCount *= 2; } private void dataCountToolStripMenuItem2_Click(object sender, EventArgs e) { dataCount /= 2; } private void speedUpToolStripMenuItem_Click(object sender, EventArgs e) { speed *= 2; } private void speedDownToolStripMenuItem_Click(object sender, EventArgs e) { speed /= 2; } // 클릭하는 곳의 데이터 값을 표시 private void c_MouseClick(object sender, MouseEventArgs e) { HitTestResult htr = c.HitTest(e.X, e.Y); if(htr.ChartElementType == ChartElementType.DataPoint) { t.Stop(); string s = string.Format( "Count : {0}, ECG : {1}, PPG : {2}", htr.PointIndex, c.Series["ECG"].Points[htr.PointIndex].YValues[0], c.Series["PPG"].Points[htr.PointIndex].YValues[0]); MessageBox.Show(s); } } } }
전체코드
실행결과 실행결과 'C# > WindowForm' 카테고리의 다른 글
C# 시계만들기 (0) 2022.06.16 C# 그래프 그리기 (0) 2022.06.01 C# Chart 그리기- 2 (0) 2022.06.01 C# Chart그리기-1 (0) 2022.06.01 ACCESS를 사용한 DB연결 -3 (PhoneBook) (0) 2022.05.18