Free cookie consent management tool by TermsFeed Policy Generator

source: branches/histogram/HeuristicLab.Visualization.ChartControlsExtensions/3.3/HistogramControl.cs @ 5970

Last change on this file since 5970 was 5970, checked in by abeham, 13 years ago

#1465

  • Separated HistogramView into a view and a control
  • Added the HistogramControl to ChartControlsExtensions (not yet userfriendly)
File size: 4.1 KB
RevLine 
[5970]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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 System.Windows.Forms.DataVisualization.Charting;
28
29namespace HeuristicLab.Visualization.ChartControlsExtensions {
30  public partial class HistogramControl : UserControl {
31    private static readonly string SeriesName = "Histogram";
32
33    private List<double> points;
34
35    public HistogramControl() {
36      InitializeComponent();
37      points = new List<double>();
38      InitializeChart();
39    }
40
41    public void AddPoint(double point) {
42      points.Add(point);
43      UpdateHistogram();
44    }
45
46    public void AddPoints(IEnumerable<double> points) {
47      this.points.AddRange(points);
48      UpdateHistogram();
49    }
50
51    public void ClearPoints() {
52      points.Clear();
53      UpdateHistogram();
54    }
55
56    private void InitializeChart() {
57      chart.Series.Clear();
58      Series s = chart.Series.Add(SeriesName);
59      s.ChartType = SeriesChartType.Column;
60      s.BorderColor = Color.Black;
61      s.BorderWidth = 1;
62      s.BorderDashStyle = ChartDashStyle.Solid;
63    }
64
65    private void UpdateHistogram() {
66
67      Series histogramSeries = chart.Series[SeriesName];
68      histogramSeries.Points.Clear();
69
70      if (!points.Any()) return;
71      int bins = (int)binsNumericUpDown.Value;
72
73      double minValue = points.Min();
74      double maxValue = points.Max();
75      double intervalWidth = (maxValue - minValue) / bins;
76      if (intervalWidth <= 0) return;
77
78      if (!exactCheckBox.Checked) {
79        intervalWidth = HumanRoundRange(intervalWidth);
80        minValue = Math.Floor(minValue / intervalWidth) * intervalWidth;
81        maxValue = Math.Ceiling(maxValue / intervalWidth) * intervalWidth;
82      }
83
84      double current = minValue;
85      int count = 0;
86      foreach (double v in points.OrderBy(x => x)) {
87        if (v < current + intervalWidth) {
88          count++;
89        } else {
90          histogramSeries.Points.AddXY(current + intervalWidth / 2.0, count);
91          count = 1;
92          while (v >= current + intervalWidth) current += intervalWidth;
93        }
94      }
95      histogramSeries.Points.AddXY(current + intervalWidth / 2.0, count);
96
97      histogramSeries["PointWidth"] = "1";
98
99      ChartArea chartArea = chart.ChartAreas[histogramSeries.ChartArea];
100      chartArea.AxisY.Title = "Frequency";
101      chartArea.AxisX.Minimum = minValue;
102      chartArea.AxisX.Maximum = maxValue;
103
104      double axisInterval = intervalWidth;
105      while ((maxValue - minValue) / axisInterval > 10.0) {
106        axisInterval *= 2.0;
107      }
108      chartArea.AxisX.Interval = axisInterval;
109    }
110
111    private double HumanRoundRange(double range) {
112      double base10 = Math.Pow(10.0, Math.Floor(Math.Log10(range)));
113      double rounding = range / base10;
114      if (rounding <= 1.5) rounding = 1;
115      else if (rounding <= 2) rounding = 2;
116      else if (rounding <= 2.5) rounding = 2.5;
117      else if (rounding <= 5) rounding = 5;
118      else rounding = 10;
119      return rounding * base10;
120    }
121
122    private void binsNumericUpDown_ValueChanged(object sender, EventArgs e) {
123      UpdateHistogram();
124    }
125
126    private void exactCheckBox_CheckedChanged(object sender, EventArgs e) {
127      UpdateHistogram();
128    }
129  }
130}
Note: See TracBrowser for help on using the repository browser.