2 using System.Collections.Generic;
3 using System.ComponentModel;
8 using System.Windows.Forms;
9 using System.Windows.Forms.DataVisualization.Charting;
11 namespace SeciControls.Graphing
15 private Double _maxDoubleValue = Math.Pow(10, 25);
16 private const int _maxPoints = 1000;
17 private DateTime _lastUpdate =
new DateTime();
21 private Double _yMin = Double.NaN;
22 private Double _yMax = Double.NaN;
23 private Double _y2Min = Double.NaN;
24 private Double _y2Max = Double.NaN;
26 private Boolean _limitsBeingChanged =
false;
27 private Boolean _yLimitsSetManually =
false;
28 private Boolean _y2LimitsSetManually =
false;
30 private Boolean _yMinAuto =
false;
31 private Boolean _yMaxAuto =
false;
32 private Boolean _y2MinAuto =
false;
33 private Boolean _y2MaxAuto =
false;
35 private Double _ySetMin = Double.NaN;
36 private Double _ySetMax = Double.NaN;
37 private Double _y2SetMin = Double.NaN;
38 private Double _y2SetMax = Double.NaN;
46 InitializeComponent();
48 chart1.ChartAreas[0].CursorX.IsUserEnabled =
true;
49 chart1.ChartAreas[0].CursorX.IsUserSelectionEnabled =
true;
50 chart1.ChartAreas[0].AxisX.ScaleView.Zoomable =
true;
51 chart1.ChartAreas[0].AxisX.ScaleView.MinSize = 1;
52 chart1.ChartAreas[0].AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Minutes;
53 chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.None;
55 chart1.ChartAreas[0].CursorY.IsUserEnabled =
true;
56 chart1.ChartAreas[0].CursorY.IsUserSelectionEnabled =
true;
57 chart1.ChartAreas[0].AxisY.ScaleView.Zoomable =
true;
58 chart1.ChartAreas[0].AxisY.ScaleView.MinSize = 1;
59 chart1.ChartAreas[0].AxisY.ScaleView.MinSizeType = DateTimeIntervalType.Auto;
60 chart1.ChartAreas[0].AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.None;
62 chart1.ChartAreas[0].AxisY2.ScaleView.Zoomable =
true;
63 chart1.ChartAreas[0].AxisY2.ScaleView.MinSize = 1;
64 chart1.ChartAreas[0].AxisY2.ScaleView.MinSizeType = DateTimeIntervalType.Auto;
65 chart1.ChartAreas[0].AxisY2.ScrollBar.ButtonStyle = ScrollBarButtonStyles.None;
67 chart1.ChartAreas[0].CursorX.Interval = 0;
68 chart1.ChartAreas[0].CursorY.Interval = 0.001;
71 public void SetupGraph(Seci.Definitions.GraphDefinition graphDef)
73 _lastUpdate =
new DateTime();
77 _minValue = DateTime.Now;
78 _maxValue = _minValue.AddSeconds(120);
81 chart1.Titles.Clear();
82 chart1.Titles.Add(_graphDef.Title);
83 chart1.ChartAreas[0].BackGradientStyle = GradientStyle.TopBottom;
84 chart1.ChartAreas[0].BackColor = Color.AliceBlue;
85 chart1.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
86 chart1.ChartAreas[0].BorderColor = Color.Gray;
89 chart1.ChartAreas[0].AxisX.MajorGrid.Enabled =
false;
90 chart1.ChartAreas[0].AxisX.LineColor = Color.Gray;
91 chart1.ChartAreas[0].AxisX.MajorTickMark.LineColor = Color.Gray;
92 chart1.ChartAreas[0].AxisY.MajorGrid.Enabled =
false;
93 chart1.ChartAreas[0].AxisY.LineColor = Color.Gray;
94 chart1.ChartAreas[0].AxisY.MajorTickMark.LineColor = Color.Gray;
95 chart1.ChartAreas[0].AxisY2.MajorGrid.Enabled =
false;
96 chart1.ChartAreas[0].AxisY2.LineColor = Color.Gray;
97 chart1.ChartAreas[0].AxisY2.MajorTickMark.LineColor = Color.Gray;
100 chart1.Legends[0].Enabled =
true;
102 chart1.Legends[0].LegendStyle = LegendStyle.Row;
103 chart1.Legends[0].Docking = Docking.Top;
105 chart1.ChartAreas[0].AxisX.Minimum = _minValue.ToOADate();
106 chart1.ChartAreas[0].AxisX.Maximum = _maxValue.ToOADate();
107 chart1.ChartAreas[0].AxisX.LabelStyle.Format =
"HH:mm:ss";
108 chart1.ChartAreas[0].AxisX.Title =
"Time";
109 chart1.ChartAreas[0].AxisY.Title = _graphDef.YLabel;
111 if (_graphDef.ShowZeroY1)
113 chart1.ChartAreas[0].AxisY.Minimum = 0;
114 chart1.ChartAreas[0].AxisY.Maximum = 1;
119 if (_graphDef.ShowZeroY2)
121 chart1.ChartAreas[0].AxisY2.Minimum = 0;
122 chart1.ChartAreas[0].AxisY.Maximum = 1;
123 y2AxisToolStripMenuItem.Enabled =
true;
128 if (!String.IsNullOrEmpty(_graphDef.Y2Label))
130 chart1.ChartAreas[0].AxisY2.Title = _graphDef.Y2Label;
131 chart1.ChartAreas[0].AxisY2.Enabled = AxisEnabled.False;
134 chart1.Series.Clear();
136 foreach (Seci.Definitions.PlotDefinition plot in _graphDef.Plots)
138 addPlot(plot.BlockName, plot.UseY2);
142 private void addPlot(
string blockname, Boolean useY2)
144 foreach (Series series
in chart1.Series)
146 if (series.Name.ToLower() == blockname.ToLower())
153 Series series1 =
new Series(blockname);
154 series1.ChartType = SeriesChartType.FastLine;
155 series1.BorderWidth = 3;
156 series1.XValueType = ChartValueType.DateTime;
159 chart1.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True;
160 series1.YAxisType = AxisType.Secondary;
162 chart1.Series.Add(series1);
169 for (
int i = 0; i < chart1.Series.Count; ++i)
174 chart1.Series[i].Color = Color.Red;
177 chart1.Series[i].Color = Color.Blue;
180 chart1.Series[i].Color = Color.Purple;
183 chart1.Series[i].Color = Color.Goldenrod;
186 chart1.Series[i].Color = Color.Black;
194 chart1.Series.Clear();
199 if (Math.Abs(value) > _maxDoubleValue)
207 series.Points.AddXY(time.ToOADate(), value);
213 while (series.Points.Count > _maxPoints)
215 series.Points.RemoveAt(0);
224 foreach (Series series
in chart1.Series)
226 if (series.Points != null && series.Points.Count > 0)
228 if (minX == -1 || series.Points[0].XValue < minX) minX = series.Points[0].XValue;
229 if (maxX == -1 || series.Points[series.Points.Count - 1].XValue > maxX) maxX = series.Points[series.Points.Count - 1].XValue;
232 chart1.ChartAreas[0].AxisX.Minimum = minX;
233 chart1.ChartAreas[0].AxisX.Maximum = maxX;
238 foreach (Series series
in chart1.Series)
240 series.Points.Clear();
250 if (series.YAxisType == AxisType.Primary)
252 if (_yLimitsSetManually)
255 setYRange(chart1.ChartAreas[0].AxisY, ref _yMin, ref _yMax, value,
false);
259 else if (!_graphDef.ShowZeroY1)
261 setYRange(chart1.ChartAreas[0].AxisY, ref _yMin, ref _yMax, value, !_limitsBeingChanged);
265 setYRange(chart1.ChartAreas[0].AxisY, ref _yMin, ref _yMax, value, !_limitsBeingChanged);
266 if (_yMin != _yMax && !_limitsBeingChanged)
268 chart1.ChartAreas[0].AxisY.Minimum = Double.NaN;
269 chart1.ChartAreas[0].AxisY.Maximum = Double.NaN;
273 else if (series.YAxisType == AxisType.Secondary)
275 if (_y2LimitsSetManually)
278 setYRange(chart1.ChartAreas[0].AxisY2, ref _y2Min, ref _y2Max, value,
false);
282 else if (!_graphDef.ShowZeroY2)
284 setYRange(chart1.ChartAreas[0].AxisY2, ref _y2Min, ref _y2Max, value, !_limitsBeingChanged);
288 setYRange(chart1.ChartAreas[0].AxisY2, ref _y2Min, ref _y2Max, value, !_limitsBeingChanged);
289 if (_y2Min != _y2Max && !_limitsBeingChanged)
291 chart1.ChartAreas[0].AxisY2.Minimum = Double.NaN;
292 chart1.ChartAreas[0].AxisY2.Maximum = Double.NaN;
300 if ((_y2MinAuto || _y2MaxAuto) && _y2Min == _y2Max)
302 chart1.ChartAreas[0].AxisY2.Maximum = _y2Min + 1;
303 chart1.ChartAreas[0].AxisY2.Minimum = _y2Min - 1;
305 else if (_y2MaxAuto && _y2MinAuto)
307 chart1.ChartAreas[0].AxisY2.Maximum = Double.NaN;
308 chart1.ChartAreas[0].AxisY2.Minimum = Double.NaN;
312 chart1.ChartAreas[0].AxisY2.Minimum = Double.NaN;
313 chart1.ChartAreas[0].AxisY2.Maximum = _y2SetMax;
317 chart1.ChartAreas[0].AxisY2.Maximum = Double.NaN;
318 chart1.ChartAreas[0].AxisY2.Minimum = _y2SetMin;
324 if ((_yMinAuto || _yMaxAuto) && _yMin == _yMax)
326 chart1.ChartAreas[0].AxisY.Maximum = _yMin + 1;
327 chart1.ChartAreas[0].AxisY.Minimum = _yMin - 1;
329 else if (_yMaxAuto && _yMinAuto)
331 chart1.ChartAreas[0].AxisY.Maximum = Double.NaN;
332 chart1.ChartAreas[0].AxisY.Minimum = Double.NaN;
336 chart1.ChartAreas[0].AxisY.Minimum = Double.NaN;
337 chart1.ChartAreas[0].AxisY.Maximum = _ySetMax;
341 chart1.ChartAreas[0].AxisY.Maximum = Double.NaN;
342 chart1.ChartAreas[0].AxisY.Minimum = _ySetMin;
348 if (Double.IsNaN(min))
352 else if (value < min)
362 if (Double.IsNaN(max))
366 else if (value > max)
374 private void setYRange(Axis axis, ref Double min, ref Double max, Double value, Boolean setAxis)
376 min = findMinimum(min, value);
377 max = findMaximum(max, value);
383 axis.Minimum = min - 1;
384 axis.Maximum = max + 1;
394 #region IUpdate Members
398 DateTime time = DateTime.Now;
400 if (time >= _lastUpdate.AddSeconds(_graphDef.UpdateRate))
404 foreach (Series series
in chart1.Series)
411 if (series.Name.EndsWith(
" (Setpoint)"))
413 if (Double.TryParse(Seci.Managers.BlockMgr.GetBlockSetpoint(series.Name.Substring(0, series.Name.IndexOf(
" (Setpoint)"))), out result))
415 addDataPoint(series, time, result);
416 checkYRange(series, result);
421 if (Double.TryParse(Seci.Managers.BlockMgr.GetBlockValue(series.Name), out result))
423 addDataPoint(series, time, result);
424 checkYRange(series, result);
443 chart1.ChartAreas[0].AxisX.ScaleView.ZoomReset(0);
444 chart1.ChartAreas[0].AxisY.ScaleView.ZoomReset(0);
445 chart1.ChartAreas[0].AxisY2.ScaleView.ZoomReset(0);
466 _limitsBeingChanged =
true;
467 limits.Min = chart1.ChartAreas[0].AxisY.Minimum;
468 limits.Max = chart1.ChartAreas[0].AxisY.Maximum;
469 if (_yMinAuto) limits.Min = Double.NaN;
470 if (_yMaxAuto) limits.Max = Double.NaN;
472 if (limits.ShowDialog() == DialogResult.OK)
474 _yLimitsSetManually =
true;
475 _ySetMin = limits.Min;
476 _ySetMax = limits.Max;
477 chart1.ChartAreas[0].AxisY.Minimum = limits.Min;
478 chart1.ChartAreas[0].AxisY.Maximum = limits.Max;
479 _yMinAuto = Double.IsNaN(limits.Min);
480 _yMaxAuto = Double.IsNaN(limits.Max);
483 _limitsBeingChanged =
false;
488 _yLimitsSetManually =
false;
489 _ySetMin = Double.NaN;
490 _ySetMax = Double.NaN;
496 _limitsBeingChanged =
true;
497 limits.Min = chart1.ChartAreas[0].AxisY2.Minimum;
498 limits.Max = chart1.ChartAreas[0].AxisY2.Maximum;
499 if (_y2MinAuto) limits.Min = Double.NaN;
500 if (_y2MaxAuto) limits.Max = Double.NaN;
502 if (limits.ShowDialog() == DialogResult.OK)
504 _y2LimitsSetManually =
true;
505 _y2SetMin = limits.Min;
506 _y2SetMax = limits.Max;
507 chart1.ChartAreas[0].AxisY2.Minimum = limits.Min;
508 chart1.ChartAreas[0].AxisY2.Maximum = limits.Max;
509 _y2MinAuto = Double.IsNaN(limits.Min);
510 _y2MaxAuto = Double.IsNaN(limits.Max);
513 _limitsBeingChanged =
false;
518 _y2LimitsSetManually =
false;
519 _y2SetMin = Double.NaN;
520 _y2SetMax = Double.NaN;
This class is used for serializing the graphs for saving in the configuration.
void setLimitsXToolStripMenuItem(object sender, EventArgs e)
void addDataPoint(Series series, DateTime time, double value)
void checkYRange(Series series, double value)
void autoScaleXToolStripMenuItem_Click(object sender, EventArgs e)
Double findMaximum(Double max, Double value)
void autoScaleYToolStripMenuItem_Click(object sender, EventArgs e)
void autoScaleY2ToolStripMenuItem_Click(object sender, EventArgs e)
void addPlot(string blockname, Boolean useY2)
void autoScaleToolStripMenuItem_Click(object sender, EventArgs e)
Double findMinimum(Double min, Double value)
void setLimitsYToolStripMenuItem_Click(object sender, EventArgs e)
void clearPointsToolStripMenuItem_Click(object sender, EventArgs e)
void SetupGraph(Seci.Definitions.GraphDefinition graphDef)
void setYRange(Axis axis, ref Double min, ref Double max, Double value, Boolean setAxis)
Seci.Definitions.GraphDefinition _graphDef
void setLimitsY2ToolStripMenuItem_Click(object sender, EventArgs e)