Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs @ 8578

Last change on this file since 8578 was 8578, checked in by sforsten, 12 years ago

#1292:

  • added ProblemDataView which has a button to open the feature correlation
  • added abstract base class for feature correlations
  • added caches for the feature correlation
  • created own class for calculation of feature correlation
  • changed SelectedItemChanged to SelectionChangeCommitted events, so the correlation is only calculated if the user changes the selection
File size: 12.8 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.ComponentModel;
25using System.Drawing;
26using System.Linq;
27using System.Text;
28using System.Windows.Forms;
29using HeuristicLab.Analysis;
30using HeuristicLab.Common;
31using HeuristicLab.Data.Views;
32using HeuristicLab.MainForm;
33using HeuristicLab.MainForm.WindowsForms;
34using FCE = HeuristicLab.Problems.DataAnalysis.FeatureCorrelationEnums;
35
36namespace HeuristicLab.Problems.DataAnalysis.Views {
37  [View("Feature Correlation View")]
38  [Content(typeof(DataAnalysisProblemData), false)]
39  public abstract partial class AbstractFeatureCorrelationView : AsynchronousContentView {
40
41    private int[] virtualRowIndices;
42    private List<KeyValuePair<int, SortOrder>> sortedColumnIndices;
43    private StringConvertibleMatrixView.RowComparer rowComparer;
44
45    protected FeatureCorrelationCalculator fcc;
46    protected HeatMap currentCorrelation;
47
48    public new DataAnalysisProblemData Content {
49      get { return (DataAnalysisProblemData)base.Content; }
50      set { base.Content = value; }
51    }
52
53    public AbstractFeatureCorrelationView() {
54      InitializeComponent();
55      sortedColumnIndices = new List<KeyValuePair<int, SortOrder>>();
56      rowComparer = new StringConvertibleMatrixView.RowComparer();
57      fcc = new FeatureCorrelationCalculator();
58      var calculatorList = FCE.EnumToList<FCE.CorrelationCalculators>().Select(x => new KeyValuePair<FCE.CorrelationCalculators, string>(x, FCE.GetEnumDescription(x))).ToList();
59      CorrelationCalcComboBox.ValueMember = "Key";
60      CorrelationCalcComboBox.DisplayMember = "Value";
61      CorrelationCalcComboBox.DataSource = new BindingList<KeyValuePair<FCE.CorrelationCalculators, string>>(calculatorList);
62      var partitionList = FCE.EnumToList<FCE.Partitions>().Select(x => new KeyValuePair<FCE.Partitions, string>(x, FCE.GetEnumDescription(x))).ToList();
63      PartitionComboBox.ValueMember = "Key";
64      PartitionComboBox.DisplayMember = "Value";
65      PartitionComboBox.DataSource = new BindingList<KeyValuePair<FCE.Partitions, string>>(partitionList);
66    }
67
68    protected override void RegisterContentEvents() {
69      base.RegisterContentEvents();
70      fcc.ProgressCalculation += new DataAnalysis.FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
71      fcc.CorrelationCalculationFinished += new DataAnalysis.FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
72    }
73
74    protected override void DeregisterContentEvents() {
75      fcc.CorrelationCalculationFinished += new DataAnalysis.FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
76      fcc.ProgressCalculation += new DataAnalysis.FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
77      base.DeregisterContentEvents();
78    }
79
80    protected override void OnContentChanged() {
81      base.OnContentChanged();
82      if (Content != null) {
83        fcc.ProblemData = Content;
84        CalculateCorrelation();
85      } else {
86        DataGridView.Columns.Clear();
87        DataGridView.Rows.Clear();
88      }
89    }
90
91    protected void CorrelationMeasureComboBox_SelectedChangeCommitted(object sender, System.EventArgs e) {
92      CalculateCorrelation();
93    }
94    protected void PartitionComboBox_SelectedChangeCommitted(object sender, System.EventArgs e) {
95      CalculateCorrelation();
96    }
97
98    protected abstract void CalculateCorrelation();
99
100    protected void UpdateDataGrid() {
101      virtualRowIndices = Enumerable.Range(0, currentCorrelation.Rows).ToArray();
102      DataGridViewColumn[] columns = new DataGridViewColumn[currentCorrelation.Columns];
103      for (int i = 0; i < columns.Length; ++i) {
104        var column = new DataGridViewTextBoxColumn();
105        column.FillWeight = 1;
106        columns[i] = column;
107      }
108
109      DataGridView.Columns.Clear();
110      DataGridView.Columns.AddRange(columns);
111
112      DataGridView.RowCount = currentCorrelation.Rows;
113
114      ClearSorting();
115      UpdateColumnHeaders();
116      UpdateRowHeaders();
117
118      maximumLabel.Text = currentCorrelation.Maximum.ToString();
119      minimumLabel.Text = currentCorrelation.Minimum.ToString();
120
121      DataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader);
122      DataGridView.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders);
123      DataGridView.Enabled = true;
124    }
125
126    protected virtual void UpdateColumnHeaders() {
127      for (int i = 0; i < DataGridView.ColumnCount; i++) {
128        DataGridView.Columns[i].HeaderText = currentCorrelation.ColumnNames.ElementAt(i);
129      }
130    }
131    protected virtual void UpdateRowHeaders() {
132      for (int i = 0; i < DataGridView.RowCount; i++) {
133        DataGridView.Rows[i].HeaderCell.Value = currentCorrelation.RowNames.ElementAt(virtualRowIndices[i]);
134      }
135    }
136
137    protected void Content_ProgressCalculation(object sender, ProgressChangedEventArgs e) {
138      if (!CalculatingPanel.Visible && e.ProgressPercentage != HeatMapProgressBar.Maximum) {
139        CalculatingPanel.Show();
140      } else if (e.ProgressPercentage == HeatMapProgressBar.Maximum) {
141        CalculatingPanel.Hide();
142      }
143      HeatMapProgressBar.Value = e.ProgressPercentage;
144    }
145
146    protected abstract void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e);
147
148    protected void DataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) {
149      if (Content == null) return;
150      int rowIndex = virtualRowIndices[e.RowIndex];
151      e.Value = currentCorrelation[rowIndex, e.ColumnIndex];
152    }
153
154    protected void DataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
155      if (Content == null) return;
156      if (e.RowIndex < 0) return;
157      if (e.ColumnIndex < 0) return;
158      if (e.State.HasFlag(DataGridViewElementStates.Selected)) return;
159      if (!e.PaintParts.HasFlag(DataGridViewPaintParts.Background)) return;
160
161      int rowIndex = virtualRowIndices[e.RowIndex];
162      Color backColor = GetDataPointColor(currentCorrelation[rowIndex, e.ColumnIndex], currentCorrelation.Minimum, currentCorrelation.Maximum);
163      using (Brush backColorBrush = new SolidBrush(backColor)) {
164        e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
165      }
166      e.PaintContent(e.CellBounds);
167      e.Handled = true;
168    }
169
170    protected virtual Color GetDataPointColor(double value, double min, double max) {
171      IList<Color> colors = ColorGradient.Colors;
172      int index = (int)((colors.Count - 1) * (value - min) / (max - min));
173      if (index >= colors.Count) index = colors.Count - 1;
174      if (index < 0) index = 0;
175      return colors[index];
176    }
177
178    #region sort
179    protected void DataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
180      if (Content != null) {
181        if (e.Button == MouseButtons.Left) {
182          bool addToSortedIndices = (Control.ModifierKeys & Keys.Control) == Keys.Control;
183          SortOrder newSortOrder = SortOrder.Ascending;
184          if (sortedColumnIndices.Any(x => x.Key == e.ColumnIndex)) {
185            SortOrder oldSortOrder = sortedColumnIndices.Where(x => x.Key == e.ColumnIndex).First().Value;
186            int enumLength = Enum.GetValues(typeof(SortOrder)).Length;
187            newSortOrder = oldSortOrder = (SortOrder)Enum.Parse(typeof(SortOrder), ((((int)oldSortOrder) + 1) % enumLength).ToString());
188          }
189
190          if (!addToSortedIndices)
191            sortedColumnIndices.Clear();
192
193          if (sortedColumnIndices.Any(x => x.Key == e.ColumnIndex)) {
194            int sortedIndex = sortedColumnIndices.FindIndex(x => x.Key == e.ColumnIndex);
195            if (newSortOrder != SortOrder.None)
196              sortedColumnIndices[sortedIndex] = new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder);
197            else
198              sortedColumnIndices.RemoveAt(sortedIndex);
199          } else
200            if (newSortOrder != SortOrder.None)
201              sortedColumnIndices.Add(new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder));
202          Sort();
203        }
204      }
205    }
206
207    protected virtual void ClearSorting() {
208      virtualRowIndices = Enumerable.Range(0, currentCorrelation.Rows).ToArray();
209      sortedColumnIndices.Clear();
210      UpdateSortGlyph();
211    }
212
213    private void Sort() {
214      virtualRowIndices = Sort(sortedColumnIndices);
215      UpdateSortGlyph();
216      UpdateRowHeaders();
217      DataGridView.Invalidate();
218    }
219
220    protected virtual int[] Sort(IEnumerable<KeyValuePair<int, SortOrder>> sortedColumns) {
221      int[] newSortedIndex = Enumerable.Range(0, currentCorrelation.Rows).ToArray();
222      if (sortedColumns.Count() != 0) {
223        rowComparer.SortedIndices = sortedColumns;
224        rowComparer.Matrix = currentCorrelation;
225        Array.Sort(newSortedIndex, rowComparer);
226      }
227      return newSortedIndex;
228    }
229    private void UpdateSortGlyph() {
230      foreach (DataGridViewColumn col in this.DataGridView.Columns)
231        col.HeaderCell.SortGlyphDirection = SortOrder.None;
232      foreach (KeyValuePair<int, SortOrder> p in sortedColumnIndices)
233        this.DataGridView.Columns[p.Key].HeaderCell.SortGlyphDirection = p.Value;
234    }
235    #endregion
236
237    #region copy
238    protected void DataGridView_KeyDown(object sender, KeyEventArgs e) {
239      if (e.Control && e.KeyCode == Keys.C)
240        CopyValuesFromDataGridView();
241    }
242
243    private void CopyValuesFromDataGridView() {
244      if (DataGridView.SelectedCells.Count == 0) return;
245      StringBuilder s = new StringBuilder();
246      int minRowIndex = DataGridView.SelectedCells[0].RowIndex;
247      int maxRowIndex = DataGridView.SelectedCells[DataGridView.SelectedCells.Count - 1].RowIndex;
248      int minColIndex = DataGridView.SelectedCells[0].ColumnIndex;
249      int maxColIndex = DataGridView.SelectedCells[DataGridView.SelectedCells.Count - 1].ColumnIndex;
250
251      if (minRowIndex > maxRowIndex) {
252        int temp = minRowIndex;
253        minRowIndex = maxRowIndex;
254        maxRowIndex = temp;
255      }
256      if (minColIndex > maxColIndex) {
257        int temp = minColIndex;
258        minColIndex = maxColIndex;
259        maxColIndex = temp;
260      }
261
262      bool addRowNames = DataGridView.AreAllCellsSelected(false) && currentCorrelation.RowNames.Count() > 0;
263      bool addColumnNames = DataGridView.AreAllCellsSelected(false) && currentCorrelation.ColumnNames.Count() > 0;
264
265      //add colum names
266      if (addColumnNames) {
267        if (addRowNames)
268          s.Append('\t');
269
270        DataGridViewColumn column = DataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
271        while (column != null) {
272          s.Append(column.HeaderText);
273          s.Append('\t');
274          column = DataGridView.Columns.GetNextColumn(column, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
275        }
276        s.Remove(s.Length - 1, 1); //remove last tab
277        s.Append(Environment.NewLine);
278      }
279
280      for (int i = minRowIndex; i <= maxRowIndex; i++) {
281        int rowIndex = this.virtualRowIndices[i];
282        if (addRowNames) {
283          s.Append(currentCorrelation.RowNames.ElementAt(rowIndex));
284          s.Append('\t');
285        }
286
287        DataGridViewColumn column = DataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
288        while (column != null) {
289          DataGridViewCell cell = DataGridView[column.Index, i];
290          if (cell.Selected) {
291            s.Append(currentCorrelation[rowIndex, column.Index]);
292            s.Append('\t');
293          }
294
295          column = DataGridView.Columns.GetNextColumn(column, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
296        }
297        s.Remove(s.Length - 1, 1); //remove last tab
298        s.Append(Environment.NewLine);
299      }
300      Clipboard.SetText(s.ToString());
301    }
302    #endregion
303  }
304}
Note: See TracBrowser for help on using the repository browser.