Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3530 was 3530, checked in by gkronber, 14 years ago

Checked for invalid values in all series manipulating operations and changed the legend to dock at the top. #920 (Each single objective problem should provide a parameter for its best known quality)

File size: 12.8 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 = "#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 = valuesRowsTable[(IObservableList<double>)sender];
225        foreach (IndexedItem<double> item in e.Items) {
226          var value = item.Value;
227          if (IsInvalidValue(item.Value)) {
228            DataPoint point = new DataPoint();
229            point.IsEmpty = true;
230            chart.Series[row.Name].Points.Insert(item.Index, point);
231          } else {
232            chart.Series[row.Name].Points.InsertY(item.Index, value);
233          }
234        }
235      }
236    }
237    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
238      if (InvokeRequired)
239        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved), sender, e);
240      else {
241        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
242        List<DataPoint> points = new List<DataPoint>();
243        foreach (IndexedItem<double> item in e.Items)
244          points.Add(chart.Series[row.Name].Points[item.Index]);
245        foreach (DataPoint point in points)
246          chart.Series[row.Name].Points.Remove(point);
247      }
248    }
249    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
250      if (InvokeRequired)
251        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced), sender, e);
252      else {
253        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
254        foreach (IndexedItem<double> item in e.Items) {
255          if (IsInvalidValue(item.Value))
256            chart.Series[row.Name].Points[item.Index].IsEmpty = true;
257          else {
258            chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
259            chart.Series[row.Name].Points[item.Index].IsEmpty = false;
260          }
261        }
262      }
263    }
264    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
265      if (InvokeRequired)
266        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved), sender, e);
267      else {
268        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
269        foreach (IndexedItem<double> item in e.Items) {
270          if (IsInvalidValue(item.Value))
271            chart.Series[row.Name].Points[item.Index].IsEmpty = true;
272          else {
273            chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
274            chart.Series[row.Name].Points[item.Index].IsEmpty = false;
275          }
276        }
277      }
278    }
279
280    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
281      if (InvokeRequired)
282        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset), sender, e);
283      else {
284        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
285        chart.Series[row.Name].Points.Clear();
286        foreach (IndexedItem<double> item in e.Items) {
287          if (IsInvalidValue(item.Value))
288            chart.Series[row.Name].Points[item.Index].IsEmpty = true;
289          else {
290            chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
291            chart.Series[row.Name].Points[item.Index].IsEmpty = false;
292          }
293        }
294      }
295    }
296    #endregion
297
298    private bool IsInvalidValue(double x) {
299      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
300    }
301  }
302}
Note: See TracBrowser for help on using the repository browser.