Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/DensityTrackbar.cs @ 13846

Last change on this file since 13846 was 13846, checked in by pfleck, 9 years ago

#2597

  • Added a manual y-axis control.
  • Fixed bug with dragging the cursor in the GradientChart out of the chart.
File size: 5.8 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.Globalization;
25using System.Linq;
26using System.Windows.Forms;
27using System.Windows.Forms.DataVisualization.Charting;
28using HeuristicLab.Common;
29using HeuristicLab.Problems.DataAnalysis;
30
31namespace HeuristicLab.Algorithms.DataAnalysis.Views {
32  public partial class DensityTrackbar : UserControl {
33
34    public decimal Value {
35      get { return TickToValue(trackBar.Value); }
36      set { trackBar.Value = ValueToTick(value); }
37    }
38    public event EventHandler ValueChanged;
39
40    public bool Checked {
41      get { return radioButton.Checked; }
42      set { radioButton.Checked = value; }
43    }
44    public event EventHandler CheckedChanged;
45
46    public DoubleLimit Limits {
47      get { return doubleLimitView.Content; }
48    }
49    public event EventHandler LimitsChanged;
50
51    private IList<double> trainingValues;
52
53    // For VisualStudio Designer
54    internal DensityTrackbar() {
55      InitializeComponent();
56    }
57
58    public DensityTrackbar(string name, DoubleLimit limit, IList<double> trainingValues) {
59      InitializeComponent();
60
61      this.trainingValues = trainingValues;
62
63      doubleLimitView.Content = limit;
64      doubleLimitView.Content.ValueChanged += doubleLimit_ValueChanged;
65
66      textBox.Text = Value.ToString(CultureInfo.InvariantCulture);
67      radioButton.Text = name;
68
69      UpdateDensityChart();
70    }
71
72    public void UpdateTrainingValues(IList<double> trainingValues) {
73      this.trainingValues = trainingValues;
74      UpdateDensityChart();
75    }
76
77    private void UpdateDensityChart() {
78      var series = chart.Series[0];
79      ClearPointsQuick(series.Points);
80
81      int numBuckets = trackBar.Maximum - trackBar.Minimum;
82      var buckets = new double[numBuckets];
83      var bucketSize = (Limits.Upper - Limits.Lower) / buckets.Length;
84      foreach (var value in trainingValues) {
85        if (bucketSize > 0.0) {
86          int bucketIndex = (int)((value - Limits.Lower) / bucketSize);
87          if (bucketIndex == numBuckets) {
88            bucketIndex--;
89          }
90          buckets[bucketIndex] += 1.0;
91        }
92      }
93
94      // set minimum height of all non-zero buckets on 20% of maximum
95      double min = buckets.Max() / 20.0;
96      for (int i = 0; i < buckets.Length; i++) {
97        if (buckets[i] >= 1 && buckets[i] < min)
98          buckets[i] = min;
99      }
100
101      series.Points.DataBindY(buckets);
102
103      // Set trackbar on highest density
104      double highestDensity = buckets.Max();
105      var highestIndices = buckets.Select((v, i) => new { v, i }).Where(x => x.v.IsAlmost(highestDensity)).Select(x => x.i).ToList();
106      trackBar.Value = highestIndices[highestIndices.Count / 2];
107    }
108
109    #region Event Handlers
110    private void trackBar_ValueChanged(object sender, EventArgs e) {
111      textBox.Text = Value.ToString(CultureInfo.InvariantCulture);
112      OnValueChanged();
113    }
114    private void doubleLimit_ValueChanged(object sender, EventArgs e) {
115      UpdateDensityChart();
116      OnLimitsChanged();
117      OnValueChanged();
118    }
119    private void radioButton_CheckedChanged(object sender, EventArgs e) {
120      Checked = radioButton.Checked;
121      trackBar.Enabled = !Checked;
122      textBox.Text = Checked ? "Plotted" : Value.ToString(CultureInfo.InvariantCulture);
123      OnCheckedChanged();
124    }
125    protected override void OnTextChanged(EventArgs e) {
126      base.OnTextChanged(e);
127      radioButton.Text = Text;
128    }
129    #endregion
130
131    protected virtual void OnValueChanged() {
132      if (ValueChanged != null)
133        ValueChanged(this, EventArgs.Empty);
134    }
135    protected virtual void OnCheckedChanged() {
136      if (CheckedChanged != null)
137        CheckedChanged(this, EventArgs.Empty);
138    }
139    protected virtual void OnLimitsChanged() {
140      if (LimitsChanged != null)
141        LimitsChanged(this, EventArgs.Empty);
142    }
143    #region Hepers
144
145    private decimal TickToValue(int tick) {
146      return TickToValue(tick, trackBar.Maximum - trackBar.Minimum, (decimal)Limits.Lower, (decimal)Limits.Upper);
147    }
148    private int ValueToTick(decimal value) {
149      return ValueToTick(value, trackBar.Maximum - trackBar.Minimum, (decimal)Limits.Lower, (decimal)Limits.Upper);
150    }
151    private static decimal TickToValue(int tick, int numberOfTicks, decimal lower, decimal upper) {
152      return lower + (upper - lower) * tick / numberOfTicks;
153    }
154    private static int ValueToTick(decimal value, int numberOfTicks, decimal lower, decimal upper) {
155      return (int)((value - lower) / ((upper - lower) / numberOfTicks));
156    }
157
158    // workaround as per http://stackoverflow.com/questions/5744930/datapointcollection-clear-performance
159    private static void ClearPointsQuick(DataPointCollection points) {
160      points.SuspendUpdates();
161      while (points.Count > 0)
162        points.RemoveAt(points.Count - 1);
163      points.ResumeUpdates();
164    }
165
166    #endregion
167  }
168}
Note: See TracBrowser for help on using the repository browser.