Free cookie consent management tool by TermsFeed Policy Generator

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

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

Implemented first version of best and best known quality handling (#920)

File size: 12.2 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      if (Content == null) {
98        Caption = "DataTable";
99        chart.Enabled = false;
100      } else {
101        Caption = Content.Name + " (" + Content.GetType().Name + ")";
102        chart.Enabled = true;
103        chart.Titles.Add(new Title(Content.Name, Docking.Top));
104        foreach (DataRow row in Content.Rows)
105          AddDataRow(row);
106      }
107    }
108
109    private void AddDataRow(DataRow row) {
110      Series series = new Series(row.Name);
111      series.ChartType = SeriesChartType.FastLine;
112      series.ToolTip = "#VAL";
113      for (int i = 0; i < row.Values.Count; i++) {
114        if (double.IsNaN(row.Values[i])) {
115          DataPoint point = new DataPoint();
116          point.IsEmpty = true;
117          series.Points.Add(point);
118        } else {
119          series.Points.Add(row.Values[i]);
120        }
121      }
122      chart.Series.Add(series);
123    }
124    private void RemoveDataRow(DataRow row) {
125      Series series = chart.Series[row.Name];
126      chart.Series.Remove(series);
127    }
128
129    #region Content Events
130    private void RegisterDataRowEvents(DataRow row) {
131      row.NameChanged += new EventHandler(Row_NameChanged);
132      valuesRowsTable.Add(row.Values, row);
133      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
134      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
135      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
136      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
137      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
138    }
139    private void DeregisterDataRowEvents(DataRow row) {
140      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
141      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
142      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
143      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
144      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
145      valuesRowsTable.Remove(row.Values);
146      row.NameChanged -= new EventHandler(Row_NameChanged);
147    }
148    protected override void Content_NameChanged(object sender, EventArgs e) {
149      if (InvokeRequired)
150        Invoke(new EventHandler(Content_NameChanged), sender, e);
151      else {
152        chart.Titles[0].Text = Content.Name;
153        base.Content_NameChanged(sender, e);
154      }
155    }
156    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
157      if (InvokeRequired)
158        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded), sender, e);
159      else {
160        foreach (DataRow row in e.Items) {
161          AddDataRow(row);
162          RegisterDataRowEvents(row);
163        }
164      }
165    }
166    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
167      if (InvokeRequired)
168        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved), sender, e);
169      else {
170        foreach (DataRow row in e.Items) {
171          DeregisterDataRowEvents(row);
172          RemoveDataRow(row);
173        }
174      }
175    }
176    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
177      if (InvokeRequired)
178        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);
179      else {
180        foreach (DataRow row in e.OldItems) {
181          DeregisterDataRowEvents(row);
182          RemoveDataRow(row);
183        }
184        foreach (DataRow row in e.Items) {
185          AddDataRow(row);
186          RegisterDataRowEvents(row);
187        }
188      }
189    }
190    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
191      if (InvokeRequired)
192        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset), sender, e);
193      else {
194        foreach (DataRow row in e.OldItems) {
195          DeregisterDataRowEvents(row);
196          RemoveDataRow(row);
197        }
198        foreach (DataRow row in e.Items) {
199          AddDataRow(row);
200          RegisterDataRowEvents(row);
201        }
202      }
203    }
204    private void Row_NameChanged(object sender, EventArgs e) {
205      if (InvokeRequired)
206        Invoke(new EventHandler(Row_NameChanged), sender, e);
207      else {
208        DataRow row = (DataRow)sender;
209        chart.Series[row.Name].Name = row.Name;
210      }
211    }
212    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
213      if (InvokeRequired)
214        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded), sender, e);
215      else {
216        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
217        foreach (IndexedItem<double> item in e.Items) {
218          if (double.IsNaN(item.Value)) {
219            DataPoint point = new DataPoint();
220            point.IsEmpty = true;
221            chart.Series[row.Name].Points.Insert(item.Index, point);
222          } else {
223            chart.Series[row.Name].Points.InsertY(item.Index, item.Value);
224          }
225        }
226      }
227    }
228    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
229      if (InvokeRequired)
230        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved), sender, e);
231      else {
232        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
233        List<DataPoint> points = new List<DataPoint>();
234        foreach (IndexedItem<double> item in e.Items)
235          points.Add(chart.Series[row.Name].Points[item.Index]);
236        foreach (DataPoint point in points)
237          chart.Series[row.Name].Points.Remove(point);
238      }
239    }
240    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
241      if (InvokeRequired)
242        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced), sender, e);
243      else {
244        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
245        foreach (IndexedItem<double> item in e.Items) {
246          if (double.IsNaN(item.Value))
247            chart.Series[row.Name].Points[item.Index].IsEmpty = true;
248          else
249            chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
250        }
251      }
252    }
253    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
254      if (InvokeRequired)
255        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved), sender, e);
256      else {
257        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
258        foreach (IndexedItem<double> item in e.Items) {
259          if (double.IsNaN(item.Value))
260            chart.Series[row.Name].Points[item.Index].IsEmpty = true;
261          else
262            chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
263        }
264      }
265    }
266    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
267      if (InvokeRequired)
268        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset), sender, e);
269      else {
270        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
271        chart.Series[row.Name].Points.Clear();
272        foreach (IndexedItem<double> item in e.Items) {
273          if (double.IsNaN(item.Value))
274            chart.Series[row.Name].Points[item.Index].IsEmpty = true;
275          else
276            chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
277        }
278      }
279    }
280    #endregion
281  }
282}
Note: See TracBrowser for help on using the repository browser.