Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 8729 was 8729, checked in by mkommend, 12 years ago

#1292: Moved FeatureCorrelation specific classes from Problems.DataAnalysis to Problems.DataAnalysis.Views.

File size: 14.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.DataAnalysis.Views;
33using HeuristicLab.MainForm;
34using HeuristicLab.MainForm.WindowsForms;
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 VariableVisibilityDialog variableVisibility;
43    private List<KeyValuePair<int, SortOrder>> sortedColumnIndices;
44    private StringConvertibleMatrixView.RowComparer rowComparer;
45
46    protected FeatureCorrelationCalculator fcc;
47    protected HeatMap currentCorrelation;
48
49    public new DataAnalysisProblemData Content {
50      get { return (DataAnalysisProblemData)base.Content; }
51      set { base.Content = value; }
52    }
53
54    protected AbstractFeatureCorrelationView() {
55      InitializeComponent();
56      sortedColumnIndices = new List<KeyValuePair<int, SortOrder>>();
57      rowComparer = new StringConvertibleMatrixView.RowComparer();
58      fcc = new FeatureCorrelationCalculator();
59      var calculatorList = FeatureCorrelationEnums.EnumToList<FeatureCorrelationEnums.CorrelationCalculators>().Select(x => new KeyValuePair<FeatureCorrelationEnums.CorrelationCalculators, string>(x, FeatureCorrelationEnums.GetEnumDescription(x))).ToList();
60      CorrelationCalcComboBox.ValueMember = "Key";
61      CorrelationCalcComboBox.DisplayMember = "Value";
62      CorrelationCalcComboBox.DataSource = new BindingList<KeyValuePair<FeatureCorrelationEnums.CorrelationCalculators, string>>(calculatorList);
63      var partitionList = FeatureCorrelationEnums.EnumToList<FeatureCorrelationEnums.Partitions>().Select(x => new KeyValuePair<FeatureCorrelationEnums.Partitions, string>(x, FeatureCorrelationEnums.GetEnumDescription(x))).ToList();
64      PartitionComboBox.ValueMember = "Key";
65      PartitionComboBox.DisplayMember = "Value";
66      PartitionComboBox.DataSource = new BindingList<KeyValuePair<FeatureCorrelationEnums.Partitions, string>>(partitionList);
67    }
68
69    protected override void RegisterContentEvents() {
70      base.RegisterContentEvents();
71      fcc.ProgressCalculation += new FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
72      fcc.CorrelationCalculationFinished += new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
73    }
74
75    protected override void DeregisterContentEvents() {
76      fcc.CorrelationCalculationFinished += new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
77      fcc.ProgressCalculation += new FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
78      base.DeregisterContentEvents();
79    }
80
81    protected override void OnContentChanged() {
82      base.OnContentChanged();
83      if (Content != null) {
84        fcc.ProblemData = Content;
85        bool[] initialVisibility = SetInitialVisibilityOfColumns();
86
87        variableVisibility = new VariableVisibilityDialog(Content.Dataset.DoubleVariables, initialVisibility);
88        variableVisibility.VariableVisibilityChanged += new ItemCheckEventHandler(variableVisibility_VariableVisibilityChanged);
89        CalculateCorrelation();
90      } else {
91        DataGridView.Columns.Clear();
92        DataGridView.Rows.Clear();
93      }
94    }
95
96    protected virtual bool[] SetInitialVisibilityOfColumns() {
97      bool[] initialVisibility = new bool[Content.Dataset.DoubleVariables.Count()];
98      int i = 0;
99      foreach (var variable in Content.Dataset.DoubleVariables) {
100        initialVisibility[i] = Content.AllowedInputVariables.Contains(variable);
101        i++;
102      }
103      return initialVisibility;
104    }
105
106    protected abstract void variableVisibility_VariableVisibilityChanged(object sender, ItemCheckEventArgs e);
107
108    protected void CorrelationMeasureComboBox_SelectedChangeCommitted(object sender, System.EventArgs e) {
109      CalculateCorrelation();
110    }
111    protected void PartitionComboBox_SelectedChangeCommitted(object sender, System.EventArgs e) {
112      CalculateCorrelation();
113    }
114
115    protected abstract void CalculateCorrelation();
116    protected abstract void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e);
117
118    protected void UpdateDataGrid() {
119      virtualRowIndices = Enumerable.Range(0, currentCorrelation.Rows).ToArray();
120      DataGridViewColumn[] columns = new DataGridViewColumn[currentCorrelation.Columns];
121      for (int i = 0; i < columns.Length; ++i) {
122        var column = new DataGridViewTextBoxColumn();
123        column.FillWeight = 1;
124        columns[i] = column;
125      }
126
127      DataGridView.Columns.Clear();
128      DataGridView.Columns.AddRange(columns);
129
130      DataGridView.RowCount = currentCorrelation.Rows;
131
132      ClearSorting();
133      UpdateColumnHeaders();
134      UpdateRowHeaders();
135
136      maximumLabel.Text = currentCorrelation.Maximum.ToString();
137      minimumLabel.Text = currentCorrelation.Minimum.ToString();
138
139      DataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader);
140      DataGridView.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders);
141      DataGridView.Enabled = true;
142    }
143
144    protected virtual void UpdateColumnHeaders() {
145      for (int i = 0; i < DataGridView.ColumnCount; i++) {
146        DataGridView.Columns[i].HeaderText = currentCorrelation.ColumnNames.ElementAt(i);
147        DataGridView.Columns[i].Visible = variableVisibility.Visibility[i];
148      }
149    }
150    protected virtual void UpdateRowHeaders() {
151      for (int i = 0; i < DataGridView.RowCount; i++) {
152        DataGridView.Rows[i].HeaderCell.Value = currentCorrelation.RowNames.ElementAt(virtualRowIndices[i]);
153        DataGridView.Rows[i].Visible = variableVisibility.Visibility[virtualRowIndices[i]];
154      }
155    }
156
157    protected void Content_ProgressCalculation(object sender, ProgressChangedEventArgs e) {
158      if (!CalculatingPanel.Visible && e.ProgressPercentage != HeatMapProgressBar.Maximum) {
159        CalculatingPanel.Show();
160      } else if (e.ProgressPercentage == HeatMapProgressBar.Maximum) {
161        CalculatingPanel.Hide();
162      }
163      HeatMapProgressBar.Value = e.ProgressPercentage;
164    }
165
166    protected void DataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) {
167      if (Content == null) return;
168      int rowIndex = virtualRowIndices[e.RowIndex];
169      e.Value = currentCorrelation[rowIndex, e.ColumnIndex];
170    }
171
172    protected void DataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
173      if (Content == null) return;
174      if (e.RowIndex < 0) return;
175      if (e.ColumnIndex < 0) return;
176      if (e.State.HasFlag(DataGridViewElementStates.Selected)) return;
177      if (!e.PaintParts.HasFlag(DataGridViewPaintParts.Background)) return;
178
179      int rowIndex = virtualRowIndices[e.RowIndex];
180      Color backColor = GetDataPointColor(currentCorrelation[rowIndex, e.ColumnIndex], currentCorrelation.Minimum, currentCorrelation.Maximum);
181      using (Brush backColorBrush = new SolidBrush(backColor)) {
182        e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
183      }
184      e.PaintContent(e.CellBounds);
185      e.Handled = true;
186    }
187
188    protected virtual Color GetDataPointColor(double value, double min, double max) {
189      if (double.IsNaN(value)) {
190        return Color.DarkGray;
191      }
192      IList<Color> colors = ColorGradient.Colors;
193      int index = (int)((colors.Count - 1) * (value - min) / (max - min));
194      if (index >= colors.Count) index = colors.Count - 1;
195      if (index < 0) index = 0;
196      return colors[index];
197    }
198
199    #region sort
200    protected void DataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
201      if (Content != null) {
202        if (e.Button == MouseButtons.Left) {
203          bool addToSortedIndices = (Control.ModifierKeys & Keys.Control) == Keys.Control;
204          SortOrder newSortOrder = SortOrder.Ascending;
205          if (sortedColumnIndices.Any(x => x.Key == e.ColumnIndex)) {
206            SortOrder oldSortOrder = sortedColumnIndices.Where(x => x.Key == e.ColumnIndex).First().Value;
207            int enumLength = Enum.GetValues(typeof(SortOrder)).Length;
208            newSortOrder = oldSortOrder = (SortOrder)Enum.Parse(typeof(SortOrder), ((((int)oldSortOrder) + 1) % enumLength).ToString());
209          }
210
211          if (!addToSortedIndices)
212            sortedColumnIndices.Clear();
213
214          if (sortedColumnIndices.Any(x => x.Key == e.ColumnIndex)) {
215            int sortedIndex = sortedColumnIndices.FindIndex(x => x.Key == e.ColumnIndex);
216            if (newSortOrder != SortOrder.None)
217              sortedColumnIndices[sortedIndex] = new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder);
218            else
219              sortedColumnIndices.RemoveAt(sortedIndex);
220          } else
221            if (newSortOrder != SortOrder.None)
222              sortedColumnIndices.Add(new KeyValuePair<int, SortOrder>(e.ColumnIndex, newSortOrder));
223          Sort();
224        }
225      }
226    }
227
228    protected virtual void ClearSorting() {
229      virtualRowIndices = Enumerable.Range(0, currentCorrelation.Rows).ToArray();
230      sortedColumnIndices.Clear();
231      UpdateSortGlyph();
232    }
233
234    private void Sort() {
235      virtualRowIndices = Sort(sortedColumnIndices);
236      UpdateSortGlyph();
237      UpdateRowHeaders();
238      DataGridView.Invalidate();
239    }
240
241    protected virtual int[] Sort(IEnumerable<KeyValuePair<int, SortOrder>> sortedColumns) {
242      int[] newSortedIndex = Enumerable.Range(0, currentCorrelation.Rows).ToArray();
243      if (sortedColumns.Count() != 0) {
244        rowComparer.SortedIndices = sortedColumns;
245        rowComparer.Matrix = currentCorrelation;
246        Array.Sort(newSortedIndex, rowComparer);
247      }
248      return newSortedIndex;
249    }
250    private void UpdateSortGlyph() {
251      foreach (DataGridViewColumn col in this.DataGridView.Columns)
252        col.HeaderCell.SortGlyphDirection = SortOrder.None;
253      foreach (KeyValuePair<int, SortOrder> p in sortedColumnIndices)
254        this.DataGridView.Columns[p.Key].HeaderCell.SortGlyphDirection = p.Value;
255    }
256    #endregion
257
258    #region copy
259    protected void DataGridView_KeyDown(object sender, KeyEventArgs e) {
260      if (e.Control && e.KeyCode == Keys.C)
261        CopyValuesFromDataGridView();
262    }
263
264    private void CopyValuesFromDataGridView() {
265      if (DataGridView.SelectedCells.Count == 0) return;
266      StringBuilder s = new StringBuilder();
267      int minRowIndex = DataGridView.SelectedCells[0].RowIndex;
268      int maxRowIndex = DataGridView.SelectedCells[DataGridView.SelectedCells.Count - 1].RowIndex;
269      int minColIndex = DataGridView.SelectedCells[0].ColumnIndex;
270      int maxColIndex = DataGridView.SelectedCells[DataGridView.SelectedCells.Count - 1].ColumnIndex;
271
272      if (minRowIndex > maxRowIndex) {
273        int temp = minRowIndex;
274        minRowIndex = maxRowIndex;
275        maxRowIndex = temp;
276      }
277      if (minColIndex > maxColIndex) {
278        int temp = minColIndex;
279        minColIndex = maxColIndex;
280        maxColIndex = temp;
281      }
282
283      bool addRowNames = DataGridView.AreAllCellsSelected(false) && currentCorrelation.RowNames.Count() > 0;
284      bool addColumnNames = DataGridView.AreAllCellsSelected(false) && currentCorrelation.ColumnNames.Count() > 0;
285
286      //add colum names
287      if (addColumnNames) {
288        if (addRowNames)
289          s.Append('\t');
290
291        DataGridViewColumn column = DataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
292        while (column != null) {
293          s.Append(column.HeaderText);
294          s.Append('\t');
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
301      for (int i = minRowIndex; i <= maxRowIndex; i++) {
302        int rowIndex = this.virtualRowIndices[i];
303        if (addRowNames) {
304          s.Append(currentCorrelation.RowNames.ElementAt(rowIndex));
305          s.Append('\t');
306        }
307
308        DataGridViewColumn column = DataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
309        while (column != null) {
310          DataGridViewCell cell = DataGridView[column.Index, i];
311          if (cell.Selected) {
312            s.Append(currentCorrelation[rowIndex, column.Index]);
313            s.Append('\t');
314          }
315
316          column = DataGridView.Columns.GetNextColumn(column, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
317        }
318        s.Remove(s.Length - 1, 1); //remove last tab
319        s.Append(Environment.NewLine);
320      }
321      Clipboard.SetText(s.ToString());
322    }
323    #endregion
324
325    protected void ShowHideColumns_Click(object sender, EventArgs e) {
326      variableVisibility.ShowDialog();
327    }
328
329    protected void DataGridView_MouseClick(object sender, MouseEventArgs e) {
330      if (Content == null) return;
331      if (e.Button == MouseButtons.Right && DataGridView.Columns.Count != 0)
332        contextMenu.Show(MousePosition);
333    }
334
335    protected int GetRowIndexOfVirtualindex(int virtualIndex) {
336      if (virtualIndex < 0 || virtualIndex >= virtualRowIndices.Length) {
337        throw new ArgumentException("Virtual index is out of bounds");
338      }
339
340      for (int i = 0; i < virtualRowIndices.Length; i++) {
341        if (virtualRowIndices[i] == virtualIndex) {
342          return i;
343        }
344      }
345      throw new ArgumentException("Virtual index was not found!");
346    }
347  }
348}
Note: See TracBrowser for help on using the repository browser.