Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs @ 3561

Last change on this file since 3561 was 3561, checked in by swagner, 14 years ago

Fixed exceptions (#893)

File size: 13.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Windows.Forms.DataVisualization.Charting;
25using HeuristicLab.Collections;
26using HeuristicLab.Core.Views;
27using HeuristicLab.MainForm;
28
29namespace HeuristicLab.Analysis.Views {
30  /// <summary>
31  /// The visual representation of a <see cref="Variable"/>.
32  /// </summary>
33  [View("DataTable View")]
34  [Content(typeof(DataTable), true)]
35  public sealed partial class DataTableView : NamedItemView {
36    Dictionary<IObservableList<double>, DataRow> valuesRowsTable;
37    /// <summary>
38    /// Gets or sets the variable to represent visually.
39    /// </summary>
40    /// <remarks>Uses property <see cref="ViewBase.Item"/> of base class <see cref="ViewBase"/>.
41    /// No own data storage present.</remarks>
42    public new DataTable Content {
43      get { return (DataTable)base.Content; }
44      set { base.Content = value; }
45    }
46
47    /// <summary>
48    /// Initializes a new instance of <see cref="VariableView"/> with caption "Variable".
49    /// </summary>
50    public DataTableView() {
51      InitializeComponent();
52      Caption = "DataTable";
53      valuesRowsTable = new Dictionary<IObservableList<double>, DataRow>();
54    }
55    /// <summary>
56    /// Initializes a new instance of <see cref="VariableView"/> with the given <paramref name="variable"/>.
57    /// </summary>
58    /// <remarks>Calls <see cref="VariableView()"/>.</remarks>
59    /// <param name="variable">The variable to represent visually.</param>
60    public DataTableView(DataTable content)
61      : this() {
62      Content = content;
63    }
64
65    /// <summary>
66    /// Removes the eventhandlers from the underlying <see cref="Variable"/>.
67    /// </summary>
68    /// <remarks>Calls <see cref="ViewBase.RemoveItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
69    protected override void DeregisterContentEvents() {
70      foreach (DataRow row in Content.Rows)
71        DeregisterDataRowEvents(row);
72      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
73      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
74      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);
75      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);
76      base.DeregisterContentEvents();
77    }
78
79    /// <summary>
80    /// Adds eventhandlers to the underlying <see cref="Variable"/>.
81    /// </summary>
82    /// <remarks>Calls <see cref="ViewBase.AddItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
83    protected override void RegisterContentEvents() {
84      base.RegisterContentEvents();
85      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
86      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
87      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);
88      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);
89      foreach (DataRow row in Content.Rows)
90        RegisterDataRowEvents(row);
91    }
92
93    protected override void OnContentChanged() {
94      base.OnContentChanged();
95      chart.Titles.Clear();
96      chart.Series.Clear();
97      Caption = "DataTable";
98      if (Content != null) {
99        Caption = Content.Name + " (" + Content.GetType().Name + ")";
100        chart.Titles.Add(new Title(Content.Name, Docking.Top));
101        foreach (DataRow row in Content.Rows)
102          AddDataRow(row);
103      }
104      SetEnabledStateOfControls();
105    }
106
107    protected override void OnReadOnlyChanged() {
108      base.OnReadOnlyChanged();
109      SetEnabledStateOfControls();
110    }
111
112    private void SetEnabledStateOfControls() {
113      chart.Enabled = Content != null;
114    }
115
116    private void AddDataRow(DataRow row) {
117      Series series = new Series(row.Name);
118      series.ChartType = SeriesChartType.FastLine;
119      series.ToolTip = row.Name + " #VAL";
120      for (int i = 0; i < row.Values.Count; i++) {
121        var value = row.Values[i];
122        if (IsInvalidValue(value)) {
123          DataPoint point = new DataPoint();
124          point.IsEmpty = true;
125          series.Points.Add(point);
126        } else {
127          series.Points.Add(value);
128        }
129      }
130      chart.Series.Add(series);
131    }
132    private void RemoveDataRow(DataRow row) {
133      Series series = chart.Series[row.Name];
134      chart.Series.Remove(series);
135    }
136
137    #region Content Events
138    private void RegisterDataRowEvents(DataRow row) {
139      row.NameChanged += new EventHandler(Row_NameChanged);
140      valuesRowsTable.Add(row.Values, row);
141      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
142      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
143      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
144      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
145      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
146    }
147    private void DeregisterDataRowEvents(DataRow row) {
148      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
149      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
150      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
151      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
152      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
153      valuesRowsTable.Remove(row.Values);
154      row.NameChanged -= new EventHandler(Row_NameChanged);
155    }
156    protected override void Content_NameChanged(object sender, EventArgs e) {
157      if (InvokeRequired)
158        Invoke(new EventHandler(Content_NameChanged), sender, e);
159      else {
160        chart.Titles[0].Text = Content.Name;
161        base.Content_NameChanged(sender, e);
162      }
163    }
164    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
165      if (InvokeRequired)
166        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded), sender, e);
167      else {
168        foreach (DataRow row in e.Items) {
169          AddDataRow(row);
170          RegisterDataRowEvents(row);
171        }
172      }
173    }
174    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
175      if (InvokeRequired)
176        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved), sender, e);
177      else {
178        foreach (DataRow row in e.Items) {
179          DeregisterDataRowEvents(row);
180          RemoveDataRow(row);
181        }
182      }
183    }
184    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
185      if (InvokeRequired)
186        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);
187      else {
188        foreach (DataRow row in e.OldItems) {
189          DeregisterDataRowEvents(row);
190          RemoveDataRow(row);
191        }
192        foreach (DataRow row in e.Items) {
193          AddDataRow(row);
194          RegisterDataRowEvents(row);
195        }
196      }
197    }
198    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
199      if (InvokeRequired)
200        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset), sender, e);
201      else {
202        foreach (DataRow row in e.OldItems) {
203          DeregisterDataRowEvents(row);
204          RemoveDataRow(row);
205        }
206        foreach (DataRow row in e.Items) {
207          AddDataRow(row);
208          RegisterDataRowEvents(row);
209        }
210      }
211    }
212    private void Row_NameChanged(object sender, EventArgs e) {
213      if (InvokeRequired)
214        Invoke(new EventHandler(Row_NameChanged), sender, e);
215      else {
216        DataRow row = (DataRow)sender;
217        chart.Series[row.Name].Name = row.Name;
218      }
219    }
220    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
221      if (InvokeRequired)
222        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded), sender, e);
223      else {
224        DataRow row = null;
225        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
226        if (row != null) {
227          foreach (IndexedItem<double> item in e.Items) {
228            var value = item.Value;
229            if (IsInvalidValue(item.Value)) {
230              DataPoint point = new DataPoint();
231              point.IsEmpty = true;
232              chart.Series[row.Name].Points.Insert(item.Index, point);
233            } else {
234              chart.Series[row.Name].Points.InsertY(item.Index, value);
235            }
236          }
237        }
238      }
239    }
240    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
241      if (InvokeRequired)
242        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved), sender, e);
243      else {
244        DataRow row = null;
245        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
246        if (row != null) {
247          List<DataPoint> points = new List<DataPoint>();
248          foreach (IndexedItem<double> item in e.Items)
249            points.Add(chart.Series[row.Name].Points[item.Index]);
250          foreach (DataPoint point in points)
251            chart.Series[row.Name].Points.Remove(point);
252        }
253      }
254    }
255    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
256      if (InvokeRequired)
257        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced), sender, e);
258      else {
259        DataRow row = null;
260        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
261        if (row != null) {
262          foreach (IndexedItem<double> item in e.Items) {
263            if (IsInvalidValue(item.Value))
264              chart.Series[row.Name].Points[item.Index].IsEmpty = true;
265            else {
266              chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
267              chart.Series[row.Name].Points[item.Index].IsEmpty = false;
268            }
269          }
270        }
271      }
272    }
273    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
274      if (InvokeRequired)
275        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved), sender, e);
276      else {
277        DataRow row = null;
278        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
279        if (row != null) {
280          foreach (IndexedItem<double> item in e.Items) {
281            if (IsInvalidValue(item.Value))
282              chart.Series[row.Name].Points[item.Index].IsEmpty = true;
283            else {
284              chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
285              chart.Series[row.Name].Points[item.Index].IsEmpty = false;
286            }
287          }
288        }
289      }
290    }
291
292    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
293      if (InvokeRequired)
294        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset), sender, e);
295      else {
296        DataRow row = null;
297        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
298        if (row != null) {
299          chart.Series[row.Name].Points.Clear();
300          foreach (IndexedItem<double> item in e.Items) {
301            if (IsInvalidValue(item.Value))
302              chart.Series[row.Name].Points[item.Index].IsEmpty = true;
303            else {
304              chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
305              chart.Series[row.Name].Points[item.Index].IsEmpty = false;
306            }
307          }
308        }
309      }
310    }
311    #endregion
312
313    private bool IsInvalidValue(double x) {
314      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
315    }
316  }
317}
Note: See TracBrowser for help on using the repository browser.