Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 14381 was 14381, checked in by pfleck, 7 years ago

#2698

  • Refactored CheckedVariablesView out of the ChartView to allow reuse of the checked variables list.
    • The new list visualizes the non-input/target variables in gray.
    • Added context menu to quickly (un)check all variables or only the inputs+target variables.
  • In the Multi-Scatterplot
    • New structure and layout of the single charts to support fixed header rows and columns (for the variable names). Instead, removed the legend of each plot for better usage of plot area.
    • Adapted the new CheckedVariablesView (but hidden until (un)checking is implemented).
File size: 11.5 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.Data;
29using HeuristicLab.MainForm;
30
31namespace HeuristicLab.DataPreprocessing.Views {
32  [View("Preprocessing Chart View")]
33  [Content(typeof(PreprocessingChartContent), false)]
34  public partial class PreprocessingChartView : PreprocessingCheckedVariablesView {
35
36    protected PreprocessingDataTable dataTable;
37    protected List<PreprocessingDataTable> dataTablePerVariable;
38    protected List<DataRow> dataRows;
39    protected List<DataRow> selectedDataRows;
40
41    protected DataRowVisualProperties.DataRowChartType chartType;
42    protected string chartTitle;
43
44    private const string DEFAULT_CHART_TITLE = "Chart";
45    private const int FIXED_CHART_SIZE = 300;
46    private const int MAX_TABLE_AUTO_SIZE_ROWS = 3;
47
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    protected override void OnContentChanged() {
59      base.OnContentChanged();
60      if (Content != null) {
61        InitData();
62        GenerateChart();
63      }
64    }
65
66    private void InitData() {
67      //Create data tables and data rows
68      dataRows = Content.CreateAllDataRows(chartType);
69      dataTable = new PreprocessingDataTable(chartTitle);
70      dataTablePerVariable = new List<PreprocessingDataTable>();
71
72      //add data rows to data tables according to checked item list
73      foreach (var checkedItem in Content.VariableItemList.CheckedItems) {
74        string variableName = Content.VariableItemList[checkedItem.Index].Value;
75        PreprocessingDataTable d = new PreprocessingDataTable(variableName);
76        DataRow row = GetDataRow(variableName);
77
78        if (row != null) {
79          //add row to data table
80          dataTable.Rows.Add(row);
81
82          //add row to data table per variable
83          d.Rows.Add(row);
84          dataTablePerVariable.Add(d);
85        }
86      }
87
88      UpdateSelection();
89    }
90
91    protected override void CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> checkedItems) {
92      base.CheckedItemsChanged(sender, checkedItems);
93
94      foreach (IndexedItem<StringValue> item in checkedItems.Items) {
95        string variableName = item.Value.Value;
96
97        // not checked -> remove
98        if (!VariableIsChecked(variableName)) {
99          dataTableView.SetRowEnabled(variableName, false);
100          dataTable.SelectedRows.Remove(variableName);
101          dataTablePerVariable.Remove(dataTablePerVariable.Find(x => (x.Name == variableName)));
102        } else {
103          DataRow row = GetDataRow(variableName);
104          DataRow selectedRow = GetSelectedDataRow(variableName);
105          dataTableView.SetRowEnabled(variableName, true);
106
107          PreprocessingDataTable pdt = new PreprocessingDataTable(variableName);
108          pdt.Rows.Add(row);
109          // dataTablePerVariable does not contain unchecked variables => reduce insert position by number of uncheckt variables to correct the index
110          int uncheckedUntilVariable = checkedItemList.Content.TakeWhile(x => x.Value != variableName).Count(x => !checkedItemList.Content.ItemChecked(x));
111          dataTablePerVariable.Insert(item.Index - uncheckedUntilVariable, pdt);
112
113          //update selection
114          if (selectedRow != null) {
115            dataTable.SelectedRows.Add(selectedRow);
116            pdt.SelectedRows.Add(selectedRow);
117          }
118        }
119      }
120
121      // update chart if not in all in one mode
122      if (Content != null && !Content.AllInOneMode)
123        GenerateChart();
124    }
125
126    private DataRow GetSelectedDataRow(string variableName) {
127      foreach (DataRow row in selectedDataRows) {
128        if (row.Name == variableName)
129          return row;
130      }
131      return null;
132    }
133    private DataRow GetDataRow(string variableName) {
134      foreach (DataRow row in dataRows) {
135        if (row.Name == variableName)
136          return row;
137      }
138      return null;
139    }
140
141    #region Add/Remove/Update Variable, Reset
142    protected override void AddVariable(string name) {
143      base.AddVariable(name);
144      DataRow row = Content.CreateDataRow(name, chartType);
145      dataTable.Rows.Add(row);
146      PreprocessingDataTable d = new PreprocessingDataTable(name);
147      d.Rows.Add(row);
148      dataTablePerVariable.Add(d);
149
150      if (!Content.AllInOneMode)
151        GenerateChart();
152    }
153
154    // remove variable from data table and item list
155    protected override void RemoveVariable(string name) {
156      base.RemoveVariable(name);
157      dataTable.Rows.Remove(name);
158      dataTablePerVariable.Remove(dataTablePerVariable.Find(x => (x.Name == name)));
159
160      if (!Content.AllInOneMode)
161        GenerateChart();
162    }
163
164    protected override void UpdateVariable(string name) {
165      base.UpdateVariable(name);
166      DataRow newRow = Content.CreateDataRow(name, chartType);
167      dataTable.Rows.Remove(name);
168      dataTable.Rows.Add(newRow);
169      DataTable dt = dataTablePerVariable.Find(x => x.Rows.Find(y => y.Name == name) != null);
170      if (dt != null) {
171        dt.Rows.Remove(name);
172        dt.Rows.Add(newRow);
173      }
174    }
175    protected override void ResetAllVariables() {
176      InitData();
177    }
178    #endregion
179
180    #region Generate Charts
181    protected void GenerateChart() {
182      ClearTableLayout();
183      if (Content.AllInOneMode) {
184        GenerateSingleChartLayout();
185      } else
186        GenerateMultiChartLayout();
187    }
188
189    private void GenerateSingleChartLayout() {
190      tableLayoutPanel.ColumnCount = 1;
191      tableLayoutPanel.RowCount = 1;
192      tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
193      tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
194      tableLayoutPanel.Controls.Add(dataTableView, 0, 0);
195      dataTableView.Content = dataTable;
196    }
197
198    private void GenerateMultiChartLayout() {
199      int checkedItemsCnt = 0;
200      foreach (var item in Content.VariableItemList.CheckedItems)
201        checkedItemsCnt++;
202
203      // set columns and rows based on number of items
204      int columns = GetNrOfMultiChartColumns(checkedItemsCnt);
205      int rows = GetNrOfMultiChartRows(checkedItemsCnt, columns);
206
207      tableLayoutPanel.ColumnCount = columns;
208      tableLayoutPanel.RowCount = rows;
209
210      List<PreprocessingDataTable>.Enumerator enumerator = dataTablePerVariable.GetEnumerator();
211      for (int x = 0; x < columns; x++) {
212
213        if (rows <= MAX_TABLE_AUTO_SIZE_ROWS)
214          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100 / columns));
215        else
216          //scrollbar is shown if there are more than 3 rows -> remove scroll bar width from total width
217          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, (tableLayoutPanel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth) / columns));
218        for (int y = 0; y < rows; y++) {
219          //Add a row only when creating the first column
220          if (x == 0) {
221            // fixed chart size when there are more than 3 tables
222            if (rows > MAX_TABLE_AUTO_SIZE_ROWS)
223              tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, FIXED_CHART_SIZE));
224            else
225              tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100 / rows));
226          }
227
228          enumerator.MoveNext();
229          PreprocessingDataTable d = enumerator.Current;
230          AddDataTableToTableLayout(d, x, y);
231
232        }
233      }
234    }
235    private int GetNrOfMultiChartColumns(int itemCount) {
236      int columns = 0;
237      if (itemCount <= 2)
238        columns = 1;
239      else if (itemCount <= 6)
240        columns = 2;
241      else
242        columns = 3;
243      return columns;
244    }
245    private int GetNrOfMultiChartRows(int itemCount, int columns) {
246      int rows = 0;
247      if (columns == 3)
248        rows = (itemCount + 2) / columns;
249      else if (columns == 2)
250        rows = (itemCount + 1) / columns;
251      else
252        rows = itemCount / columns;
253      return rows;
254    }
255
256    private void AddDataTableToTableLayout(PreprocessingDataTable dataTable, int x, int y) {
257      PreprocessingDataTableView dataView = new PreprocessingDataTableView();
258      dataView.Classification = Classification;
259      dataView.IsDetailedChartViewEnabled = IsDetailedChartViewEnabled;
260
261      if (dataTable == null) {
262        // dummy panel for empty field
263        Panel p = new Panel();
264        p.Dock = DockStyle.Fill;
265        tableLayoutPanel.Controls.Add(p, y, x);
266      } else {
267        dataView.Content = dataTable;
268        dataView.Dock = DockStyle.Fill;
269        tableLayoutPanel.Controls.Add(dataView, y, x);
270      }
271    }
272
273    protected void ClearTableLayout() {
274      //Clear out the existing controls
275      tableLayoutPanel.Controls.Clear();
276
277      //Clear out the existing row and column styles
278      tableLayoutPanel.ColumnStyles.Clear();
279      tableLayoutPanel.RowStyles.Clear();
280      tableLayoutPanel.AutoScroll = false;
281      tableLayoutPanel.AutoScroll = true;
282    }
283    //Remove horizontal scroll bar if visible
284    private void tableLayoutPanel_Layout(object sender, LayoutEventArgs e) {
285      if (tableLayoutPanel.HorizontalScroll.Visible) {
286        // Add padding on the right in order to accomodate the vertical scrollbar
287        int vWidth = SystemInformation.VerticalScrollBarWidth;
288        tableLayoutPanel.Padding = new Padding(0, 0, vWidth, 0);
289      } else {
290        // Reset padding
291        tableLayoutPanel.Padding = new Padding(0);
292      }
293    }
294    #endregion
295
296    #region Update Selection
297    protected override void PreprocessingData_SelctionChanged(object sender, EventArgs e) {
298      base.PreprocessingData_SelctionChanged(sender, e);
299      UpdateSelection();
300    }
301
302    private void UpdateSelection() {
303      //update data table selection
304      selectedDataRows = Content.CreateAllSelectedDataRows(chartType);
305      dataTable.SelectedRows.Clear();
306      foreach (var selectedRow in selectedDataRows) {
307        if (VariableIsChecked(selectedRow.Name))
308          dataTable.SelectedRows.Add(selectedRow);
309      }
310
311      //update data table per variable selection
312      foreach (PreprocessingDataTable d in dataTablePerVariable) {
313        d.SelectedRows.Clear();
314        DataRow row = selectedDataRows.Find(x => x.Name == d.Name);
315        if (row != null)
316          d.SelectedRows.Add(row);
317      }
318    }
319    #endregion
320  }
321}
Note: See TracBrowser for help on using the repository browser.