Search code examples
wpfdatetimewpf-controlsscichart

Limit zoom on DateTime axis


I am using SciChart with DateTimeAxis.

My items are starting from 15 May 2016 8:30 AM and ending on 25 May 2016 8:30 AM. Initial value of VisibleRange is set this this range as well. I have also added VisibleRangeLimit again with same range.

But the problem is that when I am scrolling to corners, date values are going out of my range and, as a result, on some zoom levels I see dates out of my allowed range, like 15 May 2016 8:25 AM. This is causing to blank are for 5 minutes.

Is there any way to really limit visible range?


Solution

  • Yes there is,

    From the Documentation: Clipping the Axis.VisibleRange on Zoom and Pan.

    Advanced VisibleRange Clipping and Manipulation

    Axis.VisibleRangeLimit is a useful API to ensure the axis clips the VisibleRange when zooming to extents. However, it will not stop a user from scrolling outside of that range. To achieve that, you need a small modification:

    Clipping Axis.VisibleRange in Code

    To clip the VisibleRange and force a certain maximum or minimum, just use the following code:

    axis.VisibleRangeChanged += (s, e) =>
    {
       // e is VisibleRangeChangedEventArgs
       // Assuming axis is NumericAxis
    
       if (e.NewVisibleRange != null && e.NewVisibleRange.Min < 0)
       {
          // Force minimum visiblerange to zero always
          ((NumericAxis)sender).VisibleRange = new DoubleRange(0, e.NewVisibleRange.Max);
       }
    };
    

    Clipping Axis.VisibleRange with MVVM

    The same can be achieved in MVVM by creating a custom behavior.

    public class AxisClippingBehavior : Behavior<AxisBase>
      {
        protected override void OnAttached()
        {
            base.OnAttached();
    
            AssociatedObject.VisibleRangeChanged +=OnVisibleRangeChanged;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
    
            AssociatedObject.VisibleRangeChanged -= OnVisibleRangeChanged;
        }
    
        private void OnVisibleRangeChanged(object sender, VisibleRangeChangedEventArgs visibleRangeChangedEventArgs)
        {
            var visibleRangeLimit = AssociatedObject.VisibleRangeLimit;
            if (visibleRangeLimit != null)
            {
                var limitMode = AssociatedObject.VisibleRangeLimitMode;
    
                var range = (IRange)AssociatedObject.VisibleRange.Clone();
                range.ClipTo(visibleRangeLimit, limitMode);
    
                AssociatedObject.SetCurrentValue(AxisBase.VisibleRangeProperty, range);
            }
        }
    }