I'm implementing some real-time charts in a C# WPF application, but am using WinForms charts as they are generally easy to work with and are surprisingly performant.
Anyway, I've got the charts working just fine except for one major issue which I can't for the life of me figure out:
When I add data to the chart, it sometimes just resizes itself. Sometimes it does that a lot, giving itself the wiggles and making the chart super annoying to read and deal with.
My question is: how can I prevent this damned chart from constantly resizing itself?!
Some additional information:
The chart is included in my XAML as such:
<WindowsFormsHost Grid.Row="1" Grid.ColumnSpan="2" Margin="5">
<winformchart:Chart Dock="Fill" x:Name="Session0Chart">
<winformchart:Chart.ChartAreas>
<winformchart:ChartArea/>
</winformchart:Chart.ChartAreas>
</winformchart:Chart>
</WindowsFormsHost>
Gets initialized via:
// initialize it!
chart.Palette = ChartColorPalette.Bright;
// setup the labels
Font monoSpaceFont = new Font("Consolas", 10);
chart.ChartAreas[0].AxisX.LabelStyle.Font = monoSpaceFont;
chart.ChartAreas[0].AxisY.LabelStyle.Font = monoSpaceFont;
// set the axis limits appropriately
chart.ChartAreas[0].AxisY.Maximum = 600;
chart.ChartAreas[0].AxisY.Minimum = -200;
// set up grid lines and axis styles
chart.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dash;
chart.ChartAreas[0].AxisX.MinorGrid.LineColor = System.Drawing.Color.Gray;
chart.ChartAreas[0].AxisX.MinorGrid.Interval = 0.04;
chart.ChartAreas[0].AxisX.LabelStyle.Format = "F2";
chart.ChartAreas[0].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.None;
chart.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
chart.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
chart.ChartAreas[0].AxisY.MajorGrid.Interval = 200;
chart.ChartAreas[0].AxisY.LabelAutoFitStyle = LabelAutoFitStyles.None;
chart.ChartAreas[0].AxisY.LabelStyle.Format = "F0";
chart.Series.Clear();
Series s = new Series();
s.ChartType = SeriesChartType.FastLine;
chart.Series.Add(s);
chart.Refresh();
And data points get added via:
// if we get too many points, remove the head
if (session.Chart.Series[0].Points.Count >= Properties.Settings.Default.ECGDataPoints)
{
session.Chart.Series[0].Points.RemoveAt(0);
}
// add the points
for (int i = data.samples.Length - 1; i >= 0; i--)
{
session.Chart.Series[0].Points.AddXY(session.ecgT, data.samples[i]);
session.ecgT += session.ECGPeriod / (double)data.samples.Length;
}
// only look at the last few seconds
session.Chart.ChartAreas[0].AxisX.Maximum = session.ecgT;
session.Chart.ChartAreas[0].AxisX.Minimum = session.ecgT - Properties.Settings.Default.ECGTimeWindow;
Any help you can offer would be GREATLY appreciated, this has been driving me crazy for way too long!
You can set ChartArea Position
and InnerPlotPosition
to avoid those wiggles.
chrt.ChartAreas[0].Position.Auto = false;
chrt.ChartAreas[0].Position.Height = 70;
chrt.ChartAreas[0].Position.Y = 5;
chrt.ChartAreas[0].InnerPlotPosition.Auto = false;
chrt.ChartAreas[0].InnerPlotPosition.Height = 50;
chrt.ChartAreas[0].InnerPlotPosition.Y = 10;
chart.ChartAreas[0].InnerPlotPosition.X = 50;
chart.ChartAreas[0].InnerPlotPosition.Y = 5;
chart.ChartAreas[0].InnerPlotPosition.Width = 80;
chart.ChartAreas[0].InnerPlotPosition.Height = 80;
Read this.
You should make your X axis DateTime
, not double
. It's an ECG anyway....
The wiggle is caused by incrementing your X axis with values such as 0.10000000001234.
// No wiggle
chartNoWiggle.Series[0].Points.AddXY(xdatetime, r.NextDouble());
if (chartNoWiggle.Series[0].Points.Count > 10)
chartNoWiggle.Series[0].Points.RemoveAt(0);
chartNoWiggle.ChartAreas[0].AxisX.Minimum = chartNoWiggle.Series[0].Points[0].XValue;
chartNoWiggle.ChartAreas[0].AxisX.Maximum = xdatetime.ToOADate();
xdatetime = xdatetime.AddMinutes(1);
// Wiggle
chartWiggle.Series[0].Points.AddXY(xdouble, r.NextDouble());
if (chartWiggle.Series[0].Points.Count > 10)
chartWiggle.Series[0].Points.RemoveAt(0);
chartWiggle.ChartAreas[0].AxisX.Minimum = chartWiggle.Series[0].Points[0].XValue;
chartWiggle.ChartAreas[0].AxisX.Maximum = xdouble;
xdouble += 0.10000000001234;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With