/// <summary> /// Overrides the data value range and returns a range that takes the /// margins of the values into account. /// </summary> /// <param name="range">The range of data values.</param> /// <returns>A range that can store both the data values and their /// margins.</returns> protected override Range <IComparable> OverrideDataRange(Range <IComparable> range) { range = base.OverrideDataRange(range); if (ExtendRangeToOrigin) { Range <double> adjustedRange = range.ToDoubleRange(); if (!adjustedRange.HasData) { return(new Range <IComparable>(0.0, 0.0)); } else { double minimum = adjustedRange.Minimum; double maximum = adjustedRange.Maximum; if (minimum > 0.0) { minimum = 0.0; } else if (maximum < 0.0) { maximum = 0.0; } return(new Range <IComparable>(minimum, maximum)); } } return(range); }
/// <summary> /// Returns the plot area coordinate of a value. /// </summary> /// <param name="value">The value to plot.</param> /// <param name="currentRange">The range of values.</param> /// <param name="length">The length of axis.</param> /// <returns>The plot area coordinate of a value.</returns> protected override UnitValue GetPlotAreaCoordinate(object value, Range <IComparable> currentRange, double length) { return(GetPlotAreaCoordinate(value, currentRange.ToDoubleRange(), length)); }
/// <summary> /// Overrides the actual range to ensure that it is never set to an /// empty range. /// </summary> /// <param name="range">The range to override.</param> /// <returns>Returns the overridden range.</returns> protected override Range <IComparable> OverrideDataRange(Range <IComparable> range) { range = base.OverrideDataRange(range); if (!range.HasData) { return(new Range <IComparable>(0.0, 1.0)); } else if (ValueHelper.Compare(range.Minimum, range.Maximum) == 0) { Range <IComparable> outputRange = new Range <IComparable>((ValueHelper.ToDouble(range.Minimum)) - 1, (ValueHelper.ToDouble(range.Maximum)) + 1); return(outputRange); } // ActualLength of 1.0 or less maps all points to the same coordinate if (range.HasData && this.ActualLength > 1.0) { bool isDataAnchoredToOrigin = false; IList <ValueMarginCoordinateAndOverlap> valueMargins = new List <ValueMarginCoordinateAndOverlap>(); foreach (IValueMarginProvider valueMarginProvider in this.RegisteredListeners.OfType <IValueMarginProvider>()) { foreach (ValueMargin valueMargin in valueMarginProvider.GetValueMargins(this)) { IAnchoredToOrigin dataAnchoredToOrigin = valueMarginProvider as IAnchoredToOrigin; isDataAnchoredToOrigin = (dataAnchoredToOrigin != null && dataAnchoredToOrigin.AnchoredAxis == this); valueMargins.Add( new ValueMarginCoordinateAndOverlap { ValueMargin = valueMargin, }); } } if (valueMargins.Count > 0) { double maximumPixelMarginLength = valueMargins .Select(valueMargin => valueMargin.ValueMargin.LowMargin + valueMargin.ValueMargin.HighMargin) .MaxOrNullable().Value; // Requested margin is larger than the axis so give up // trying to find a range that will fit it. if (maximumPixelMarginLength > this.ActualLength) { return(range); } Range <double> originalRange = range.ToDoubleRange(); Range <double> currentRange = range.ToDoubleRange(); // Ensure range is not empty. if (currentRange.Minimum == currentRange.Maximum) { currentRange = new Range <double>(currentRange.Maximum - 1, currentRange.Maximum + 1); } // priming the loop double actualLength = this.ActualLength; ValueMarginCoordinateAndOverlap maxLeftOverlapValueMargin; ValueMarginCoordinateAndOverlap maxRightOverlapValueMargin; UpdateValueMargins(valueMargins, currentRange.ToComparableRange()); GetMaxLeftAndRightOverlap(valueMargins, out maxLeftOverlapValueMargin, out maxRightOverlapValueMargin); while (maxLeftOverlapValueMargin.LeftOverlap > 0 || maxRightOverlapValueMargin.RightOverlap > 0) { double unitOverPixels = currentRange.GetLength().Value / actualLength; double newMinimum = currentRange.Minimum - ((maxLeftOverlapValueMargin.LeftOverlap + 0.5) * unitOverPixels); double newMaximum = currentRange.Maximum + ((maxRightOverlapValueMargin.RightOverlap + 0.5) * unitOverPixels); currentRange = new Range <double>(newMinimum, newMaximum); UpdateValueMargins(valueMargins, currentRange.ToComparableRange()); GetMaxLeftAndRightOverlap(valueMargins, out maxLeftOverlapValueMargin, out maxRightOverlapValueMargin); } if (isDataAnchoredToOrigin) { if (originalRange.Minimum >= 0 && currentRange.Minimum < 0) { currentRange = new Range <double>(0, currentRange.Maximum); } else if (originalRange.Maximum <= 0 && currentRange.Maximum > 0) { currentRange = new Range <double>(currentRange.Minimum, 0); } } return(currentRange.ToComparableRange()); } } return(range); }
/// <summary> /// Updates ActualDoubleRange when ActualRange changes. /// </summary> /// <param name="range">New ActualRange value.</param> protected override void OnActualRangeChanged(Range <IComparable> range) { ActualDoubleRange = range.ToDoubleRange(); base.OnActualRangeChanged(range); }