/// <summary> /// Converts a given size of the x-axis to the amount of pixels required to display it. /// </summary> /// <param name="size">The size on the x-axis.</param> /// <param name="intervals">The currently visible interval.</param> /// <param name="panelSize">The amount of pixels within which the interval is shown.</param> /// <returns></returns> protected static double SizeToPixels(TXSize size, AxesIntervals <TX, TXSize, TY, TYSize> intervals, Size panelSize) { double intervalSize = Interval <TX, TXSize> .ConvertSizeToDouble(intervals.IntervalX.Size); double requestedSize = Interval <TX, TXSize> .ConvertSizeToDouble(size); return(panelSize.Width * (requestedSize / intervalSize)); }
/// <summary> /// Converts a given amount of pixels to the equivalent size along the x-axis which that amount of pixels represents. /// </summary> /// <param name="pixels">The amount of pixels for which to know the size along the x-axis.</param> /// <param name="intervals">The currently visible interval.</param> /// <param name="panelSize">The amount of pixels within which the interval is shown.</param> /// <returns></returns> protected static TXSize PixelsToSize(double pixels, AxesIntervals <TX, TXSize, TY, TYSize> intervals, Size panelSize) { double intervalSize = Interval <TX, TXSize> .ConvertSizeToDouble(intervals.IntervalX.Size); double size = (pixels / panelSize.Width) * intervalSize; return(Interval <TX, TXSize> .ConvertDoubleToSize(size)); }
double IntervalSize <T, TSize>(Interval <T, TSize> visible, TSize desiredSize, double visiblePixels) where T : IComparable <T> where TSize : IComparable <TSize> { double intervalSize = Interval <T, TSize> .ConvertSizeToDouble(visible.Size); double desired = Interval <T, TSize> .ConvertSizeToDouble(desiredSize); return((desired / intervalSize) * visiblePixels); }
public override void VisibleIntervalChanged( AxesIntervals <TX, TXSize, TY, TYSize> visible, AxesIntervals <TX, TXSize, TY, TYSize> limits, Size panelSize) { // Create extended intervals. Interval <TX, TXSize> intervalX = visible.IntervalX; Interval <TY, TYSize> intervalY = visible.IntervalY; Tuple <TXSize, TYSize> maxLabelSize = GetMaximumLabelSize(visible); var additionalX = Operator <TXSize> .Add(maxLabelSize.Item1, maxLabelSize.Item1); var additionalY = Operator <TYSize> .Add(maxLabelSize.Item2, maxLabelSize.Item2); var extendedX = Operator <TXSize> .Add(intervalX.Size, additionalX); var extendedY = Operator <TYSize> .Add(intervalY.Size, additionalY); double scaleX = Interval <TX, TXSize> .ConvertSizeToDouble(extendedX) / Interval <TX, TXSize> .ConvertSizeToDouble(intervalX.Size); double scaleY = Interval <TY, TYSize> .ConvertSizeToDouble(extendedY) / Interval <TY, TYSize> .ConvertSizeToDouble(intervalY.Size); Interval <TX, TXSize> scaledX = intervalX.Scale(scaleX, limits.IntervalX); Interval <TY, TYSize> scaledY = intervalY.Scale(scaleY, limits.IntervalY); var extendedIntervals = new AxesIntervals <TX, TXSize, TY, TYSize>(scaledX, scaledY); var toPosition = new HashSet <Tuple <TX, TY> >(GetPositions(extendedIntervals, panelSize)); // Free up labels which are no longer visible, and update those already positioned. var toRemove = new List <PositionedElement>(); var toUpdate = new List <PositionedElement>(); foreach (var positioned in _visibleLabels) { if (toPosition.Contains(positioned.Position)) { toUpdate.Add(positioned); toPosition.Remove(positioned.Position); } else { Remove(positioned.Element); _availableLabels.Push(positioned.Element); toRemove.Add(positioned); } } toRemove.ForEach(r => _visibleLabels.Remove(r)); // Position new labels. var toInitialize = new List <PositionedElement>(); foreach (var position in toPosition) { // Create a new label when needed, or retrieve existing one. FrameworkElement toPlace; if (_availableLabels.Count == 0) { toPlace = CreateLabel(); toPlace.CacheMode = new BitmapCache(); } else { toPlace = _availableLabels.Pop(); } toPlace.SetValue(AxesPanel <TX, TXSize, TY, TYSize> .XProperty, position.Item1); toPlace.SetValue(AxesPanel <TX, TXSize, TY, TYSize> .YProperty, position.Item2); Add(toPlace); var positioned = new PositionedElement(toPlace, position); _visibleLabels.Add(positioned); toInitialize.Add(positioned); } // Only update and initialize labels at end, so that _visibleLabels is up to date. toInitialize.ForEach(i => InitializeLabel(i, visible, panelSize)); toUpdate.ForEach(u => UpdateLabel(u, visible, panelSize)); }