コード例 #1
0
        /// <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));
        }
コード例 #2
0
        /// <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));
        }
コード例 #3
0
        public override void LabelResized(FrameworkElement label, AxesIntervals <TX, TXSize, TY, TYSize> visible, Size panelSize)
        {
            // TODO: Can this be handled locally within this class, rather than relying on a callback from AxesPanel?
            //       Main problems seems to be 'visible' and 'panelSize' are needed to update.
            var positioned = _visibleLabels.FirstOrDefault(v => v.Element == label);

            if (positioned != null)
            {
                UpdateLabel(positioned, visible, panelSize);
            }
        }
コード例 #4
0
        protected override IEnumerable <Tuple <TX, TY> > GetPositions(AxesIntervals <TX, TXSize, TY, TYSize> intervals, Size panelSize)
        {
            // When not enough pixels in between labels, do not show any labels.
            double pixelsBetween = SizeToPixels(MaximumLabelSize, intervals, panelSize);

            if (pixelsBetween < MinimumPixelsBetweenLabels)
            {
                MinimumPixelsExceeded = true;
                return(new Tuple <TX, TY>[] { });
            }

            MinimumPixelsExceeded = false;
            return(GetXValues(intervals).Select(x => new Tuple <TX, TY>(x, FixedY)));
        }
コード例 #5
0
 protected override Tuple <TXSize, TYSize> GetMaximumLabelSize(AxesIntervals <TX, TXSize, TY, TYSize> visible)
 {
     return(new Tuple <TXSize, TYSize>(MaximumLabelSize, default(TYSize)));
 }
コード例 #6
0
 /// <summary>
 ///   Returns all x positions on which to place labels within the specified interval.
 /// </summary>
 /// <param name="intervals">The currently visible interval.</param>
 protected abstract IEnumerable <TX> GetXValues(AxesIntervals <TX, TXSize, TY, TYSize> intervals);
 protected override IEnumerable <TX> GetXValues(AxesIntervals <TX, TXSize, TY, TYSize> intervals)
 {
     return(intervals.IntervalX.GetValues(StepSize, Anchor));
 }
コード例 #8
0
 /// <summary>
 ///   Called whenever a label added by the collection was resized.
 ///   When you position labels within a collection based on their size, this callback can be used to update their position.
 /// </summary>
 /// <param name="label">The label which was resized.</param>
 /// <param name="visible">The visible interval.</param>
 /// <param name="panelSize">The size within which the intervals are presented.</param>
 public abstract void LabelResized(FrameworkElement label, AxesIntervals <TX, TXSize, TY, TYSize> visible, Size panelSize);
コード例 #9
0
 /// <summary>
 ///   Called whenever either the visible interval has changed, or the size within which it is presented has changed.
 /// </summary>
 /// <param name="visible">The visible interval.</param>
 /// <param name="limits">The maximum ranges within which all values must lie.</param>
 /// <param name="panelSize">The size within which the intervals are presented.</param>
 public abstract void VisibleIntervalChanged(
     AxesIntervals <TX, TXSize, TY, TYSize> visible,
     AxesIntervals <TX, TXSize, TY, TYSize> limits,
     Size panelSize);
コード例 #10
0
        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));
        }
コード例 #11
0
 /// <summary>
 ///   Called for already positioned elements which might potentionally need to be updated based on a new visible interval.
 /// </summary>
 protected abstract void UpdateLabel(PositionedElement label, AxesIntervals <TX, TXSize, TY, TYSize> visible, Size panelSize);
コード例 #12
0
 /// <summary>
 ///   Initializes a label which has just been repositioned to a certain position.
 /// </summary>
 protected abstract void InitializeLabel(PositionedElement positioned, AxesIntervals <TX, TXSize, TY, TYSize> visible, Size panelSize);
コード例 #13
0
 /// <summary>
 ///   Returns all positions on which to place labels within the specified interval.
 /// </summary>
 protected abstract IEnumerable <Tuple <TX, TY> > GetPositions(AxesIntervals <TX, TXSize, TY, TYSize> intervals, Size panelSize);
コード例 #14
0
 /// <summary>
 ///   Returns the maximum size a label can have given specified visible intervals.
 /// </summary>
 protected abstract Tuple <TXSize, TYSize> GetMaximumLabelSize(AxesIntervals <TX, TXSize, TY, TYSize> visible);