Swift - sChartDidStartZooming is deprecated - how to limit zoom?


#1

Hi,

the sChartDidStartZooming method has been deprecated in the swift API.

I understand that I am supposed to use the following API " func sChart(_ chart: ShinobiChart, didAlterRangeOn axis: SChartAxis) "

However, with a discontinuous xAxis, this method is producing rather weird results where the zoom values and the range values jump about as you pan. This is making it rather difficult to detect whether the user is panning or zooming.

Does anyone have any suggestions how to implement a zoom limit on the X Axis which doesn’t limit panning?


#2

Hi wardy,

I’m guessing what’s happening here is that you’re checking whether the axis’s span (i.e. the difference between the maximum and minimum properties of the range) has changed, before taking action. So the issue is that depending on how many skips are in the current range, that span changes while the user is panning, so you can’t detect whether the range change is a pan or a zoom.

What you can do instead is look at the zoom property on the axis instead, as it isn’t affected by skips.

As an illustration, here’s some example logging from sChart:didAlterRangeOnAxis whilst panning over a skip between 12 and 13 on the x-axis:

Range { 11.944556, 14.020023 }, span 2.075467, zoom 13.017601 Range { 11.943089, 14.018556 }, span 2.075467, zoom 13.017601 Range { 11.932085, 14.007552 }, span 2.075467, zoom 13.017601 Range { 11.921081, 12.996548 }, span 1.075467, zoom 13.017601 Range { 11.920347, 12.995814 }, span 1.075467, zoom 13.017601 Range { 11.918880, 12.994347 }, span 1.075467, zoom 13.017601

You can see that though the span (based on the range) changes as the skip goes out of range, the zoom remains constant.

I hope this helps you to implement your zoom limit.

Kind regards,

Alison


#3

Hi Alison,
thank you for your response.

What is compounding the issue, is that the zoom is also changing occasionally. It switches to 1 and then back to the new zoom value. This doesn’t happen every time, but is happening occasionally on a pan and frequently on a zoom.

Cheers.


#4

Hi wardy,

Thanks for the update.

Is there a possibility that the zoom level of 1 is happening when the chart is reloading data, or could the range be being reset elsewhere in your code?

If not, and if it’s something you can reproduce in one of our sample apps, then we’ll investigate further to see if there’s a bug in the library.

Alison


#5

Hi Alison,

thank you again for your response. I have inherited this project, so still becoming familiar with the code. I have found where the range was being modified - each time a zoom was “allowed”.

I have commented this line out - is there a property I need to set / method I need to call in order to prevent further zooming?

The code was using “self.chart.xAxis?.setRange(lastRangeX, withAnimation: true)” to set a new range upon zooming - this is causing the jumping in values. Without this though, it’s possible for the user to keep zooming in. So how do I prevent that?


#6

Hi wardy,

Before we go any further: I’m assuming you’re using a date time axis so you can’t make use of zoomInLimit and zoomOutLimit on SChartNumberAxis?

We have logged a feature request to add zoom limits to other axis types, but we don’t currently have an estimate on when it might be implemented.

In terms of your current issue, I think what may be happening is that using the new method, when you call setRange(lastRangeX, withAnimation: true), the sChart:didAlterRangeOnAxis: method is called for each frame of the animation, with a range that is still larger than the one allowed, which will then make repeated calls to setRange. I would suggest setting a flag before calling setRange, to prevent repeated calls, and resetting the flag from sChart:didFinishAnimatingAxis:.

[Edit: the simplest way to check whether this is what’s happening is to change the withAnimation parameter to false, which should remove the repeated calls.]

If you can’t get this working feel free to send over your delegate code to info@shinobicontrols.com and we’ll take a look in more detail.

Kind regards,

Alison


#7

Hi Alison,
I’ll email you - we are indeed using a date time axis. The suggested solution didn’t work - my information was slightly wrong too. We are setting the range upon hitting the “zoom limit” we have attempted to set in code.


#8

@wardy has managed to fix the issue, so I’m giving an update here in case it helps anyone else.

Here’s what I believe was the final solution:

  • Use zoom instead of span when calculating the limit, to take account of the discontinuities in the axis.
  • Keep track of the current zoom level and last valid range in class level variables.
  • Keep track of the current animation state in a class level variable, and implement didFinishAnimating to update it.
  • In sChart:didAlterRangeOnAxis:, use the variables to see whether animation has finished and whether the zoom level has changed, to work out whether the user is panning or zooming, and if they are zooming past the limit, call setRange:withAnimation to reset the range to the last valid one.