source: trunk/sources/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs @ 12012

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

#2212 merged r12008, r12009, r12010 back into trunk

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