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