/// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
            }
        }