Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionSolutionTargetResponseGradientView.cs @ 13843

Last change on this file since 13843 was 13843, checked in by pfleck, 8 years ago

#2597 Implemented "sync" y-axis for Target Response Gradient View.

File size: 6.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.Threading.Tasks;
26using System.Windows.Forms;
27using HeuristicLab.Common;
28using HeuristicLab.MainForm;
29using HeuristicLab.Visualization.ChartControlsExtensions;
30
31namespace HeuristicLab.Problems.DataAnalysis.Views {
32  [View("Target Response Gradient View")]
33  [Content(typeof(IRegressionSolution))]
34  public partial class RegressionSolutionTargetResponseGradientView : DataAnalysisSolutionEvaluationView {
35    private readonly Dictionary<string, GradientChart> charts;
36    private const int Points = 200;
37
38    private IEnumerable<GradientChart> VisibleCharts {
39      get { return gradientChartTableLayout.Controls.OfType<GradientChart>(); }
40    }
41
42    public RegressionSolutionTargetResponseGradientView() {
43      InitializeComponent();
44      charts = new Dictionary<string, GradientChart>();
45    }
46
47    public new IRegressionSolution Content {
48      get { return (IRegressionSolution)base.Content; }
49      set { base.Content = value; }
50    }
51
52    protected override void RegisterContentEvents() {
53      base.RegisterContentEvents();
54      variableListView.ItemChecked += variableListView_ItemChecked;
55    }
56
57    protected override void DeregisterContentEvents() {
58      variableListView.ItemChecked -= variableListView_ItemChecked;
59      base.DeregisterContentEvents();
60    }
61
62    protected override void OnContentChanged() {
63      base.OnContentChanged();
64      if (Content == null) return;
65      var problemData = Content.ProblemData;
66      // create dataset
67      var variableNames = Content.GetUsedVariablesForPrediction().ToList();
68      var variableValues = variableNames.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
69      var sharedFixedVariables = new ModifiableDataset(variableNames, variableValues);
70      // create charts
71      charts.Clear();
72      foreach (var variableName in variableNames) {
73        var gradientChart = new GradientChart {
74          Dock = DockStyle.Fill,
75          Margin = Padding.Empty,
76          ShowLegend = false,
77          ShowCursor = true,
78          ShowXAxisLabel = true,
79          ShowYAxisLabel = true,
80          YAxisTicks = 5,
81        };
82        gradientChart.VariableValueChanged += async (o, e) => {
83          var recalculations = VisibleCharts.Except(new[] { (GradientChart)o }).Select(async chart => {
84            await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
85          }).ToList();
86          await Task.WhenAll(recalculations);
87
88          if (recalculations.All(t => t.IsCompleted))
89            SyncYAxis();
90        };
91        gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableName, Points);
92        charts[variableName] = gradientChart;
93      }
94      // update variable list
95      variableListView.Items.Clear();
96      variableListView.Items.AddRange(variableNames.Select(x => new ListViewItem(x, 0)).ToArray());
97    }
98
99    private void SyncYAxis() {
100      double min = double.MaxValue, max = double.MinValue;
101      foreach (var chart in VisibleCharts) {
102        if (chart.YMin < min) min = chart.YMin;
103        if (chart.YMax > max) max = chart.YMax;
104      }
105      double axisMin, axisMax, axisInterval;
106      ChartUtil.CalculateAxisInterval(min, max, 5, out axisMin, out axisMax, out axisInterval);
107
108      foreach (var chart in VisibleCharts) {
109        chart.FixedYAxisMin = axisMin;
110        chart.FixedYAxisMax = axisMax;
111        chart.Update();
112      }
113    }
114
115    // sort chart controls so that they always appear in the same order as in the list view
116    // the gradient chart layout should be suspended before calling this method
117    private void SortControls() {
118      var tl = gradientChartTableLayout;
119      var indices = variableListView.CheckedItems.Cast<ListViewItem>().ToDictionary(checkedItem => checkedItem.Text, checkedItem => checkedItem.Index);
120      var count = tl.Controls.Count;
121      var charts = new GradientChart[count];
122      for (int i = 0; i < count; ++i) charts[i] = (GradientChart)tl.Controls[i];
123      Array.Sort(charts, (a, b) => indices[a.FreeVariable].CompareTo(indices[b.FreeVariable]));
124      tl.Controls.Clear();
125      tl.Controls.AddRange(charts);
126    }
127
128    private async void variableListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
129      if (charts == null) return;
130      var item = e.Item;
131      var variable = item.Text;
132      var chart = charts[variable];
133      var tl = gradientChartTableLayout;
134      tl.SuspendLayout();
135      var columnWidth = tl.GetColumnWidths()[0]; // all columns have the same width
136      var rowHeight = 0.8f * columnWidth;
137      tl.RowStyles.Clear();
138      if (item.Checked) {
139        tl.Controls.Add(chart);
140        await chart.RecalculateAsync();
141      } else {
142        tl.Controls.Remove(chart);
143      }
144      SyncYAxis();
145
146      var count = tl.Controls.Count;
147      SortControls();
148      tl.RowCount = count / tl.ColumnCount + (count % tl.ColumnCount == 0 ? 0 : 1);
149      for (int i = 0; i < count; ++i) {
150        var control = tl.Controls[i];
151        int rowIndex = i / tl.ColumnCount;
152        int columnIndex = i % tl.ColumnCount;
153        tl.SetRow(control, rowIndex);
154        tl.SetColumn(control, columnIndex);
155      }
156      for (int i = 0; i < tl.RowCount; ++i) {
157        tl.RowStyles.Add(new RowStyle(SizeType.Absolute, rowHeight));
158      }
159      tl.ResumeLayout();
160    }
161  }
162}
Note: See TracBrowser for help on using the repository browser.