Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataPreprocessing Enhancements/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotMultiView.cs @ 14975

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

#2709

  • Improved Check/Uncheck of variables.
    • Instead of removing whole columns/rows from the tablelayout, the tablelayout stays the same with the column/rows width/height set to zero.
    • Hidden charts are not updated to avoid unnessecary calculations.
  • Added a check (messagebox) if >20 variables should be displayed in the multi scatterplot or reduced to 20.
  • Added configuration for point size/opacity and (histogram)aggregation.
File size: 30.4 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.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Analysis;
28using HeuristicLab.Analysis.Views;
29using HeuristicLab.Collections;
30using HeuristicLab.Data;
31using HeuristicLab.MainForm;
32using HeuristicLab.MainForm.WindowsForms;
33using AggregationType = HeuristicLab.Analysis.DataRowVisualProperties.DataRowHistogramAggregation;
34using RegressionType = HeuristicLab.Analysis.ScatterPlotDataRowVisualProperties.ScatterPlotDataRowRegressionType;
35
36namespace HeuristicLab.DataPreprocessing.Views {
37  [View("Scatter Plot Multi View")]
38  [Content(typeof(MultiScatterPlotContent), true)]
39  public partial class ScatterPlotMultiView : PreprocessingCheckedVariablesView {
40    private readonly IDictionary<string, Label> columnHeaderCache = new Dictionary<string, Label>();
41    private readonly IDictionary<string, VerticalLabel> rowHeaderCache = new Dictionary<string, VerticalLabel>();
42    private readonly IDictionary<Tuple<string/*col*/, string/*row*/>, Control> bodyCache = new Dictionary<Tuple<string, string>, Control>();
43
44    public ScatterPlotMultiView() {
45      InitializeComponent();
46
47      oldWidth = (int)widthNumericUpDown.Value;
48      oldHeight = (int)heightNumericUpDown.Value;
49
50      regressionTypeComboBox.DataSource = Enum.GetValues(typeof(RegressionType));
51      regressionTypeComboBox.SelectedItem = RegressionType.None;
52
53      aggregationComboBox.DataSource = Enum.GetValues(typeof(AggregationType));
54      aggregationComboBox.SelectedItem = AggregationType.Overlapping;
55
56      #region Initialize Scrollbars
57      columnHeaderScrollPanel.HorizontalScroll.Enabled = true;
58      columnHeaderScrollPanel.VerticalScroll.Enabled = false;
59      columnHeaderScrollPanel.HorizontalScroll.Visible = false;
60      columnHeaderScrollPanel.VerticalScroll.Visible = false;
61
62      rowHeaderScrollPanel.HorizontalScroll.Enabled = false;
63      rowHeaderScrollPanel.VerticalScroll.Enabled = true;
64      rowHeaderScrollPanel.HorizontalScroll.Visible = false;
65      rowHeaderScrollPanel.VerticalScroll.Visible = false;
66
67      bodyScrollPanel.HorizontalScroll.Enabled = true;
68      bodyScrollPanel.VerticalScroll.Enabled = true;
69      bodyScrollPanel.HorizontalScroll.Visible = true;
70      bodyScrollPanel.VerticalScroll.Visible = true;
71      bodyScrollPanel.AutoScroll = true;
72      #endregion
73
74      bodyScrollPanel.MouseWheel += bodyScrollPanel_MouseWheel;
75    }
76
77    public new MultiScatterPlotContent Content {
78      get { return (MultiScatterPlotContent)base.Content; }
79      set { base.Content = value; }
80    }
81
82    protected override void OnContentChanged() {
83      base.OnContentChanged();
84      if (Content != null) {
85        groupingComboBox.Items.Add("");
86        foreach (string var in PreprocessingChartContent.GetVariableNamesForGrouping(Content.PreprocessingData)) {
87          groupingComboBox.Items.Add(var);
88        }
89        groupingComboBox.SelectedItem = Content.GroupingVariable;
90
91        // uncheck variables that max 20 vars are selected initially
92        var list = Content.VariableItemList;
93        int numChecked = list.CheckedItems.Count();
94        if (numChecked > 20) {
95          string message = string.Format("Displaying {0} variables ({1} charts) can cause HeuristicLab to become instable. " +
96                                         "Should the number of initially checked variables be reduced to 20?",
97            numChecked, numChecked * numChecked);
98          if (MessageBox.Show(this, message, "Reduce befor continue?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) {
99            suppressCheckedChangedUpdate = true;
100            foreach (var var in list.CheckedItems.Reverse().Take(numChecked - 20)) {
101              Content.VariableItemList.SetItemCheckedState(var.Value, false);
102            }
103            suppressCheckedChangedUpdate = false;
104          }
105        }
106        GenerateCharts(true);
107      }
108    }
109
110    protected override void SetEnabledStateOfControls() {
111      base.SetEnabledStateOfControls();
112      var regressionType = (RegressionType)regressionTypeComboBox.SelectedValue;
113      polynomialRegressionOrderNumericUpDown.Enabled = regressionType == RegressionType.Polynomial;
114      sizeGroupBox.Enabled = Content != null;
115      pointsGroupBox.Enabled = Content != null;
116      groupingComboBox.Enabled = Content != null;
117      regressionGroupBox.Enabled = Content != null;
118    }
119
120    protected override void CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> checkedItems) {
121      base.CheckedItemsChanged(sender, checkedItems);
122      if (suppressCheckedChangedUpdate) return;
123
124      foreach (var variable in checkedItems.Items) {
125        if (Content.VariableItemList.ItemChecked(variable.Value))
126          ShowChartOnTable(variable.Value.Value, variable.Index);
127        else
128          HideChartFromTable(variable.Value.Value, variable.Index);
129      }
130    }
131
132    #region Show and Hide charts
133    private void ShowChartOnTable(string variable, int idx) {
134      frameTableLayoutPanel.SuspendLayout();
135
136      // show column header
137      var colH = columnHeaderTableLayoutPanel;
138      colH.ColumnStyles[idx].Width = GetColumnWidth();
139      if (colH.GetControlFromPosition(idx, 0) == null)
140        colH.Controls.Add(GetColumnHeader(variable), idx, 0);
141      else
142        colH.GetControlFromPosition(idx, 0).Visible = true;
143
144      // show row header
145      var rowH = rowHeaderTableLayoutPanel;
146      rowH.RowStyles[idx].Height = GetRowHeight();
147      if (rowH.GetControlFromPosition(0, idx) == null)
148        rowH.Controls.Add(GetRowHeader(variable), 0, idx);
149      else
150        rowH.GetControlFromPosition(0, idx).Visible = true;
151
152      // show body
153      var body = bodyTableLayoutPanel;
154      ShowColumnHelper(body, idx, r => GetBody(variable, Content.VariableItemList[r].Value));
155      ShowRowHelper(body, idx, c => GetBody(Content.VariableItemList[c].Value, variable));
156
157      frameTableLayoutPanel.ResumeLayout(true);
158    }
159    private void ShowColumnHelper(TableLayoutPanel tlp, int idx, Func<int, Control> creatorFunc) {
160      tlp.ColumnStyles[idx].Width = GetColumnWidth();
161      for (int r = 0; r < tlp.RowCount; r++) {
162        if (Content.VariableItemList.ItemChecked(Content.VariableItemList[r])) {
163          var control = tlp.GetControlFromPosition(idx, r);
164          if (control == null)
165            tlp.Controls.Add(creatorFunc(r), idx, r);
166          else
167            control.Visible = true;
168        }
169      }
170    }
171    private void ShowRowHelper(TableLayoutPanel tlp, int idx, Func<int, Control> creatorFunc) {
172      tlp.RowStyles[idx].Height = GetRowHeight();
173      for (int c = 0; c < tlp.ColumnCount; c++) {
174        if (Content.VariableItemList.ItemChecked(Content.VariableItemList[c])) {
175          var control = tlp.GetControlFromPosition(c, idx);
176          if (control == null)
177            tlp.Controls.Add(creatorFunc(c), c, idx);
178          else
179            tlp.GetControlFromPosition(c, idx).Visible = true;
180        }
181      }
182    }
183
184    private void HideChartFromTable(string variable, int idx) {
185      frameTableLayoutPanel.SuspendLayout();
186
187      // hide column header
188      var colH = columnHeaderTableLayoutPanel;
189      HideColumnHelper(colH, idx);
190
191      // hide row header
192      var rowH = rowHeaderTableLayoutPanel;
193      HideRowHelper(rowH, idx);
194
195      // hide from body
196      var body = bodyTableLayoutPanel;
197      HideColumnHelper(body, idx);
198      HideRowHelper(body, idx);
199
200      frameTableLayoutPanel.ResumeLayout(true);
201    }
202    private void HideColumnHelper(TableLayoutPanel tlp, int idx) {
203      tlp.ColumnStyles[idx].Width = 0;
204      // hide controls
205      for (int r = 0; r < tlp.RowCount; r++) {
206        //tlp.Controls.Remove(tlp.GetControlFromPosition(idx, r));
207        var control = tlp.GetControlFromPosition(idx, r);
208        if (control != null)
209          control.Visible = false;
210      }
211    }
212    private void HideRowHelper(TableLayoutPanel tlp, int idx) {
213      tlp.RowStyles[idx].Height = 0;
214      // hide controls
215      for (int c = 0; c < tlp.ColumnCount; c++) {
216        //tlp.Controls.Remove(tlp.GetControlFromPosition(c, idx));
217        var control = tlp.GetControlFromPosition(c, idx);
218        if (control != null)
219          control.Visible = false;
220      }
221    }
222    #endregion
223
224    #region Add/Remove/Update Variable
225    protected override void AddVariable(string name) {
226      base.AddVariable(name);
227      if (IsVariableChecked(name))
228        AddChartToTable(name);
229    }
230    protected override void RemoveVariable(string name) {
231      base.RemoveVariable(name);
232
233      if (IsVariableChecked(name)) {
234        RemoveChartFromTable(name);
235      }
236
237      // clear caches
238      columnHeaderCache[name].Dispose();
239      columnHeaderCache.Remove(name);
240      rowHeaderCache[name].Dispose();
241      rowHeaderCache.Remove(name);
242      var keys = bodyCache.Keys.Where(t => t.Item1 == name || t.Item2 == name).ToList();
243      foreach (var key in keys) {
244        bodyCache[key].Dispose();
245        bodyCache.Remove(key);
246      }
247    }
248    protected override void UpdateVariable(string name) {
249      base.UpdateVariable(name);
250      RemoveVariable(name);
251      AddVariable(name);
252    }
253    protected override void ResetAllVariables() {
254      GenerateCharts(true);
255    }
256
257    private void AddChartToTable(string variable) {
258      frameTableLayoutPanel.SuspendLayout();
259
260      // find index to insert
261      var variables = Content.VariableItemList.Select(v => v.Value).ToList();
262      int idx = variables              // all variables
263        .TakeWhile(t => t != variable) // ... until the variable that was checked
264        .Count(IsVariableChecked);     // ... how many checked variables
265
266      // add column header
267      var colH = columnHeaderTableLayoutPanel;
268      AddColumnHelper(colH, idx, _ => GetColumnHeader(variable));
269
270      // add row header
271      var rowH = rowHeaderTableLayoutPanel;
272      AddRowHelper(rowH, idx, _ => GetRowHeader(variable));
273
274      // add body
275      var body = bodyTableLayoutPanel;
276      var vars = GetCheckedVariables();
277      var varsMinus = vars.Except(new[] { variable }).ToList();
278      AddColumnHelper(body, idx, r => GetBody(variable, varsMinus[r])); // exclude "variable" because the row for it does not exist yet
279      AddRowHelper(body, idx, c => GetBody(vars[c], variable));
280
281      frameTableLayoutPanel.ResumeLayout(true);
282    }
283    private void AddColumnHelper(TableLayoutPanel tlp, int idx, Func<int, Control> creatorFunc) {
284      // add column
285      tlp.ColumnCount++;
286      tlp.ColumnStyles.Insert(idx, new ColumnStyle(SizeType.Absolute, GetColumnWidth()));
287      // shift right
288      for (int c = tlp.ColumnCount; c > idx - 1; c--) {
289        for (int r = 0; r < tlp.RowCount; r++) {
290          var control = tlp.GetControlFromPosition(c, r);
291          if (control != null) {
292            tlp.SetColumn(control, c + 1);
293          }
294        }
295      }
296      // add controls
297      for (int r = 0; r < tlp.RowCount; r++) {
298        if (tlp.GetControlFromPosition(idx, r) == null)
299          tlp.Controls.Add(creatorFunc(r), idx, r);
300      }
301
302    }
303    private void AddRowHelper(TableLayoutPanel tlp, int idx, Func<int, Control> creatorFunc) {
304      // add row
305      tlp.RowCount++;
306      tlp.RowStyles.Insert(idx, new RowStyle(SizeType.Absolute, GetRowHeight()));
307      // shift right
308      for (int r = tlp.RowCount; r > idx - 1; r--) {
309        for (int c = 0; c < tlp.ColumnCount; c++) {
310          var control = tlp.GetControlFromPosition(c, r);
311          if (control != null) {
312            tlp.SetRow(control, r + 1);
313          }
314        }
315      }
316      // add controls
317      for (int c = 0; c < tlp.ColumnCount; c++)
318        if (tlp.GetControlFromPosition(c, idx) == null)
319          tlp.Controls.Add(creatorFunc(c), c, idx);
320    }
321
322    private void RemoveChartFromTable(string variable) {
323      frameTableLayoutPanel.SuspendLayout();
324
325      // remove column header
326      var colH = columnHeaderTableLayoutPanel;
327      int colIdx = colH.GetColumn(colH.Controls[variable]);
328      RemoveColumnHelper(colH, colIdx);
329
330      // remove row header
331      var rowH = rowHeaderTableLayoutPanel;
332      int rowIdx = rowH.GetRow(rowH.Controls[variable]);
333      RemoveRowHelper(rowH, rowIdx);
334
335      // remove from body
336      var body = bodyTableLayoutPanel;
337      RemoveColumnHelper(body, colIdx);
338      RemoveRowHelper(body, rowIdx);
339
340      frameTableLayoutPanel.ResumeLayout(true);
341    }
342    private void RemoveColumnHelper(TableLayoutPanel tlp, int idx) {
343      // remove controls
344      for (int r = 0; r < tlp.RowCount; r++)
345        tlp.Controls.Remove(tlp.GetControlFromPosition(idx, r));
346      // shift left
347      for (int c = idx + 1; c < tlp.ColumnCount; c++) {
348        for (int r = 0; r < tlp.RowCount; r++) {
349          var control = tlp.GetControlFromPosition(c, r);
350          if (control != null) {
351            tlp.SetColumn(control, c - 1);
352          }
353        }
354      }
355      // delete column
356      tlp.ColumnStyles.RemoveAt(tlp.ColumnCount - 1);
357      tlp.ColumnCount--;
358    }
359    private void RemoveRowHelper(TableLayoutPanel tlp, int idx) {
360      // remove controls
361      for (int c = 0; c < tlp.ColumnCount; c++)
362        tlp.Controls.Remove(tlp.GetControlFromPosition(c, idx));
363      // shift left
364      for (int r = idx + 1; r < tlp.RowCount; r++) {
365        for (int c = 0; c < tlp.ColumnCount; c++) {
366          var control = tlp.GetControlFromPosition(c, r);
367          if (control != null) {
368            tlp.SetRow(control, r - 1);
369          }
370        }
371      }
372      // delete rows
373      tlp.RowStyles.RemoveAt(tlp.RowCount - 1);
374      tlp.RowCount--;
375    }
376    #endregion
377
378    #region Creating Headers and Body
379    private Label GetColumnHeader(string variable) {
380      if (!columnHeaderCache.ContainsKey(variable)) {
381        columnHeaderCache.Add(variable, new Label() {
382          Text = variable,
383          TextAlign = ContentAlignment.MiddleCenter,
384          Name = variable,
385          Height = columnHeaderTableLayoutPanel.Height,
386          Dock = DockStyle.Fill,
387          Margin = new Padding(3)
388        });
389      }
390      return columnHeaderCache[variable];
391    }
392    private Label GetRowHeader(string variable) {
393      if (!rowHeaderCache.ContainsKey(variable)) {
394        rowHeaderCache.Add(variable, new VerticalLabel() {
395          Text = variable,
396          TextAlign = ContentAlignment.MiddleCenter,
397          Name = variable,
398          Width = rowHeaderTableLayoutPanel.Width,
399          Height = columnHeaderScrollPanel.Width,
400          Dock = DockStyle.Fill,
401          Margin = new Padding(3)
402        });
403      }
404      return rowHeaderCache[variable];
405    }
406    private Control GetBody(string colVariable, string rowVariable) {
407      var key = Tuple.Create(colVariable, rowVariable);
408      if (!bodyCache.ContainsKey(key)) {
409        if (rowVariable == colVariable) { // use historgram if x and y variable are equal
410          var dataTable = HistogramContent.CreateHistogram(
411            Content.PreprocessingData,
412            rowVariable,
413            (string)groupingComboBox.SelectedItem,
414            (AggregationType)aggregationComboBox.SelectedItem);
415          dataTable.VisualProperties.Title = string.Empty;
416          foreach (var dataRow in dataTable.Rows)
417            dataRow.VisualProperties.IsVisibleInLegend = groupingComboBox.SelectedIndex > 0;
418          var pcv = new DataTableControl {
419            Name = key.ToString(),
420            Content = dataTable,
421            Dock = DockStyle.Fill,
422            //ShowLegend = false,
423            //XAxisFormat = "G3"
424          };
425          //pcv.ChartDoubleClick += HistogramDoubleClick;
426          bodyCache.Add(key, pcv);
427        } else { //scatter plot
428          var scatterPlot = ScatterPlotContent.CreateScatterPlot(Content.PreprocessingData,
429            colVariable,
430            rowVariable,
431            (string)groupingComboBox.SelectedItem);
432          var regressionType = (RegressionType)regressionTypeComboBox.SelectedValue;
433          int order = (int)polynomialRegressionOrderNumericUpDown.Value;
434          int i = 0;
435          var colors = PreprocessingChartView.Colors;
436          foreach (var row in scatterPlot.Rows) {
437            row.VisualProperties.PointSize = (int)pointSizeNumericUpDown.Value;
438            row.VisualProperties.Color = Color.FromArgb((int)(pointOpacityNumericUpDown.Value * 255),
439              row.VisualProperties.Color.IsEmpty ? colors[i++ % colors.Length] : row.VisualProperties.Color);
440            //row.VisualProperties.IsVisibleInLegend = true;
441            row.VisualProperties.IsRegressionVisibleInLegend = false;
442            row.VisualProperties.RegressionType = regressionType;
443            row.VisualProperties.PolynomialRegressionOrder = order;
444          }
445          scatterPlot.VisualProperties.Title = string.Empty;
446          var scatterPlotControl = new ScatterPlotControl {
447            Name = key.ToString(),
448            Content = scatterPlot,
449            Dock = DockStyle.Fill,
450            //ShowLegend = false,
451            //XAxisFormat = "G3"
452          };
453          //scatterPlotControl.DoubleClick += ScatterPlotDoubleClick; // ToDo: not working; double click is already handled by the chart
454          bodyCache.Add(key, scatterPlotControl);
455        }
456      }
457      return bodyCache[key];
458    }
459    #endregion
460
461    protected override void CheckedChangedUpdate() {
462      GenerateCharts(false); // only checked-changes -> reuse cached values
463    }
464
465    #region Generate Charts
466    private void GenerateCharts(bool clearCache) {
467      if (suppressCheckedChangedUpdate) return;
468
469      // Clear old layouts and cache
470      foreach (var tableLayoutPanel in new[] { columnHeaderTableLayoutPanel, rowHeaderTableLayoutPanel, bodyTableLayoutPanel }) {
471        tableLayoutPanel.Controls.Clear();
472        tableLayoutPanel.ColumnStyles.Clear();
473        tableLayoutPanel.RowStyles.Clear();
474      }
475
476      if (clearCache) {
477        foreach (var control in bodyCache.Values
478          .Concat(columnHeaderCache.Values)
479          .Concat(rowHeaderCache.Values)) {
480          control.Dispose();
481        }
482        columnHeaderCache.Clear();
483        rowHeaderCache.Clear();
484        bodyCache.Clear();
485      }
486
487      var variables = Content.VariableItemList.Select(x => x.Value).ToList();
488
489      // Set row and column count
490      columnHeaderTableLayoutPanel.ColumnCount = variables.Count;
491      rowHeaderTableLayoutPanel.RowCount = variables.Count;
492      bodyTableLayoutPanel.ColumnCount = variables.Count;
493      bodyTableLayoutPanel.RowCount = variables.Count;
494
495      // Set column and row layout
496      for (int i = 0; i < variables.Count; i++) {
497        bool @checked = Content.VariableItemList.ItemChecked(Content.VariableItemList[i]);
498        columnHeaderTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, @checked ? GetColumnWidth() : 0));
499        rowHeaderTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, @checked ? GetRowHeight() : 0));
500        bodyTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, @checked ? GetColumnWidth() : 0));
501        bodyTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, @checked ? GetRowHeight() : 0));
502      }
503
504      frameTableLayoutPanel.SuspendLayout();
505      AddHeaderToTableLayoutPanels();
506      AddChartsToTableLayoutPanel();
507      UpdateHeaderMargin();
508      frameTableLayoutPanel.ResumeLayout(true);
509    }
510
511    private void AddHeaderToTableLayoutPanels() {
512      for (int i = 0; i < Content.VariableItemList.Count; i++) {
513        var variable = Content.VariableItemList[i];
514        if (Content.VariableItemList.ItemChecked(variable)) {
515          columnHeaderTableLayoutPanel.Controls.Add(GetColumnHeader(variable.Value), i, 0);
516          rowHeaderTableLayoutPanel.Controls.Add(GetRowHeader(variable.Value), 0, i);
517        }
518      }
519    }
520    private void AddChartsToTableLayoutPanel() {
521      for (int c = 0; c < Content.VariableItemList.Count; c++) {
522        var colVar = Content.VariableItemList[c].Value;
523        if (!IsVariableChecked(colVar)) continue;
524        for (int r = 0; r < Content.VariableItemList.Count; r++) {
525          var rowVar = Content.VariableItemList[r].Value;
526          if (!IsVariableChecked(rowVar)) continue;
527          bodyTableLayoutPanel.Controls.Add(GetBody(colVar, rowVar), c, r);
528        }
529      }
530      UpdateRegressionLine();
531    }
532
533    #endregion
534
535    #region DoubleClick Events
536    //Open scatter plot in new tab with new content when double clicked
537    private void ScatterPlotDoubleClick(object sender, EventArgs e) {
538      var scatterPlotControl = (ScatterPlotControl)sender;
539      var scatterContent = new SingleScatterPlotContent(Content.PreprocessingData);
540      ScatterPlot scatterPlot = scatterPlotControl.Content;
541
542      //Extract variable names from scatter plot and set them in content
543      if (scatterPlot.Rows.Count == 1) {
544        string[] variables = scatterPlot.Rows.ElementAt(0).Name.Split(new string[] { " - " }, StringSplitOptions.None); // extract variable names from string
545        scatterContent.SelectedXVariable = variables[0];
546        scatterContent.SelectedYVariable = variables[1];
547      }
548
549      MainFormManager.MainForm.ShowContent(scatterContent, typeof(ScatterPlotSingleView));  // open in new tab
550    }
551
552    //open histogram in new tab with new content when double clicked
553    private void HistogramDoubleClick(object sender, EventArgs e) {
554      DataTableControl pcv = (DataTableControl)sender;
555      HistogramContent histoContent = new HistogramContent(Content.PreprocessingData);  // create new content     
556                                                                                        //ToDo: histoContent.VariableItemList = Content.CreateVariableItemList();
557      var dataTable = pcv.Content;
558
559      //Set variable item list from with variable from data table
560      if (dataTable.Rows.Count == 1) { // only one data row should be in data table
561        string variableName = dataTable.Rows.ElementAt(0).Name;
562
563        // set only variable name checked
564        foreach (var checkedItem in histoContent.VariableItemList) {
565          histoContent.VariableItemList.SetItemCheckedState(checkedItem, checkedItem.Value == variableName);
566        }
567      }
568      MainFormManager.MainForm.ShowContent(histoContent, typeof(HistogramView));  // open in new tab
569    }
570    #endregion
571
572    #region Scrolling
573    private void bodyScrollPanel_Scroll(object sender, ScrollEventArgs e) {
574      SyncScroll();
575
576      UpdateHeaderMargin();
577    }
578    private void bodyScrollPanel_MouseWheel(object sender, MouseEventArgs e) {
579      // Scrolling with the mouse wheel is not captured in the Scoll event
580      SyncScroll();
581    }
582    private void SyncScroll() {
583      frameTableLayoutPanel.SuspendRepaint();
584
585      columnHeaderScrollPanel.HorizontalScroll.Minimum = bodyScrollPanel.HorizontalScroll.Minimum;
586      columnHeaderScrollPanel.HorizontalScroll.Maximum = bodyScrollPanel.HorizontalScroll.Maximum;
587      rowHeaderScrollPanel.VerticalScroll.Minimum = bodyScrollPanel.VerticalScroll.Minimum;
588      rowHeaderScrollPanel.VerticalScroll.Maximum = bodyScrollPanel.VerticalScroll.Maximum;
589
590      columnHeaderScrollPanel.HorizontalScroll.Value = Math.Max(bodyScrollPanel.HorizontalScroll.Value, 1);
591      rowHeaderScrollPanel.VerticalScroll.Value = Math.Max(bodyScrollPanel.VerticalScroll.Value, 1);
592      // minimum 1 is nececary  because of two factors:
593      // - setting the Value-property of Horizontal/VerticalScroll updates the internal state but the Value-property stays 0
594      // - setting the same number of the Value-property has no effect
595      // since the Value-property is always 0, setting it to 0 would have no effect; so it is set to 1 instead
596
597      frameTableLayoutPanel.ResumeRepaint(true);
598    }
599    // add a margin to the header table layouts if the scollbar is visible to account for the width/height of the scrollbar
600    private void UpdateHeaderMargin() {
601      columnHeaderScrollPanel.Margin = new Padding(0, 0, bodyScrollPanel.VerticalScroll.Visible ? SystemInformation.VerticalScrollBarWidth : 0, 0);
602      rowHeaderScrollPanel.Margin = new Padding(0, 0, 0, bodyScrollPanel.HorizontalScroll.Visible ? SystemInformation.HorizontalScrollBarHeight : 0);
603    }
604    #endregion
605
606    #region Sizing of Charts
607    private int oldWidth;
608    private int oldHeight;
609    private float AspectRatio {
610      get {
611        if (oldWidth == 0 || oldHeight == 0) return 1;
612        return (float)oldWidth / oldHeight;
613      }
614    }
615    private bool lockChange = false;
616
617    private int GetColumnWidth() { return (int)widthNumericUpDown.Value; }
618    private int GetRowHeight() { return (int)heightNumericUpDown.Value; }
619
620    private void widthNumericUpDown_ValueChanged(object sender, EventArgs e) {
621      frameTableLayoutPanel.SuspendRepaint();
622      if (lockAspectCheckBox.Checked && !lockChange) {
623        lockChange = true;
624        heightNumericUpDown.Value = (int)((double)widthNumericUpDown.Value / AspectRatio);
625        lockChange = false;
626      }
627      for (int i = 0; i < columnHeaderTableLayoutPanel.ColumnCount; i++) {
628        if (Content.VariableItemList.ItemChecked(Content.VariableItemList[i])) {
629          columnHeaderTableLayoutPanel.ColumnStyles[i].Width = GetColumnWidth();
630          bodyTableLayoutPanel.ColumnStyles[i].Width = GetColumnWidth();
631        }
632      }
633      oldWidth = GetColumnWidth();
634      oldHeight = GetRowHeight();
635      frameTableLayoutPanel.ResumeRepaint(true);
636    }
637    private void heightNumericUpDown_ValueChanged(object sender, EventArgs e) {
638      frameTableLayoutPanel.SuspendRepaint();
639      if (lockAspectCheckBox.Checked && !lockChange) {
640        lockChange = true;
641        widthNumericUpDown.Value = (int)((double)heightNumericUpDown.Value * AspectRatio);
642        lockChange = false;
643      }
644      for (int i = 0; i < rowHeaderTableLayoutPanel.RowCount; i++) {
645        if (Content.VariableItemList.ItemChecked(Content.VariableItemList[i])) {
646          rowHeaderTableLayoutPanel.RowStyles[i].Height = GetRowHeight();
647          bodyTableLayoutPanel.RowStyles[i].Height = GetRowHeight();
648        }
649      }
650      oldWidth = GetColumnWidth();
651      oldHeight = GetRowHeight();
652      frameTableLayoutPanel.ResumeRepaint(true);
653    }
654    private void pointSizeNumericUpDown_ValueChanged(object sender, EventArgs e) {
655      int pointSize = (int)pointSizeNumericUpDown.Value;
656      foreach (var control in bodyCache.ToList()) {
657        var scatterPlotControl = control.Value as ScatterPlotControl;
658        if (scatterPlotControl != null) {
659          foreach (var row in scatterPlotControl.Content.Rows) {
660            row.VisualProperties.PointSize = pointSize;
661          }
662        }
663      }
664    }
665    private void pointOpacityNumericUpDown_ValueChanged(object sender, EventArgs e) {
666      float opacity = (float)pointOpacityNumericUpDown.Value;
667      foreach (var control in bodyCache.ToList()) {
668        var scatterPlotControl = control.Value as ScatterPlotControl;
669        if (scatterPlotControl != null) {
670          foreach (var row in scatterPlotControl.Content.Rows) {
671            var color = row.VisualProperties.Color;
672            if (color.IsEmpty)
673              color = PreprocessingChartView.Colors.First();
674            row.VisualProperties.Color = Color.FromArgb((int)(opacity * 255), color);
675          }
676        }
677      }
678    }
679    #endregion
680
681    #region Regression Line
682    private void regressionTypeComboBox_SelectedValueChanged(object sender, EventArgs e) {
683      var regressionType = (RegressionType)regressionTypeComboBox.SelectedValue;
684      polynomialRegressionOrderNumericUpDown.Enabled = regressionType == RegressionType.Polynomial;
685      UpdateRegressionLine();
686    }
687
688    private void polynomialRegressionOrderNumericUpDown_ValueChanged(object sender, EventArgs e) {
689      UpdateRegressionLine();
690    }
691
692    private void UpdateRegressionLine() {
693      var regressionType = (RegressionType)regressionTypeComboBox.SelectedValue;
694      int order = (int)polynomialRegressionOrderNumericUpDown.Value;
695
696      foreach (var control in bodyCache.ToList()) {
697        // hidden chart => reset cache
698        if (!bodyTableLayoutPanel.Controls.Contains(control.Value)) {
699          bodyCache.Remove(control.Key);
700        }
701
702        var scatterPlotControl = control.Value as ScatterPlotControl;
703        if (scatterPlotControl != null) {
704          foreach (var row in scatterPlotControl.Content.Rows) {
705            row.VisualProperties.IsRegressionVisibleInLegend = false;
706            row.VisualProperties.RegressionType = regressionType;
707            row.VisualProperties.PolynomialRegressionOrder = order;
708          }
709        }
710      }
711    }
712    #endregion
713
714    #region Grouping
715    private void groupingComboBox_SelectedIndexChanged(object sender, EventArgs e) {
716      aggregationComboBox.Enabled = groupingComboBox.SelectedIndex > 0;
717      GenerateCharts(true); // new series within charts -> clear cache
718    }
719
720    private void aggregationComboBox_SelectedIndexChanged(object sender, EventArgs e) {
721      var aggregation = (AggregationType)aggregationComboBox.SelectedValue;
722      foreach (var control in bodyCache.ToList()) {
723        // hidden chart => reset cache
724        if (!bodyTableLayoutPanel.Controls.Contains(control.Value)) {
725          bodyCache.Remove(control.Key);
726        }
727
728        var histogramControl = control.Value as DataTableControl;
729        if (histogramControl != null) {
730          foreach (var row in histogramControl.Content.Rows) {
731            row.VisualProperties.Aggregation = aggregation;
732          }
733        }
734      }
735    }
736    #endregion
737  }
738}
739
Note: See TracBrowser for help on using the repository browser.