Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2709

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