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

Last change on this file since 14185 was 14185, checked in by swagner, 5 years ago

#2526: Updated year of copyrights in license headers

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