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

Last change on this file since 8738 was 8738, checked in by mkommend, 8 years ago

#1673: Added new property AlgorithmName to the RunCollection and synced the property with the name of the surrounding IOptimizer. The AlgorithmName is used by the RunCollectionViews as prefix for its caption if it was set.

File size: 9.2 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      Content.AlgorithmNameChanged += new EventHandler(Content_AlgorithmNameChanged);
66    }
67    protected override void DeregisterContentEvents() {
68      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
69      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
70      Content.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
71      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
72      Content.AlgorithmNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
73      base.DeregisterContentEvents();
74    }
75
76    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
77      if (InvokeRequired) {
78        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
79        return;
80      }
81      AddRuns(e.Items);
82    }
83    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
84      if (InvokeRequired) {
85        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
86        return;
87      }
88      RemoveRuns(e.Items);
89    }
90    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
91      if (InvokeRequired) {
92        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
93        return;
94      }
95      RemoveRuns(e.OldItems);
96      AddRuns(e.Items);
97    }
98    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
99      if (InvokeRequired)
100        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
101      else UpdateCaption();
102    }
103    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
104      if (InvokeRequired) {
105        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
106        return;
107      }
108      suppressUpdates = Content.UpdateOfRunsInProgress;
109      if (!suppressUpdates) UpdateRuns(Content);
110    }
111
112    private void RegisterRunEvents(IRun run) {
113      run.Changed += new System.EventHandler(run_Changed);
114    }
115    private void DeregisterRunEvents(IRun run) {
116      run.Changed -= new System.EventHandler(run_Changed);
117    }
118    private void run_Changed(object sender, EventArgs e) {
119      if (suppressUpdates) return;
120      var run = (IRun)sender;
121      UpdateRuns(new IRun[] { run });
122    }
123    #endregion
124
125    protected override void OnContentChanged() {
126      base.OnContentChanged();
127      dataTableComboBox.Items.Clear();
128      dataRowComboBox.Items.Clear();
129      combinedDataTable.Rows.Clear();
130      runMapping.Clear();
131
132      UpdateCaption();
133      if (Content != null) {
134        UpdateDataTableComboBox();
135      }
136    }
137
138    private void RebuildCombinedDataTable() {
139      RemoveRuns(Content);
140      rowNumber = 0;
141      AddRuns(Content);
142    }
143
144    private void AddRuns(IEnumerable<IRun> runs) {
145      foreach (var run in runs) {
146        runMapping[run] = ExtractDataRowsFromRun(run).ToList();
147        RegisterRunEvents(run);
148      }
149      var dataRows = runs.Where(r => r.Visible && runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]);
150      combinedDataTable.Rows.AddRange(dataRows);
151    }
152
153    private void RemoveRuns(IEnumerable<IRun> runs) {
154      var dataRows = runs.Where(r => runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]).ToList();
155      foreach (var run in runs) {
156        if (!runMapping.ContainsKey(run)) continue;
157        runMapping.Remove(run);
158        DeregisterRunEvents(run);
159      }
160      combinedDataTable.Rows.RemoveRange(dataRows);
161    }
162
163    private void UpdateRuns(IEnumerable<IRun> runs) {
164      if (suppressUpdates) return;
165      foreach (var run in runs) {
166        //update color
167        foreach (var dataRow in runMapping[run]) {
168          dataRow.VisualProperties.Color = run.Color;
169        }
170        //update visibility - remove and add all rows to keep the same order as before
171        combinedDataTable.Rows.Clear();
172        combinedDataTable.Rows.AddRange(runMapping.Where(mapping => mapping.Key.Visible).SelectMany(mapping => mapping.Value));
173      }
174    }
175
176    private IEnumerable<DataRow> ExtractDataRowsFromRun(IRun run) {
177      var resultName = (string)dataTableComboBox.SelectedItem;
178      var rowName = (string)dataRowComboBox.SelectedItem;
179      if (!run.Results.ContainsKey(resultName)) yield break;
180
181      var dataTable = (DataTable)run.Results[resultName];
182      foreach (var dataRow in dataTable.Rows) {
183        if (dataRow.Name != rowName && rowName != AllDataRows) continue;
184        rowNumber++;
185        var clonedRow = (DataRow)dataRow.Clone();
186        //row names must be unique -> add incremented number to the row name
187        clonedRow.Name = run.Name + "." + dataRow.Name + rowNumber;
188        clonedRow.VisualProperties.DisplayName = run.Name + "." + dataRow.Name;
189        clonedRow.VisualProperties.Color = run.Color;
190        yield return clonedRow;
191      }
192    }
193
194    private void UpdateDataTableComboBox() {
195      dataTableComboBox.Items.Clear();
196      var dataTables = (from run in Content
197                        from result in run.Results
198                        where result.Value is DataTable
199                        select result.Key).Distinct().ToArray();
200
201      dataTableComboBox.Items.AddRange(dataTables);
202      if (dataTableComboBox.Items.Count > 0) dataTableComboBox.SelectedItem = dataTableComboBox.Items[0];
203    }
204
205    private void UpdateCaption() {
206      Caption = Content != null ? Content.AlgorithmName + "Data Table" : ViewAttribute.GetViewName(GetType());
207    }
208
209    private void UpdateDataRowComboBox() {
210      dataRowComboBox.Items.Clear();
211      var resultName = (string)dataTableComboBox.SelectedItem;
212      var dataTables = from run in Content
213                       where run.Results.ContainsKey(resultName)
214                       select run.Results[resultName] as DataTable;
215      var rowNames = (from dataTable in dataTables
216                      from row in dataTable.Rows
217                      select row.Name).Distinct().ToArray();
218
219      dataRowComboBox.Items.AddRange(rowNames);
220      dataRowComboBox.Items.Add(AllDataRows);
221      if (dataRowComboBox.Items.Count > 0) dataRowComboBox.SelectedItem = dataRowComboBox.Items[0];
222    }
223
224    private void dataTableComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
225      UpdateDataRowComboBox();
226    }
227    private void dataRowComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
228      RebuildCombinedDataTable();
229    }
230  }
231}
Note: See TracBrowser for help on using the repository browser.