I am trying to display real time ecg data output from a device to a Winforms chart.
It's working pretty well, but I can't seem to remove the data points from the left hand side of the chart as new points are added, and the major grids shrink and grow.
Here is the code in the timer:
private void butPlayEKG_Click(object sender, EventArgs e) {
chartEKG.Series.Clear();
var series1 = new Series {
Name = "EKG",
Color = Color.LawnGreen,
IsVisibleInLegend = true,
IsXValueIndexed = true,
ChartType = SeriesChartType.Line,
};
this.chartEKG.Series.Add(series1);
playButtonClicked = true;
timer1.Enabled = true;
timer1.Interval = 5;
timer1.Tick = (s, args) => timer1_Tick(series1);
timer1.Start();
}
private void timer1_Tick(Series series1) {
labelClock.Text = DateTime.Now.ToString("HH:mm:ss tt");
string str = String.Empty;
for (int j = 0; j < ekgData.Count; j ) {
str = ekgData[j].EKGWaveform.ToString();
count = str.Split('^');
EKGData = new int[count.Length];
string timeStamp = ekgData[j].VSTimeStamp.ToString();
string format = "yyyyMMddHHmmssfff";
DateTime time = DateTime.ParseExact(timeStamp, format, null);// CultureInfo.InvariantCulture);
adjTime = time;
if (j > 0) {
adjTime = time; time.AddSeconds(1 / 500);
}
for (int i = 0; i < 499; i ) {
EKGData = Array.ConvertAll<string, int>(count, Convert.ToInt32);
series1.Points.AddXY(adjTime.ToString("HH:mm:ss tt"), EKGData[i] * .61);
chartEKG.Update();
}
for (int h = 1; h < j; h ) {
series1.Points.Remove(series1.Points[h]);
chartEKG.Update();
}
}
}
and here is the chart code:
timer1.Interval = 15;
this.chartEKG.ChartAreas["ChartArea1"].CursorX.LineColor = Color.LawnGreen;
this.chartEKG.ChartAreas["ChartArea1"].CursorY.LineColor = Color.LawnGreen;
this.chartEKG.ChartAreas["ChartArea1"].AxisY.MajorGrid.Enabled = true;
this.chartEKG.ChartAreas["ChartArea1"].AxisY.MajorGrid.Interval = 200;
this.chartEKG.ChartAreas["ChartArea1"].AxisX.MajorGrid.Enabled = true;
this.chartEKG.ChartAreas["ChartArea1"].AxisX.MajorGrid.Interval = 200;
this.chartEKG.ChartAreas["ChartArea1"].AxisY.Title = "mV";
this.chartEKG.ChartAreas["ChartArea1"].AxisX.Minimum = 0;
CultureInfo culture = new CultureInfo("en-US");
ekgData = AnesthVSDatas.CreateEKGWaveformObjects(8237);
A video of the playback can be viewed here:
CodePudding user response:
Pay attention, time.AddSeconds(1 / 500);
has no effect.
I guess you insert every time the same time in the chart.
Maybe your intent was
time = time.AddSeconds(1d / 500);
Note also the d
. Because 1/500
is equal to 0
.
CodePudding user response:
Working now.
I realized I did not need the timer, and I needed a points.RemoveAt to remove points from the chart as more points are plotted. I also simplified things by Joining all of the messages together into one long string instead of parsing each message individually.
Here is the working code:
private System.Windows.Forms.DataVisualization.Charting.Chart chartEKG;
private System.Windows.Forms.DataVisualization.Charting.Series series1;
private List<AnesthVSData> ekgData;
private static string str;
private string[] count;
chartEKG.Series.Clear();
var series1 = new Series {
Name = "EKG",
Color = Color.LawnGreen,
IsVisibleInLegend = true,
IsXValueIndexed = true,
ChartType = SeriesChartType.Line,
};
this.chartEKG.Series.Add(series1);
playButtonClicked = true;
labelClock.Text = DateTime.Now.ToString("HH:mm:ss tt");
string timeStamp = DateTime.Now.ToString();
for (int j = 0; j < ekgData.Count; j ) {
str = str "^" string.Join("^", ekgData[j].EKGWaveform.ToString());
if (j == 0) {
timeStamp = ekgData[j].VSTimeStamp; //get first VSTimeStamp in series
}
}
str = str.Remove(0, 1); //remove leading ^
count = str.Split('^');
string format = "yyyyMMddHHmmssfff";
DateTime time = DateTime.ParseExact(timeStamp, format, CultureInfo.InvariantCulture);
//adjTime = time;
for (int j = 0; j < count.Length; j ) {
time = time.AddSeconds(0.002); //500 data points per HL7 message, each message is 1s long so 1/500 = 0.002
series1.Points.AddXY(time.ToString("HH:mm:ss"), Convert.ToInt32(count[j]) * 0.61); // 0.61 is resolution correction factor
if (chartEKG.Series[0].Points.Count > 1800) {
chartEKG.Series[0].Points.RemoveAt(0);
chartEKG.ChartAreas[0].AxisX.Minimum = 0; }
chartEKG.Update();
}
And here is the output: