- Timestamp:
- 07/21/16 16:57:58 (8 years ago)
- Location:
- stable
- Files:
-
- 5 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
stable
- Property svn:mergeinfo changed
/trunk/sources merged: 13764-13765,13807,14007-14008,14152,14155-14156,14159
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Problems.DataAnalysis.Views
- Property svn:mergeinfo changed
/trunk/sources/HeuristicLab.Problems.DataAnalysis.Views merged: 13764,14008
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs
r12009 r14161 26 26 using System.Windows.Forms.DataVisualization.Charting; 27 27 using HeuristicLab.MainForm; 28 using HeuristicLab.Visualization.ChartControlsExtensions; 28 29 29 30 namespace HeuristicLab.Problems.DataAnalysis.Views { … … 96 97 this.ToggleSeriesData(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]); 97 98 99 // set the y-axis bounds 100 var axisY = this.chart.ChartAreas[0].AxisY; 101 double min = double.MaxValue, max = double.MinValue; 102 foreach (var point in chart.Series.SelectMany(x => x.Points)) { 103 if (!point.YValues.Any() || double.IsInfinity(point.YValues[0]) || double.IsNaN(point.YValues[0])) 104 continue; 105 var y = point.YValues[0]; 106 if (y < min) 107 min = y; 108 if (y > max) 109 max = y; 110 } 111 112 double axisMin, axisMax, axisInterval; 113 ChartUtil.CalculateOptimalAxisInterval(min, max, out axisMin, out axisMax, out axisInterval); 114 axisY.Minimum = axisMin; 115 axisY.Maximum = axisMax; 116 axisY.Interval = axisInterval; 117 98 118 UpdateCursorInterval(); 99 119 this.UpdateStripLines(); -
stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs
r14112 r14161 26 26 using HeuristicLab.MainForm; 27 27 using HeuristicLab.MainForm.WindowsForms; 28 using HeuristicLab.Visualization.ChartControlsExtensions; 28 29 29 30 namespace HeuristicLab.Problems.DataAnalysis.Views { … … 169 170 double min = Content.EstimatedTrainingValues.Concat(Content.EstimatedTestValues.Concat(Content.EstimatedValues.Concat(dataset.GetDoubleValues(targetVariableName)))).Min(); 170 171 171 max = max + 0.2 * Math.Abs(max); 172 min = min - 0.2 * Math.Abs(min); 173 174 double interestingValuesRange = max - min; 175 int digits = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRange)); 176 177 max = Math.Round(max, digits); 178 min = Math.Round(min, digits); 179 180 this.chart.ChartAreas[0].AxisX.Maximum = max; 181 this.chart.ChartAreas[0].AxisX.Minimum = min; 182 this.chart.ChartAreas[0].AxisY.Maximum = max; 183 this.chart.ChartAreas[0].AxisY.Minimum = min; 172 double axisMin, axisMax, axisInterval; 173 ChartUtil.CalculateOptimalAxisInterval(min, max, out axisMin, out axisMax, out axisInterval); 174 this.chart.ChartAreas[0].AxisX.Maximum = axisMax; 175 this.chart.ChartAreas[0].AxisX.Minimum = axisMin; 176 this.chart.ChartAreas[0].AxisX.Interval = axisInterval; 177 this.chart.ChartAreas[0].AxisY.Maximum = axisMax; 178 this.chart.ChartAreas[0].AxisY.Minimum = axisMin; 179 this.chart.ChartAreas[0].AxisY.Interval = axisInterval; 180 184 181 UpdateCursorInterval(); 185 182 } -
stable/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ChartUtil.cs
r13765 r14161 27 27 public static class ChartUtil { 28 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; 29 if (double.IsInfinity(min) || double.IsNaN(min) || double.IsInfinity(max) || double.IsNaN(max) || (min >= max)) 30 throw new ArgumentOutOfRangeException("Invalid range provided."); 31 32 var range = max - min; 33 var dRange = (int)Math.Round(Math.Log10(range)); 34 int decimalRank = dRange - 1; 35 var aMin = min.RoundDown(decimalRank); 36 var aMax = max.RoundUp(decimalRank); 37 38 // if one of the interval ends is a multiple of 5 or 10, change the other interval end to be a multiple as well 39 if ((aMin.Mod(5).IsAlmost(0) || aMin.Mod(10).IsAlmost(0)) && Math.Abs(aMax) >= 5 && !(aMax.Mod(5).IsAlmost(0) || aMax.Mod(10).IsAlmost(0))) { 40 aMax = Math.Min(aMax + 5 - aMax % 5, aMax + 10 - aMax % 10); 41 } else if ((aMax.Mod(5).IsAlmost(0) || aMax.Mod(10).IsAlmost(0)) && Math.Abs(aMin) >= 5 && !(aMin.Mod(5).IsAlmost(0) || aMin.Mod(10).IsAlmost(0))) { 42 aMin = Math.Max(aMin - aMin.Mod(5), aMin - aMin.Mod(10)); 41 43 } 42 axisMax = axisMin + axisRange; 44 45 axisMin = aMin; 46 axisMax = aMax; 47 axisInterval = (aMax - aMin) / ticks; 43 48 } 44 49 50 /// <summary> 51 /// Tries to find an axis interval with as few fractional digits as possible (because it looks nicer). we only try between 3 and 5 ticks (inclusive) because it wouldn't make sense to exceed this interval. 52 /// </summary> 53 public static void CalculateOptimalAxisInterval(double min, double max, out double axisMin, out double axisMax, out double axisInterval) { 54 CalculateAxisInterval(min, max, 5, out axisMin, out axisMax, out axisInterval); 55 int bestLsp = int.MaxValue; 56 for (int ticks = 3; ticks <= 5; ++ticks) { 57 double aMin, aMax, aInterval; 58 CalculateAxisInterval(min, max, ticks, out aMin, out aMax, out aInterval); 59 var x = aInterval; 60 int lsp = 0; // position of the least significant fractional digit 61 while (x - Math.Floor(x) > 0) { 62 ++lsp; 63 x *= 10; 64 } 65 if (lsp <= bestLsp) { 66 axisMin = aMin; 67 axisMax = aMax; 68 axisInterval = aInterval; 69 bestLsp = lsp; 70 } 71 } 72 } 73 74 // find the number of decimals needed to represent the value 45 75 private static int Decimals(this double x) { 46 if ( double.IsInfinity(x) || double.IsNaN(x))76 if (x.IsAlmost(0) || double.IsInfinity(x) || double.IsNaN(x)) 47 77 return 0; 48 78 49 79 var v = Math.Abs(x); 50 int d = 0;80 int d = 1; 51 81 while (v < 1) { 52 82 v *= 10; … … 54 84 } 55 85 return d; 86 } 87 88 private static double RoundDown(this double value, int decimalRank) { 89 if (decimalRank > 0) { 90 var floor = (int)Math.Floor(value); 91 var pow = (int)Math.Pow(10, decimalRank); 92 var mod = Mod(floor, pow); 93 return floor - mod; 94 } 95 return value.Floor(Math.Abs(decimalRank)); 96 } 97 98 private static double RoundUp(this double value, int decimalRank) { 99 if (decimalRank > 0) { 100 var ceil = (int)Math.Ceiling(value); 101 var pow = (int)Math.Pow(10, decimalRank); 102 var mod = Mod(ceil, pow); 103 return ceil - mod + pow; 104 } 105 return value.Ceil(Math.Abs(decimalRank)); 106 } 107 108 private static double RoundNearest(this double value, int decimalRank) { 109 var nearestDown = value.RoundDown(decimalRank); 110 var nearestUp = value.RoundUp(decimalRank); 111 112 if (nearestUp - value > value - nearestDown) 113 return nearestDown; 114 115 return nearestUp; 56 116 } 57 117 … … 62 122 } 63 123 124 // rounds up to the nearest value according to the given number of decimal precision 64 125 private static double Ceil(this double value, int precision) { 65 126 var n = Math.Pow(10, precision); … … 67 128 } 68 129 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); 130 private static bool IsAlmost(this double value, double other, double eps = 1e-12) { 131 return Math.Abs(value - other) < eps; 132 } 133 134 private static double Mod(this double a, double b) { 135 return a - b * Math.Floor(a / b); 72 136 } 73 137 } -
stable/HeuristicLab.Visualization.ChartControlsExtensions/3.3/HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj
r11920 r14161 121 121 </ItemGroup> 122 122 <ItemGroup> 123 <Compile Include="ChartUtil.cs" /> 123 124 <Compile Include="EnhancedChart.cs"> 124 125 <SubType>Component</SubType>
Note: See TracChangeset
for help on using the changeset viewer.