source: trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.cs @ 12012

Last change on this file since 12012 was 12012, checked in by ascheibe, 6 years ago

#2212 merged r12008, r12009, r12010 back into trunk

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