/// <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); }