source: branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionGradientView.cs @ 14014

Last change on this file since 14014 was 14014, checked in by bburlacu, 6 years ago

#2597: Fixed small issue with layout update when the number of columns was changed. Improved layout of the configuration panel. Made GradientView invisible as an item in the Solution View.

File size: 8.3 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.Collections;
27using HeuristicLab.Core.Views;
28using HeuristicLab.MainForm;
29using HeuristicLab.MainForm.WindowsForms;
30using HeuristicLab.Problems.DataAnalysis;
31using HeuristicLab.Visualization.ChartControlsExtensions;
32
33namespace HeuristicLab.Algorithms.DataAnalysis.Views {
34  [View("Gradient View")]
35  [Content(typeof(IRegressionSolution))]
36  public partial class RegressionSolutionGradientView : ItemView {
37    private const int DrawingSteps = 1000;
38
39    private readonly List<string> variableNames;
40    private readonly ObservableList<DensityTrackbar> trackbars;
41    private ModifiableDataset sharedFixedVariables;
42
43    private int ActiveDimension {
44      get { return trackbars.FindIndex(tb => tb.Checked); }
45    }
46
47    public new IRegressionSolution Content {
48      get { return (IRegressionSolution)base.Content; }
49      set { base.Content = value; }
50    }
51
52    public RegressionSolutionGradientView()
53      : base() {
54      variableNames = new List<string>();
55
56      trackbars = new ObservableList<DensityTrackbar>();
57      trackbars.ItemsAdded += (sender, args) => {
58        args.Items.Select(i => i.Value).ForEach(RegisterEvents);
59      };
60      trackbars.ItemsRemoved += (sender, args) => {
61        args.Items.Select(i => i.Value).ForEach(DeregisterEvents);
62      };
63      trackbars.CollectionReset += (sender, args) => {
64        args.OldItems.Select(i => i.Value).ForEach(DeregisterEvents);
65        args.Items.Select(i => i.Value).ForEach(RegisterEvents);
66      };
67
68      InitializeComponent();
69
70      // Avoid additional horizontal scrollbar
71      var vertScrollWidth = SystemInformation.VerticalScrollBarWidth;
72      tableLayoutPanel.Padding = new Padding(0, 0, vertScrollWidth, 0);
73    }
74
75    private async void UpdateConfigurationControls() {
76      variableNames.Clear();
77      trackbars.Clear();
78
79      tableLayoutPanel.SuspendRepaint();
80      tableLayoutPanel.SuspendLayout();
81
82      tableLayoutPanel.RowCount = 0;
83      tableLayoutPanel.Controls.Clear();
84
85      if (Content == null) {
86        tableLayoutPanel.ResumeLayout(false);
87        tableLayoutPanel.ResumeRepaint(false);
88        return;
89      }
90
91      variableNames.AddRange(Content.ProblemData.AllowedInputVariables);
92
93      var newTrackbars = CreateConfiguration();
94
95      sharedFixedVariables = new ModifiableDataset(variableNames, newTrackbars.Select(tb => new List<double>(1) { (double)tb.Value }));
96      gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableNames.First(), DrawingSteps);
97      await gradientChart.RecalculateAsync();
98
99      // Add to table and observable lists
100      tableLayoutPanel.RowCount = variableNames.Count;
101      while (tableLayoutPanel.RowStyles.Count < variableNames.Count)
102        tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
103      for (int i = 0; i < newTrackbars.Count; i++) {
104        // events registered automatically
105        trackbars.Add(newTrackbars[i]);
106        tableLayoutPanel.Controls.Add(newTrackbars[i], 0, i);
107      }
108
109      tableLayoutPanel.ResumeLayout(true);
110      tableLayoutPanel.ResumeRepaint(true);
111
112      // Init Y-axis range
113      var problemData = Content.ProblemData;
114      double min = double.MaxValue, max = double.MinValue;
115      var trainingTarget = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices);
116      foreach (var t in trainingTarget) {
117        if (t < min) min = t;
118        if (t > max) max = t;
119      }
120      double range = max - min;
121      const double scale = 1.0 / 3.0;
122      double axisMin, axisMax, axisInterval;
123      ChartUtil.CalculateAxisInterval(min - scale * range, max + scale * range, 5, out axisMin, out axisMax, out axisInterval);
124      gradientChart.FixedYAxisMin = axisMin;
125      gradientChart.FixedYAxisMax = axisMax;
126
127      trackbars.First().Checked = true;
128    }
129
130    private IList<DensityTrackbar> CreateConfiguration() {
131      var ranges = new List<DoubleLimit>();
132      foreach (string variableName in variableNames) {
133        var values = Content.ProblemData.Dataset.GetDoubleValues(variableName, Content.ProblemData.AllIndices);
134        double min, max, interval;
135        ChartUtil.CalculateAxisInterval(values.Min(), values.Max(), 10, out min, out max, out interval);
136        ranges.Add(new DoubleLimit(min, max));
137      }
138
139      var newTrackbars = new List<DensityTrackbar>();
140      for (int i = 0; i < variableNames.Count; i++) {
141        var name = variableNames[i];
142        var trainingData = Content.ProblemData.Dataset.GetDoubleValues(name, Content.ProblemData.TrainingIndices).ToList();
143
144        var dimensionTrackbar = new DensityTrackbar(name, ranges[i], trainingData) {
145          Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
146        };
147        newTrackbars.Add(dimensionTrackbar);
148      }
149
150      return newTrackbars;
151    }
152
153    private void RegisterEvents(DensityTrackbar trackbar) {
154      trackbar.CheckedChanged += trackbar_CheckedChanged;
155      trackbar.ValueChanged += trackbar_ValueChanged;
156      trackbar.LimitsChanged += trackbar_LimitsChanged;
157    }
158    private void DeregisterEvents(DensityTrackbar trackbar) {
159      trackbar.CheckedChanged -= trackbar_CheckedChanged;
160      trackbar.ValueChanged -= trackbar_ValueChanged;
161      trackbar.LimitsChanged -= trackbar_LimitsChanged;
162    }
163
164    private void trackbar_CheckedChanged(object sender, EventArgs e) {
165      var trackBar = sender as DensityTrackbar;
166      if (trackBar == null || !trackBar.Checked) return;
167      // Uncheck all others
168      foreach (var tb in trackbars.Except(new[] { trackBar }))
169        tb.Checked = false;
170      gradientChart.FreeVariable = variableNames[trackbars.IndexOf(trackBar)];
171      gradientChart.RecalculateAsync();
172    }
173
174    private void trackbar_LimitsChanged(object sender, EventArgs e) {
175      var trackBar = sender as DensityTrackbar;
176      if (trackBar == null || !trackBar.Checked) return;
177      gradientChart.FixedXAxisMin = trackBar.Limits.Lower;
178      gradientChart.FixedXAxisMax = trackBar.Limits.Upper;
179      gradientChart.RecalculateAsync();
180    }
181
182    private void trackbar_ValueChanged(object sender, EventArgs e) {
183      var trackBar = sender as DensityTrackbar;
184      if (trackBar == null) return;
185      sharedFixedVariables.SetVariableValue((double)trackBar.Value, variableNames[trackbars.IndexOf(trackBar)], 0);
186      gradientChart.RecalculateAsync();
187    }
188
189    #region Events
190    protected override void RegisterContentEvents() {
191      base.RegisterContentEvents();
192      Content.ModelChanged += Content_ModelChanged;
193      Content.ProblemDataChanged += Content_ProblemDataChanged;
194    }
195
196    protected override void DeregisterContentEvents() {
197      base.DeregisterContentEvents();
198      Content.ModelChanged -= Content_ModelChanged;
199      Content.ProblemDataChanged -= Content_ProblemDataChanged;
200    }
201
202    protected override void OnContentChanged() {
203      base.OnContentChanged();
204      UpdateConfigurationControls();
205    }
206
207    private void Content_ModelChanged(object sender, EventArgs e) {
208      UpdateConfigurationControls();
209    }
210
211    private void Content_ProblemDataChanged(object sender, EventArgs e) {
212      UpdateConfigurationControls();
213    }
214    #endregion
215  }
216
217  internal static class Extensions {
218    public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
219      foreach (T item in source)
220        action(item);
221    }
222  }
223}
Note: See TracBrowser for help on using the repository browser.