source: trunk/sources/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ChartUtil.cs @ 13807

Last change on this file since 13807 was 13807, checked in by bburlacu, 5 years ago

#2594: Fix bug in Decimals method causing an infinite loop when the value is zero.

File size: 2.6 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25
26namespace HeuristicLab.Visualization.ChartControlsExtensions {
27  public static class ChartUtil {
28    public static void CalculateAxisInterval(double min, double max, int ticks, out double axisMin, out double axisMax, out double axisInterval) {
29      var dmin = min.Decimals();
30      axisMin = min.Floor(dmin);
31      var range = max - axisMin;
32      var slice = range / ticks;
33      var dslice = slice.Decimals();
34      var floor = slice.Floor(dslice);
35      var ceil = slice.Ceil(dslice);
36      var axisRange = floor * ticks;
37      axisInterval = floor;
38      if (axisRange < max - axisMin) {
39        axisRange = ceil * ticks;
40        axisInterval = ceil;
41      }
42      axisMax = axisMin + axisRange;
43    }
44
45    private static int Decimals(this double x) {
46      if (x.IsAlmost(0) || double.IsInfinity(x) || double.IsNaN(x))
47        return 0;
48
49      var v = Math.Abs(x);
50      int d = 0;
51      while (v < 1) {
52        v *= 10;
53        d++;
54      }
55      return d;
56    }
57
58    // rounds down to the nearest value according to the given number of decimal precision
59    private static double Floor(this double value, int precision) {
60      var n = Math.Pow(10, precision);
61      return Math.Round(Math.Floor(value * n) / n, precision);
62    }
63
64    private static double Ceil(this double value, int precision) {
65      var n = Math.Pow(10, precision);
66      return Math.Round(Math.Ceiling(value * n) / n, precision);
67    }
68
69    private static double Round(this double value, int precision) {
70      var n = Math.Pow(10, precision);
71      return Math.Round(Math.Round(value * n) / n, precision);
72    }
73
74    private static bool IsAlmost(this double value, double other, double eps = 1e-12) {
75      return Math.Abs(value - other) < eps;
76    }
77  }
78}
Note: See TracBrowser for help on using the repository browser.