/// <summary> /// Returns the value range given a plot area coordinate. /// </summary> /// <param name="value">The plot area position.</param> /// <returns>The value at that plot area coordinate.</returns> protected override IComparable GetValueAtPosition(UnitValue value) { if (ActualRange.HasData && ActualLength != 0.0) { if (value.Unit == Unit.Pixels) { double coordinate = value.Value; Range <double> actualDoubleRange = ActualRange.ToDoubleRange(); double output = Math.Pow ( 10, coordinate * Math.Log10(actualDoubleRange.Maximum / actualDoubleRange.Minimum) / ActualLength ) * actualDoubleRange.Minimum; return(output); } else { throw new NotImplementedException(); } } return(null); }
/// <summary> /// Returns the actual interval to use to determine which values are /// displayed in the axis. /// </summary> /// <param name="availableSize">The available size.</param> /// <returns>Actual interval to use to determine which values are /// displayed in the axis. /// </returns> protected virtual double CalculateActualInterval(Size availableSize) { if (Interval != null) { return(Interval.Value); } Range <double> doubleActualRange = ActualRange.ToDoubleRange(); // helper functions Func <double, double> Exponent = x => Math.Ceiling(Math.Log(x, 10)); Func <double, double> Mantissa = x => x / Math.Pow(10, Exponent(x) - 1); // reduce intervals for horizontal axis. double maxIntervals = Orientation == AxisOrientation.X ? MaximumAxisIntervalsPer200Pixels * 0.8 : MaximumAxisIntervalsPer200Pixels; // real maximum interval count double maxIntervalCount = GetLength(availableSize) / 200 * maxIntervals; double range = Math.Abs(doubleActualRange.Minimum - doubleActualRange.Maximum); double interval = Math.Pow(10, Exponent(range)); double tempInterval = interval; // decrease interval until interval count becomes less than maxIntervalCount while (true) { int mantissa = (int)Mantissa(tempInterval); if (mantissa == 5) { // reduce 5 to 2 tempInterval = ValueHelper.RemoveNoiseFromDoubleMath(tempInterval / 2.5); } else if (mantissa == 2 || mantissa == 1 || mantissa == 10) { // reduce 2 to 1,10 to 5,1 to 0.5 tempInterval = ValueHelper.RemoveNoiseFromDoubleMath(tempInterval / 2.0); } if (range / tempInterval > maxIntervalCount) { break; } interval = tempInterval; } return(interval); }
/// <summary> /// Returns the value range given a plot area coordinate. /// </summary> /// <param name="value">The plot area position.</param> /// <returns>The value at that plot area coordinate.</returns> protected override IComparable GetValueAtPosition(UnitValue value) { if (ActualRange.HasData && ActualLength != 0.0) { if (value.Unit == Unit.Pixels) { double coordinate = value.Value; Range <double> actualDoubleRange = ActualRange.ToDoubleRange(); double rangelength = actualDoubleRange.Maximum - actualDoubleRange.Minimum; double output = ((coordinate * (rangelength / ActualLength)) + actualDoubleRange.Minimum); return(output); } else { throw new NotImplementedException(); } } return(null); }
/// <summary> /// Returns a sequence of major axis values. /// </summary> /// <param name="availableSize">The available size.</param> /// <returns>A sequence of major axis values. /// </returns> private IEnumerable <double> GetMajorValues(Size availableSize) { if (!ActualRange.HasData || ValueHelper.Compare(ActualRange.Minimum, ActualRange.Maximum) == 0 || GetLength(availableSize) == 0.0) { yield break; } Range <double> typedActualRange = ActualRange.ToDoubleRange(); this.ActualInterval = CalculateActualInterval(availableSize); double startValue = AlignToInterval(typedActualRange.Minimum, this.ActualInterval); if (startValue < typedActualRange.Minimum) { startValue = AlignToInterval(typedActualRange.Minimum + this.ActualInterval, this.ActualInterval); } double nextValue = startValue; for (int counter = 1; nextValue <= typedActualRange.Maximum; counter++) { yield return(nextValue); nextValue = startValue + (counter * this.ActualInterval); } }