source: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs @ 12718

Last change on this file since 12718 was 12718, checked in by mkommend, 7 years ago

#2335: Merged all changes into stable.

File size: 13.7 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.Linq;
25using System.Windows.Forms;
26using HeuristicLab.Analysis;
27using HeuristicLab.Collections;
28using HeuristicLab.Core.Views;
29using HeuristicLab.Data;
30using HeuristicLab.DataPreprocessing.Implementations;
31using HeuristicLab.MainForm;
32
33namespace HeuristicLab.DataPreprocessing.Views {
34
35  [View("Preprocessing Chart View")]
36  [Content(typeof(PreprocessingChartContent), false)]
37  public partial class PreprocessingChartView : ItemView {
38
39    private PreprocessingDataTable dataTable;
40    private List<PreprocessingDataTable> dataTablePerVariable;
41    private List<DataRow> dataRows;
42    private List<DataRow> selectedDataRows;
43
44    protected DataRowVisualProperties.DataRowChartType chartType;
45    protected string chartTitle;
46
47    private const string DEFAULT_CHART_TITLE = "Chart";
48    private const int FIXED_CHART_SIZE = 300;
49    private const int MAX_TABLE_AUTO_SIZE_ROWS = 3;
50
51    public IEnumerable<double> Classification { get; set; }
52    public bool IsDetailedChartViewEnabled { get; set; }
53
54    public PreprocessingChartView() {
55      InitializeComponent();
56      chartType = DataRowVisualProperties.DataRowChartType.Line;
57      chartTitle = DEFAULT_CHART_TITLE;
58    }
59
60    //Variable selection changed
61    //Add or remove data row
62    private void CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> checkedItems) {
63
64      foreach (IndexedItem<StringValue> item in checkedItems.Items) {
65        string variableName = item.Value.Value;
66
67        //variable is displayed -> remove
68        if (VariableIsDisplayed(variableName)) {
69          dataTable.Rows.Remove(variableName);
70          dataTable.SelectedRows.Remove(variableName);
71          dataTablePerVariable.Remove(dataTablePerVariable.Find(x => (x.Name == variableName)));
72          //variable isnt't displayed -> add
73        } else {
74          DataRow row = GetDataRow(variableName);
75          DataRow selectedRow = GetSelectedDataRow(variableName);
76          dataTable.Rows.Add(row);
77
78          PreprocessingDataTable pdt = new PreprocessingDataTable(variableName);
79          pdt.Rows.Add(row);
80          dataTablePerVariable.Add(pdt);
81
82          //update selection
83          if (selectedRow != null) {
84            dataTable.SelectedRows.Add(selectedRow);
85            pdt.SelectedRows.Add(selectedRow);
86          }
87        }
88      }
89
90      // update chart if not in all in one mode
91      if (Content != null && !Content.AllInOneMode)
92        GenerateChart();
93
94    }
95
96    private bool VariableIsDisplayed(string name) {
97
98      foreach (var item in dataTable.Rows) {
99        if (item.Name == name)
100          return true;
101      }
102      return false;
103    }
104
105    protected override void RegisterContentEvents() {
106      base.RegisterContentEvents();
107      Content.PreprocessingData.Changed += PreprocessingData_Changed;
108      Content.PreprocessingData.SelectionChanged += PreprocessingData_SelctionChanged;
109
110    }
111
112    protected override void DeregisterContentEvents() {
113      base.DeregisterContentEvents();
114      Content.PreprocessingData.Changed -= PreprocessingData_Changed;
115      Content.PreprocessingData.SelectionChanged -= PreprocessingData_SelctionChanged;
116    }
117
118    public new PreprocessingChartContent Content {
119      get { return (PreprocessingChartContent)base.Content; }
120      set { base.Content = value; }
121    }
122
123    private void InitData() {
124      if (Content.VariableItemList == null) {
125        Content.VariableItemList = Content.CreateVariableItemList();
126      } else {
127        var checkedNames = Content.VariableItemList.CheckedItems.Select(x => x.Value.Value);
128        Content.VariableItemList = Content.CreateVariableItemList(checkedNames);
129      }
130      checkedItemList.Content = Content.VariableItemList;
131
132      //Create data tables and data rows
133      dataRows = Content.CreateAllDataRows(chartType);
134      dataTable = new PreprocessingDataTable(chartTitle);
135      dataTablePerVariable = new List<PreprocessingDataTable>();
136
137      //add data rows to data tables according to checked item list
138      foreach (var checkedItem in Content.VariableItemList.CheckedItems) {
139        string variableName = Content.VariableItemList[checkedItem.Index].Value;
140        PreprocessingDataTable d = new PreprocessingDataTable(variableName);
141        DataRow row = GetDataRow(variableName);
142
143        if (row != null) {
144          //add row to data table
145          dataTable.Rows.Add(row);
146
147          //add row to data table per variable
148          d.Rows.Add(row);
149          dataTablePerVariable.Add(d);
150        }
151      }
152
153      UpdateSelection();
154    }
155
156    private void UpdateSelection() {
157
158      //update data table selection
159      selectedDataRows = Content.CreateAllSelectedDataRows(chartType);
160      dataTable.SelectedRows.Clear();
161      foreach (var selectedRow in selectedDataRows) {
162        if (VariableIsDisplayed(selectedRow.Name))
163          dataTable.SelectedRows.Add(selectedRow);
164      }
165
166      //update data table per variable selection
167      foreach (PreprocessingDataTable d in dataTablePerVariable) {
168        d.SelectedRows.Clear();
169        DataRow row = selectedDataRows.Find(x => x.Name == d.Name);
170        if (row != null)
171          d.SelectedRows.Add(row);
172      }
173
174    }
175
176    private DataRow GetSelectedDataRow(string variableName) {
177      foreach (DataRow row in selectedDataRows) {
178        if (row.Name == variableName)
179          return row;
180      }
181      return null;
182    }
183
184    private DataRow GetDataRow(string variableName) {
185      foreach (DataRow row in dataRows) {
186        if (row.Name == variableName)
187          return row;
188      }
189      return null;
190    }
191
192    protected override void OnContentChanged() {
193      base.OnContentChanged();
194      if (Content != null) {
195        InitData();
196        Content.VariableItemList.CheckedItemsChanged += CheckedItemsChanged;
197        GenerateChart();
198      }
199    }
200
201    // TODO : handle also other changed events
202    void PreprocessingData_Changed(object sender, DataPreprocessingChangedEventArgs e) {
203      switch (e.Type) {
204        case DataPreprocessingChangedEventType.DeleteColumn:
205          RemoveVariable(Content.PreprocessingData.GetVariableName(e.Column));
206          break;
207        case DataPreprocessingChangedEventType.AddColumn:
208          AddVariable(Content.PreprocessingData.GetVariableName(e.Column));
209          break;
210        case DataPreprocessingChangedEventType.ChangeColumn:
211        case DataPreprocessingChangedEventType.ChangeItem:
212          UpdateDataForVariable(Content.PreprocessingData.GetVariableName(e.Column));
213          break;
214        case DataPreprocessingChangedEventType.DeleteRow:
215        case DataPreprocessingChangedEventType.AddRow:
216        case DataPreprocessingChangedEventType.Any:
217        default:
218          //TODO: test with transform
219          InitData();
220          GenerateChart();
221          break;
222      }
223    }
224
225    private void PreprocessingData_SelctionChanged(object sender, EventArgs e) {
226      UpdateSelection();
227    }
228
229    private void UpdateDataForVariable(string variableName) {
230      DataRow newRow = Content.CreateDataRow(variableName, chartType);
231      dataTable.Rows.Remove(variableName);
232      dataTable.Rows.Add(newRow);
233      DataTable dt = dataTablePerVariable.Find(x => x.Rows.Find(y => y.Name == variableName) != null);
234      if (dt != null) {
235        dt.Rows.Remove(variableName);
236        dt.Rows.Add(newRow);
237      }
238    }
239
240    // add variable to data table and item list
241    private void AddVariable(string name) {
242      DataRow row = Content.CreateDataRow(name, chartType);
243      dataTable.Rows.Add(row);
244      PreprocessingDataTable d = new PreprocessingDataTable(name);
245      d.Rows.Add(row);
246      dataTablePerVariable.Add(d);
247      Content.VariableItemList.Add(new StringValue(name));
248      if (!Content.AllInOneMode)
249        GenerateChart();
250    }
251
252    // remove variable from data table and item list
253    private void RemoveVariable(string name) {
254      dataTable.Rows.Remove(name);
255      dataTablePerVariable.Remove(dataTablePerVariable.Find(x => (x.Name == name)));
256
257      StringValue stringValue = FindVariableItemList(name);
258      if (stringValue != null)
259        Content.VariableItemList.Remove(stringValue);
260      if (!Content.AllInOneMode)
261        GenerateChart();
262    }
263
264    private StringValue FindVariableItemList(string name) {
265      foreach (StringValue stringValue in Content.VariableItemList) {
266        if (stringValue.Value == name)
267          return stringValue;
268      }
269      return null;
270    }
271
272    protected void GenerateChart() {
273      ClearTableLayout();
274      if (Content.AllInOneMode) {
275        GenerateSingleChartLayout();
276      } else
277        GenerateMultiChartLayout();
278    }
279
280    private void ClearTableLayout() {
281      //Clear out the existing controls
282      tableLayoutPanel.Controls.Clear();
283
284      //Clear out the existing row and column styles
285      tableLayoutPanel.ColumnStyles.Clear();
286      tableLayoutPanel.RowStyles.Clear();
287      tableLayoutPanel.AutoScroll = false;
288      tableLayoutPanel.AutoScroll = true;
289    }
290
291    private void GenerateSingleChartLayout() {
292      tableLayoutPanel.ColumnCount = 1;
293      tableLayoutPanel.RowCount = 1;
294      tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
295      tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
296      tableLayoutPanel.Controls.Add(dataTableView, 0, 0);
297      dataTableView.Content = dataTable;
298    }
299
300    private int GetNrOfMultiChartColumns(int itemCount) {
301      int columns = 0;
302      if (itemCount <= 2)
303        columns = 1;
304      else if (itemCount <= 6)
305        columns = 2;
306      else
307        columns = 3;
308      return columns;
309    }
310
311    private int GetNrOfMultiChartRows(int itemCount, int columns) {
312      int rows = 0;
313      if (columns == 3)
314        rows = (itemCount + 2) / columns;
315      else if (columns == 2)
316        rows = (itemCount + 1) / columns;
317      else
318        rows = itemCount / columns;
319      return rows;
320    }
321
322
323    private void GenerateMultiChartLayout() {
324      int checkedItemsCnt = 0;
325      foreach (var item in Content.VariableItemList.CheckedItems)
326        checkedItemsCnt++;
327
328      // set columns and rows based on number of items
329      int columns = GetNrOfMultiChartColumns(checkedItemsCnt);
330      int rows = GetNrOfMultiChartRows(checkedItemsCnt, columns);
331
332      tableLayoutPanel.ColumnCount = columns;
333      tableLayoutPanel.RowCount = rows;
334
335      List<PreprocessingDataTable>.Enumerator enumerator = dataTablePerVariable.GetEnumerator();
336      for (int x = 0; x < columns; x++) {
337
338        if (rows <= MAX_TABLE_AUTO_SIZE_ROWS)
339          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100 / columns));
340        else
341          //scrollbar is shown if there are more than 3 rows -> remove scroll bar width from total width
342          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, (tableLayoutPanel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth) / columns));
343        for (int y = 0; y < rows; y++) {
344          //Add a row only when creating the first column
345          if (x == 0) {
346            // fixed chart size when there are more than 3 tables
347            if (rows > MAX_TABLE_AUTO_SIZE_ROWS)
348              tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, FIXED_CHART_SIZE));
349            else
350              tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100 / rows));
351          }
352
353          enumerator.MoveNext();
354          PreprocessingDataTable d = enumerator.Current;
355          AddDataTableToTableLayout(d, x, y);
356
357        }
358      }
359    }
360
361    private void AddDataTableToTableLayout(PreprocessingDataTable dataTable, int x, int y) {
362      PreprocessingDataTableView dataView = new PreprocessingDataTableView();
363      dataView.Classification = Classification;
364      dataView.IsDetailedChartViewEnabled = IsDetailedChartViewEnabled;
365
366      if (dataTable == null) {
367        // dummy panel for empty field
368        Panel p = new Panel();
369        p.Dock = DockStyle.Fill;
370        tableLayoutPanel.Controls.Add(p, y, x);
371      } else {
372        dataView.Content = dataTable;
373        dataView.Dock = DockStyle.Fill;
374        tableLayoutPanel.Controls.Add(dataView, y, x);
375      }
376    }
377
378    //Remove horizontal scroll bar if visible
379    private void tableLayoutPanel_Layout(object sender, LayoutEventArgs e) {
380      if (tableLayoutPanel.HorizontalScroll.Visible) {
381        // Add padding on the right in order to accomodate the vertical scrollbar
382        int vWidth = SystemInformation.VerticalScrollBarWidth;
383        tableLayoutPanel.Padding = new Padding(0, 0, vWidth, 0);
384      } else {
385        // Reset padding
386        tableLayoutPanel.Padding = new Padding(0);
387      }
388    }
389
390  }
391}
392
393
Note: See TracBrowser for help on using the repository browser.