source: trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionDataTableView.cs @ 8108

Last change on this file since 8108 was 8108, checked in by abeham, 8 years ago

#1869:

  • Removed ToEnumerable extension method (I agree with gkronber and it's just one occurrence)
  • Reset rowNumber to 0 when rebuilding the combined data table
  • Some minor changes (moved ctor below variable/property declaration, replaced some obvious variable types with var)
File size: 8.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.Linq;
25using System.Windows.Forms;
26using HeuristicLab.Analysis;
27using HeuristicLab.Collections;
28using HeuristicLab.Core.Views;
29using HeuristicLab.MainForm;
30
31namespace HeuristicLab.Optimization.Views {
32  [View("RunCollection DataTableView")]
33  [Content(typeof(RunCollection), false)]
34  public partial class RunCollectionDataTableView : ItemView {
35    private const string AllDataRows = "All DataRows";
36
37    public new RunCollection Content {
38      get { return (RunCollection)base.Content; }
39      set { base.Content = value; }
40    }
41
42    private int rowNumber = 0;
43    private bool suppressUpdates;
44    private readonly Dictionary<IRun, IEnumerable<DataRow>> runMapping;
45    private readonly DataTable combinedDataTable;
46    public DataTable CombinedDataTable {
47      get { return combinedDataTable; }
48    }
49
50    public RunCollectionDataTableView() {
51      InitializeComponent();
52      runMapping = new Dictionary<IRun, IEnumerable<DataRow>>();
53      combinedDataTable = new DataTable("Combined DataTable", "A data table containing data rows from multiple runs.");
54      viewHost.Content = combinedDataTable;
55      suppressUpdates = false;
56    }
57
58    #region Content events
59    protected override void RegisterContentEvents() {
60      base.RegisterContentEvents();
61      Content.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
62      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
63      Content.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
64      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
65    }
66    protected override void DeregisterContentEvents() {
67      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
68      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
69      Content.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
70      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
71      base.DeregisterContentEvents();
72    }
73
74    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
75      if (InvokeRequired) {
76        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
77        return;
78      }
79      AddRuns(e.Items);
80    }
81    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
82      if (InvokeRequired) {
83        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
84        return;
85      }
86      RemoveRuns(e.Items);
87    }
88    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
89      if (InvokeRequired) {
90        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
91        return;
92      }
93      RemoveRuns(e.OldItems);
94      AddRuns(e.Items);
95    }
96    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
97      if (InvokeRequired) {
98        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
99        return;
100      }
101      suppressUpdates = Content.UpdateOfRunsInProgress;
102      if (!suppressUpdates) UpdateRuns(Content);
103    }
104
105    private void RegisterRunEvents(IRun run) {
106      run.Changed += new System.EventHandler(run_Changed);
107    }
108    private void DeregisterRunEvents(IRun run) {
109      run.Changed -= new System.EventHandler(run_Changed);
110    }
111    private void run_Changed(object sender, EventArgs e) {
112      if (suppressUpdates) return;
113      var run = (IRun)sender;
114      UpdateRuns(new IRun[] { run });
115    }
116    #endregion
117
118    protected override void OnContentChanged() {
119      base.OnContentChanged();
120      dataTableComboBox.Items.Clear();
121      dataRowComboBox.Items.Clear();
122      combinedDataTable.Rows.Clear();
123      runMapping.Clear();
124
125      if (Content != null) {
126        UpdateDataTableComboBox();
127      }
128    }
129
130    private void RebuildCombinedDataTable() {
131      RemoveRuns(Content);
132      rowNumber = 0;
133      AddRuns(Content);
134    }
135
136    private void AddRuns(IEnumerable<IRun> runs) {
137      foreach (var run in runs) {
138        runMapping[run] = ExtractDataRowsFromRun(run).ToList();
139        RegisterRunEvents(run);
140      }
141      var dataRows = runs.Where(r => r.Visible && runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]);
142      combinedDataTable.Rows.AddRange(dataRows);
143    }
144
145    private void RemoveRuns(IEnumerable<IRun> runs) {
146      var dataRows = runs.Where(r => runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]).ToList();
147      foreach (var run in runs) {
148        if (!runMapping.ContainsKey(run)) continue;
149        runMapping.Remove(run);
150        DeregisterRunEvents(run);
151      }
152      combinedDataTable.Rows.RemoveRange(dataRows);
153    }
154
155    private void UpdateRuns(IEnumerable<IRun> runs) {
156      if (suppressUpdates) return;
157      foreach (var run in runs) {
158        //update color
159        foreach (var dataRow in runMapping[run]) {
160          dataRow.VisualProperties.Color = run.Color;
161        }
162        //update visibility - remove and add all rows to keep the same order as before
163        combinedDataTable.Rows.Clear();
164        combinedDataTable.Rows.AddRange(runMapping.Where(mapping => mapping.Key.Visible).SelectMany(mapping => mapping.Value));
165      }
166    }
167
168    private IEnumerable<DataRow> ExtractDataRowsFromRun(IRun run) {
169      var resultName = (string)dataTableComboBox.SelectedItem;
170      var rowName = (string)dataRowComboBox.SelectedItem;
171      if (!run.Results.ContainsKey(resultName)) yield break;
172
173      var dataTable = (DataTable)run.Results[resultName];
174      foreach (var dataRow in dataTable.Rows) {
175        if (dataRow.Name != rowName && rowName != AllDataRows) continue;
176        rowNumber++;
177        var clonedRow = (DataRow)dataRow.Clone();
178        //row names must be unique -> add incremented number to the row name
179        clonedRow.Name = run.Name + "." + dataRow.Name + rowNumber;
180        clonedRow.VisualProperties.DisplayName = run.Name + "." + dataRow.Name;
181        clonedRow.VisualProperties.Color = run.Color;
182        yield return clonedRow;
183      }
184    }
185
186    private void UpdateDataTableComboBox() {
187      dataTableComboBox.Items.Clear();
188      var dataTables = (from run in Content
189                        from result in run.Results
190                        where result.Value is DataTable
191                        select result.Key).Distinct().ToArray();
192
193      dataTableComboBox.Items.AddRange(dataTables);
194      if (dataTableComboBox.Items.Count > 0) dataTableComboBox.SelectedItem = dataTableComboBox.Items[0];
195    }
196
197    private void UpdateDataRowComboBox() {
198      dataRowComboBox.Items.Clear();
199      var resultName = (string)dataTableComboBox.SelectedItem;
200      var dataTables = from run in Content
201                       where run.Results.ContainsKey(resultName)
202                       select run.Results[resultName] as DataTable;
203      var rowNames = (from dataTable in dataTables
204                      from row in dataTable.Rows
205                      select row.Name).Distinct().ToArray();
206
207      dataRowComboBox.Items.AddRange(rowNames);
208      dataRowComboBox.Items.Add(AllDataRows);
209      if (dataRowComboBox.Items.Count > 0) dataRowComboBox.SelectedItem = dataRowComboBox.Items[0];
210    }
211
212    private void dataTableComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
213      UpdateDataRowComboBox();
214    }
215    private void dataRowComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
216      RebuildCombinedDataTable();
217    }
218  }
219}
Note: See TracBrowser for help on using the repository browser.