/// <summary> /// Updates the list of categories. /// </summary> private void UpdateCategories() { IEnumerable <object> categories = RegisteredListeners .OfType <IDataProvider>() .SelectMany(infoProvider => infoProvider.GetData(this)) .Distinct(); if (SortOrder == CategorySortOrder.Ascending) { categories = categories.OrderBy(category => category); } else if (SortOrder == CategorySortOrder.Descending) { categories = categories.OrderByDescending(category => category); } Categories = categories.ToList(); Invalidate(); }
protected override Range <DateTime> OverrideDataRange(Range <DateTime> range) { var overriddenActualRange = range; if (!overriddenActualRange.HasData) { int year = DateTime.Now.Year; return(new Range <DateTime>(new DateTime(year, 1, 1), new DateTime(year + 1, 1, 1))); } // ActualLength of 1.0 or less maps all points to the same coordinate if (range.HasData && ActualLength > 1.0) { IList <ValueMarginCoordinateAndOverlap> valueMargins = RegisteredListeners.OfType <IValueMarginProvider>() .SelectMany(provider => provider.GetValueMargins(this)) .Select(valueMargin => new ValueMarginCoordinateAndOverlap { ValueMargin = valueMargin, }) .ToList(); if (valueMargins.Count > 0) { // ReSharper disable once PossibleInvalidOperationException 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 > ActualLength) { return(range); } Range <DateTime> currentRange = range; // Ensure range is not empty. if (currentRange.Minimum == currentRange.Maximum) { int year = DateTime.Now.Year; currentRange = new Range <DateTime>(new DateTime(year, 1, 1), new DateTime(year + 1, 1, 1)); } // priming the loop double actualLength = ActualLength; ValueMarginCoordinateAndOverlap maxLeftOverlapValueMargin; ValueMarginCoordinateAndOverlap maxRightOverlapValueMargin; UpdateValueMargins(valueMargins, currentRange); GetMaxLeftAndRightOverlap(valueMargins, out maxLeftOverlapValueMargin, out maxRightOverlapValueMargin); while (maxLeftOverlapValueMargin.LeftOverlap > 0 || maxRightOverlapValueMargin.RightOverlap > 0) { // ReSharper disable once PossibleInvalidOperationException long unitOverPixels = currentRange.GetLength().Value.Ticks / ((long)actualLength); var newMinimum = new DateTime(currentRange.Minimum.Ticks - (long)((maxLeftOverlapValueMargin.LeftOverlap + 0.5) * unitOverPixels)); var newMaximum = new DateTime(currentRange.Maximum.Ticks + (long)((maxRightOverlapValueMargin.RightOverlap + 0.5) * unitOverPixels)); currentRange = new Range <DateTime>(newMinimum, newMaximum); UpdateValueMargins(valueMargins, currentRange); GetMaxLeftAndRightOverlap(valueMargins, out maxLeftOverlapValueMargin, out maxRightOverlapValueMargin); } return(currentRange); } } return(range); }
/// <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 <double> OverrideDataRange(Range <double> range) { range = base.OverrideDataRange(range); if (!range.HasData) { return(new Range <double>(0.0, 1.0)); } if (ValueHelper.Compare(range.Minimum, range.Maximum) == 0) { var outputRange = new Range <double>((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 && ActualLength > 1.0) { bool isDataAnchoredToOrigin = false; IList <ValueMarginCoordinateAndOverlap> valueMargins = new List <ValueMarginCoordinateAndOverlap>(); foreach (IValueMarginProvider valueMarginProvider in RegisteredListeners.OfType <IValueMarginProvider>()) { foreach (ValueMargin valueMargin in valueMarginProvider.GetValueMargins(this)) { var dataAnchoredToOrigin = valueMarginProvider as IAnchoredToOrigin; // ReSharper disable once PossibleUnintendedReferenceComparison 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) .Max(); // Requested margin is larger than the axis so give up // trying to find a range that will fit it. if (maximumPixelMarginLength > ActualLength) { return(range); } Range <double> originalRange = range; Range <double> currentRange = range; // 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 = ActualLength; ValueMarginCoordinateAndOverlap maxLeftOverlapValueMargin; ValueMarginCoordinateAndOverlap maxRightOverlapValueMargin; UpdateValueMargins(valueMargins, currentRange); GetMaxLeftAndRightOverlap(valueMargins, out maxLeftOverlapValueMargin, out maxRightOverlapValueMargin); while (maxLeftOverlapValueMargin.LeftOverlap > 0 || maxRightOverlapValueMargin.RightOverlap > 0) { // ReSharper disable once PossibleInvalidOperationException 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); 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); } } return(range); }