SciChart iOS v2.x API > Axis APIs > Axis Ranging - Restricting VisibleRange
Axis Ranging - Restricting VisibleRange

Clipping the Axis VisibleRange on Zoom and Pan

SCIAxisBase VisibleRangeLimit

Given a chart with data in the range of 0:10, when you zoom to extents, the axis will have a VisibleRange of 0:10. Sometimes this is not desirable, and you want to clip the axis.visibleRange inside the data-range.
To do this, you can use the axis.visibleRangeLimit property.

For example. Given an axis without any limits (axis.visibleRangeLimit = nil). When we perform ZoomExtents on the chart, the XAxis gets the visible range (0;10):

Actual XAxis data range = (0:10) ; XAxis.VisibleRangeLimit = nil; XAxis.VisibleRange after ZoomExtents = (0:10)

After setting XAxis.visibleRangeLimit = (1:9) and using ZoomExtents we now get an XAxis.visibleRange = (1:9). In other words, zooming has clipped or limited the visibleRange to (1:9)

NOTE:  VisibleRangeLimit does not clip data range when VisibleRangeLimit is greater than data range. In this case after ZoomExtents you’ll get the actual data range.

 

Actual data range = (0:10); XAxis.VisibleRange = (1:9); XAxis.VisibleRange after ZoomExtents = (1:9)

 

Declaring an Axis VisibleRangeLimit

// VisibleRangeLimit expects a minimum and maximum value according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects SCIDoubleRange,
//  SCIDateTimeAxis expects SCIDateRange,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect SCIIndexRange
//
// SCIGeneric is used to marshal between iOS types and faster SciChart primitive types
SCINumericAxis * axis = [[SCINumericAxis alloc] init];
[axis setVisibleRangeLimit:[[SCIDoubleRange alloc]initWithMin:SCIGeneric(1) Max:SCIGeneric(9)]];
// VisibleRangeLimit expects a minimu and maximum value according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects SCIDoubleRange,
//  SCIDateTimeAxis expects SCIDateRange,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect SCIIndexRange
//
// SCIGeneric is used to marshal between iOS types and faster SciChart primitive types
let axis = SCINumericAxis()
axis.visibleRangeLimit = SCIDoubleRange(min: SCIGeneric(1), max: SCIGeneric(9))
// VisibleRangeLimit expects a minimu and maximum value according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects SCIDoubleRange,
//  SCIDateTimeAxis expects SCIDateRange,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect SCIIndexRange
var axis = new SCINumericAxis();
axis.VisibleRangeLimit = new SCIDoubleRange(1, 9);

SCIAxisBase VisibleRangeLimitMode

Another property which can be used to change how the VisibleRangeLimit works is AxisBase VisibleRangeLimitMode.

Use this property if you wish to ensure that one side of the chart is always clipped, while the other side is not.

Results in a chart that always sets VisibleRange.Min = 0 when you zoom to extents.

NOTE:  VisibleRangeLimit does not clip data range when VisibleRangeLimit is greater than data range. In this case after ZoomExtents you’ll get the actual data range.

 

Advanced VisibleRange Clipping

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. 

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

// Register a VisibleRangeChanged callback
SCICallbackHelper * helper = [axis registerVisibleRangeChangedCallback:
                ^(id<SCIRangeProtocol> newRange, id<SCIRangeProtocol> oldRange, BOOL isAnimated, id sender){
                            // Set the old range back on the axis if the new range.Min is less than 0
                            if (SCIGenericDouble(newRange.min) < 0.0) {
                                axis.visibleRange = oldRange;
                            }
                     }];
    
// When finished, unsubscribe to the callback
[helper remove];
// Register a VisibleRangeChanged callback
var helper2: SCICallbackHelper? = axis.registerVisibleRangeChangedCallback({(_ newRange: SCIRangeProtocol, _ oldRange: SCIRangeProtocol, _ isAnimated: Bool, _ sender: Any) -> Void in
        // Set the old range back on the axis if the new range.Min is less than 0
        if SCIGenericDouble(newRange.min) < 0.0 {
            axis.visibleRange = oldRange
        }
    })

// When finished, unsubscribe to the callback
helper2?.remove()
// Register a VisibleRangeChanged callback
var helper = axis.RegisterVisibleRangeChangedCallback((newRange, oldRange, isAnimated, sender) =>
{
    if (newRange.Min_native.doubleData < 0.0)
    {
        axis.VisibleRange = oldRange;
    }               
});

// When finished, unsubscribe to the callback
helper.Remove();
helper.Dispose();

 

Specifying a Minimum Zoom Level

If you want to constrain zoom depth in your application, the Axis.MinimalZoomConstrain property allows you to constrain changing of axis VisibleRange if its VisibleRange.Diff value is too small.

When you use MinimalZoomConstain you define minimal difference between Min and Max of VisibleRange and if this difference < MinimalZoomConstrain then VisibleRange will not change.

// MinimalZoomConstrain expects a value type according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects double,
//  SCIDateTimeAxis expects NSDate,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect an integer value
//
// SCIGeneric is used to marshal between iOS types and faster SciChart primitive types
SCINumericAxis * axis = [[SCINumericAxis alloc] init];
axis.minimalZoomConstrain = SCIGeneric(0.1);
// MinimalZoomConstrain expects a value type according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects double,
//  SCIDateTimeAxis expects NSDate,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect an integer value
//
// SCIGeneric is used to marshal between iOS types and faster SciChart primitive types
let axis = SCINumericAxis()
axis.minimalZoomConstrain = SCIGeneric(0.1);
// MinimalZoomConstrain expects a value type according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects double,
//  SCIDateTimeAxis expects DateTime,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect an integer value
var axis = new SCINumericAxis();
axis.MinimalZoomConstrain = 0.1;

 

Specifying a Maximum Zoom Level

If you want to constrain zoom depth in your application, the Axis.MaximalZoomConstrain property allows you to constrain changing of axis VisibleRange if its VisibleRange.Diff value is too large.

When you use MaximalZoomConstrain you define maximum difference between Min and Max of VisibleRange and if this difference > MaximalZoomConstrain then VisibleRange will not change.

// MaximalZoomConstrain expects a value type according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects double,
//  SCIDateTimeAxis expects NSDate,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect an integer value
//
// SCIGeneric is used to marshal between iOS types and faster SciChart primitive types
SCINumericAxis * axis = [[SCINumericAxis alloc] init];
axis.maximalZoomConstrain = SCIGeneric(10000);
// MaximalZoomConstrain expects a value type according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects double,
//  SCIDateTimeAxis expects NSDate,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect an integer value
//
// SCIGeneric is used to marshal between iOS types and faster SciChart primitive types
let axis = SCINumericAxis()
axis.maximalZoomConstrain = SCIGeneric(10000);
// MaximalZoomConstrain expects a value type according to the axis VisibleRange type
//
// e.g. SCINumericAxis expects double,
//  SCIDateTimeAxis expects DateTime,
//  SCICategoryNumericAxis and SCICategoryDateTimeAxis expect an integer value
var axis = new SCINumericAxis();
axis.MinimalZoomConstrain = 10000;

 

See Also