Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataTable.cs @ 18183

Last change on this file since 18183 was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

File size: 12.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using HeuristicLab.Collections;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HEAL.Attic;
32
33namespace HeuristicLab.Analysis {
34  [Item("IndexedDataTable", "A data table where the points are also given with a certain index.")]
35  [StorableType("1453C842-6312-4931-9B05-20399A0528D6")]
36  public class IndexedDataTable<T> : NamedItem, IStringConvertibleMatrix, IDataTable<IndexedDataRow<T>> {
37    public static new Image StaticItemImage {
38      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
39    }
40
41    private DataTableVisualProperties visualProperties;
42    public DataTableVisualProperties VisualProperties {
43      get { return visualProperties; }
44      set {
45        if (visualProperties != value) {
46          if (value == null) throw new ArgumentNullException("VisualProperties");
47          if (visualProperties != null) visualProperties.PropertyChanged -= new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
48          visualProperties = value;
49          visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
50          OnVisualPropertiesChanged();
51        }
52      }
53    }
54
55    private NamedItemCollection<IndexedDataRow<T>> rows;
56    public NamedItemCollection<IndexedDataRow<T>> Rows {
57      get { return rows; }
58    }
59
60    #region Persistence Properties
61    [Storable(Name = "VisualProperties")]
62    private DataTableVisualProperties StorableVisualProperties {
63      get { return visualProperties; }
64      set {
65        visualProperties = value;
66        visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
67      }
68    }
69    [Storable(Name = "rows")]
70    private IEnumerable<IndexedDataRow<T>> StorableRows {
71      get { return rows; }
72      set { rows = new NamedItemCollection<IndexedDataRow<T>>(value); }
73    }
74    #endregion
75
76    [StorableConstructor]
77    protected IndexedDataTable(StorableConstructorFlag _) : base(_) { }
78    protected IndexedDataTable(IndexedDataTable<T> original, Cloner cloner)
79      : base(original, cloner) {
80      VisualProperties = (DataTableVisualProperties)cloner.Clone(original.visualProperties);
81      rows = cloner.Clone(original.rows);
82      this.RegisterRowsEvents();
83    }
84    public IndexedDataTable()
85      : base() {
86      VisualProperties = new DataTableVisualProperties();
87      rows = new NamedItemCollection<IndexedDataRow<T>>();
88      this.RegisterRowsEvents();
89    }
90    public IndexedDataTable(string name)
91      : base(name) {
92      VisualProperties = new DataTableVisualProperties(name);
93      rows = new NamedItemCollection<IndexedDataRow<T>>();
94      this.RegisterRowsEvents();
95    }
96    public IndexedDataTable(string name, string description)
97      : base(name, description) {
98      VisualProperties = new DataTableVisualProperties(name);
99      rows = new NamedItemCollection<IndexedDataRow<T>>();
100      this.RegisterRowsEvents();
101    }
102
103    public override IDeepCloneable Clone(Cloner cloner) {
104      return new IndexedDataTable<T>(this, cloner);
105    }
106
107    #region BackwardsCompatibility3.3
108    // Using the name as title is the old style
109    [Storable(DefaultValue = true)]
110    private bool useNameAsTitle = false;
111    #endregion
112
113    [StorableHook(HookType.AfterDeserialization)]
114    private void AfterDeserialization() {
115      // BackwardsCompatibility3.3
116      #region Backwards compatible code, remove with 3.4
117      // Previously, the Name of the IndexedDataTable was used as Title
118      if (useNameAsTitle && string.IsNullOrEmpty(VisualProperties.Title)) {
119        VisualProperties.Title = Name;
120        useNameAsTitle = false;
121      }
122      #endregion
123    }
124
125    public event EventHandler VisualPropertiesChanged;
126    protected virtual void OnVisualPropertiesChanged() {
127      var handler = VisualPropertiesChanged;
128      if (handler != null) handler(this, EventArgs.Empty);
129    }
130
131    private void VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
132      OnVisualPropertiesChanged();
133    }
134
135    private void RegisterRowsEvents() {
136      rows.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(RowsOnItemsAdded);
137      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(RowsOnItemsRemoved);
138      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(RowsOnItemsReplaced);
139      rows.CollectionReset += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(RowsOnCollectionReset);
140      foreach (var row in Rows) RegisterRowEvents(row);
141    }
142    protected virtual void RowsOnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
143      foreach (var row in e.Items)
144        this.RegisterRowEvents(row);
145
146      this.OnColumnsChanged();
147      this.OnColumnNamesChanged();
148      this.OnReset();
149    }
150    protected virtual void RowsOnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
151      foreach (var row in e.Items)
152        this.DeregisterRowEvents(row);
153
154      this.OnColumnsChanged();
155      this.OnColumnNamesChanged();
156      this.OnReset();
157    }
158    protected virtual void RowsOnItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
159      foreach (var row in e.OldItems)
160        this.DeregisterRowEvents(row);
161      foreach (var row in e.Items)
162        this.RegisterRowEvents(row);
163
164      this.OnColumnsChanged();
165      this.OnColumnNamesChanged();
166      this.OnReset();
167    }
168    protected virtual void RowsOnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
169      foreach (var row in e.OldItems)
170        this.DeregisterRowEvents(row);
171      foreach (var row in e.Items)
172        this.RegisterRowEvents(row);
173
174      if (e.OldItems.Count() != e.Items.Count())
175        this.OnColumnsChanged();
176      this.OnColumnNamesChanged();
177      this.OnReset();
178    }
179
180    private void RegisterRowEvents(IndexedDataRow<T> row) {
181      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsAdded);
182      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsMoved);
183      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsRemoved);
184      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsReplaced);
185      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnCollectionReset);
186    }
187    private void DeregisterRowEvents(IndexedDataRow<T> row) {
188      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsAdded);
189      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsMoved);
190      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsRemoved);
191      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsReplaced);
192      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnCollectionReset);
193    }
194
195    protected virtual void ValuesOnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
196      this.OnReset();
197    }
198    protected virtual void ValuesOnItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
199      this.OnReset();
200    }
201    protected virtual void ValuesOnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
202      this.OnReset();
203    }
204    protected virtual void ValuesOnItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
205      this.OnReset();
206    }
207    protected virtual void ValuesOnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
208      this.OnReset();
209    }
210
211    #region IStringConvertibleMatrix Members
212
213    int IStringConvertibleMatrix.Rows {
214      get { return rows.Count == 0 ? 0 : rows.Max(r => r.Values.Count); }
215      set { throw new NotSupportedException(); }
216    }
217    int IStringConvertibleMatrix.Columns {
218      get { return rows.Count * 2; }
219      set { throw new NotSupportedException(); }
220    }
221    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
222      get { return rows.Select(r => new string[] { r.Name + " Index", r.Name }).SelectMany(x => x); }
223      set { throw new NotSupportedException(); }
224    }
225    IEnumerable<string> IStringConvertibleMatrix.RowNames {
226      get { return new List<string>(); }
227      set { throw new NotSupportedException(); }
228    }
229
230    bool IStringConvertibleMatrix.SortableView {
231      get { return true; }
232      set { throw new NotSupportedException(); }
233    }
234    bool IStringConvertibleMatrix.ReadOnly {
235      get { return true; }
236    }
237
238    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
239      if (columnIndex < rows.Count * 2) {
240        string columnName = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
241        if (!rows.ContainsKey(columnName) && columnName.Length > " Index".Length) {
242          columnName = columnName.Substring(0, columnName.Length - " Index".Length);
243          if (rows.ContainsKey(columnName) && rowIndex < rows[columnName].Values.Count)
244            return rows[columnName].Values[rowIndex].Item1.ToString();
245          else return string.Empty;
246        } else if (rows.ContainsKey(columnName) && rowIndex < rows[columnName].Values.Count)
247          return rows[columnName].Values[rowIndex].Item2.ToString();
248      }
249      return string.Empty;
250    }
251
252    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
253      throw new NotSupportedException();
254    }
255    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
256      throw new NotSupportedException();
257    }
258
259    public event EventHandler<EventArgs<int, int>> ItemChanged;
260    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
261      var handler = ItemChanged;
262      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
263      OnToStringChanged();
264    }
265    public event EventHandler Reset;
266    protected virtual void OnReset() {
267      var handler = Reset;
268      if (handler != null) handler(this, EventArgs.Empty);
269    }
270    public event EventHandler ColumnsChanged;
271    protected virtual void OnColumnsChanged() {
272      var handler = ColumnsChanged;
273      if (handler != null) handler(this, EventArgs.Empty);
274    }
275    public event EventHandler RowsChanged;
276    protected virtual void OnRowsChanged() {
277      var handler = RowsChanged;
278      if (handler != null) handler(this, EventArgs.Empty);
279    }
280    public event EventHandler ColumnNamesChanged;
281    protected virtual void OnColumnNamesChanged() {
282      var handler = ColumnNamesChanged;
283      if (handler != null) handler(this, EventArgs.Empty);
284    }
285    public event EventHandler RowNamesChanged;
286    protected virtual void OnRowNamesChanged() {
287      var handler = RowNamesChanged;
288      if (handler != null) handler(this, EventArgs.Empty);
289    }
290    public event EventHandler SortableViewChanged;
291    protected virtual void OnSortableViewChanged() {
292      var handler = SortableViewChanged;
293      if (handler != null) handler(this, EventArgs.Empty);
294    }
295    #endregion
296  }
297}
Note: See TracBrowser for help on using the repository browser.