private static double GetFactor(double value) { var factor = 0d; var valueToSF = SignificantDigits.ToSignificantDigits(value, 6); while (valueToSF * Math.Pow(10, factor) != (int)(valueToSF * Math.Pow(10, factor)) && factor < 10) { factor++; } return(Math.Pow(10, factor)); }
private static double Adjust(AdjustType adjustType, double value, int sf) { var adjusted = adjustType == AdjustType.Down ? SignificantDigits.ToSignificantDigits(Math.Floor(value), sf) : SignificantDigits.ToSignificantDigits(Math.Ceiling(value), sf); var adjust = adjustType == AdjustType.Down ? adjusted > value : adjusted < value; while (adjust) { if (adjustType == AdjustType.Down) { adjusted -= 1; adjust = adjusted > value; } else { adjusted += 1; adjust = adjusted < value; } } return(adjusted); }
/// <summary> /// /// </summary> /// <param name="parCode"></param> /// <param name="seriesCollection"></param> public YaxisSettings(string parCode, SeriesCollection seriesCollection) { switch (parCode.ToUpper()) { case "W_PDIR": Minimum = 0; Maximum = 360; Interval = 30; break; case "W_SPR": Minimum = 0; Maximum = 90; Interval = 10; break; default: // Get value range for y-Axis double valuesMin; double valuesMax; try { valuesMin = (from series in seriesCollection select series.Points.FindMinByValue().YValues[0]) .Min(); valuesMax = (from series in seriesCollection select series.Points.FindMaxByValue().YValues[0]) .Max(); } catch { valuesMin = 0; valuesMax = 100; } // Derive Minimum and Maximum const double MINMAX_ADJUSTMENT = 0.001; var minFactor = GetFactor(valuesMin); var minimum = SignificantDigits.ToSignificantDigits(Math.Floor(valuesMin * minFactor) / minFactor, 3); while (minimum > valuesMin - valuesMin * MINMAX_ADJUSTMENT) { minimum -= minimum * MINMAX_ADJUSTMENT; } Minimum = minimum; var maxFactor = GetFactor(valuesMax); var maximum = SignificantDigits.ToSignificantDigits(Math.Ceiling(valuesMax * maxFactor) / maxFactor, 3); while (maximum < valuesMax + valuesMax * MINMAX_ADJUSTMENT) { maximum += maximum * MINMAX_ADJUSTMENT; } Maximum = maximum; // Ensure minimum range const double RANGE_MIN = 0.3; if (Range < RANGE_MIN) { var correction = (RANGE_MIN - Range) / 2; Minimum -= correction; Maximum += correction; } // 'Normalise' min/max and derive interval if (Range <= 0.6) { Minimum = Math.Floor(Minimum * 20) / 20; Maximum = Math.Ceiling(Maximum * 20) / 20; Interval = 0.05; } else if (Range <= 2.5) { Minimum = Math.Floor(Minimum * 10) / 10; Maximum = Math.Ceiling(Maximum * 10) / 10; Interval = 0.25; } else if (Range <= 5) { Minimum = Math.Floor(Minimum * 5) / 5; Maximum = Math.Ceiling(Maximum * 5) / 5; Interval = 0.5; } else if (Range <= 10) { Minimum = Adjust(AdjustType.Down, Minimum, 2); Maximum = Adjust(AdjustType.Up, Maximum, 2); Interval = 1; } else { Minimum = Adjust(AdjustType.Down, Minimum, 1); Maximum = Adjust(AdjustType.Up, Maximum, 1); Interval = SignificantDigits.ToSignificantDigits(Range / 10, 2); } // Minor tick interval MinorTickInterval = Range / Interval < 6 ? Interval / 2 : default(double?); // Derive label format (defaults to "f0"): for (var format = 0; format < 4; format++) { var formatString = $"f{format}"; if (double.Parse(Interval.ToString(formatString)) == Interval) { LabelFormat = formatString; break; } } break; } }