Android: Crash - Chart must have an X Axis and a Y Axis to draw a Series


#1

I’m getting this crash and I’ve been unable to figure out where I might have a Chart with no X-axis or Y-axis.  Most of the time the chart is displaying as expected.  Do you have any ideas?

FATAL EXCEPTION: GLThread 608
    java.lang.IllegalStateException: Chart must have an X Axis and a Y Axis to draw a Series.
            at com.shinobicontrols.charts.u.a(SourceFile:22)
            at com.shinobicontrols.charts.y.onDrawFrame(SourceFile:121)
            at com.shinobicontrols.charts.GLTextureView$f.l(SourceFile:1609)
            at com.shinobicontrols.charts.GLTextureView$f.run(SourceFile:1310)

Thanks,


Android - ConcurrentModificationException
#2

Hello,

Has someone from Shinobi been able to look at this issue?  We would like to deploy Shinobi Charts to our customers in a few weeks, but I’m uncomfortable doing this until we can resolve this crash.

Thanks!


#3

Hello aderington,

Thanks for getting in touch. Which version of ShinobiCharts for Android are you using please? Which flavour (trial, standard, premium)?

We look forward to hearing from you.

Thanks,

Kai.


#4

I am using Premium 1.5.0 version of ShinobiCharts


#5

Hello aderington,

Thank you for the extra information.

The internal code that throws this exception is fairly simple and clear cut. As such it suggests that somewhere in your application one or more axes are inadvertently being removed just before a draw. 

May I ask, are you dynamically adding or removing axes in your code? Perhaps you are swapping axes out? Are you dynamically adding data to your series? If for example a new data point is added to a DataAdapter then a draw will take place. Configuration changes (such as rotating the device) can also trigger a redraw. If at the same time an axis was swapped out, there could be an issue similar to what you experience.

Could you please advise if your code does any dynamic data loading or axes swapping as I’ve mentioned?

I look forward to hearing from you,

Thanks,

Kai.


#6

I am updating the axes during runtime, but at no time are either axis null.  The only reason I am updating my axes during runtime is because the default range of the axis does not seem to update correctly if the ranges are very different from the initial range used during the construction of the axis.

Two of my charts can have wildly different ranges for their Y-axis.

Do you know why updating the default range does not seem to update correctly?

As for the swapping of the axes, I’m using the setXaxis and setYAxis methods.  I tried to do an addAxis and then remove the old axis, but that crashed even faster.

Any help would be greatly appreciated!!


#7

Also, all of my updates are performed on the main UI thread.


#8

Hi aderington,

Thanks for the contact.

If you are wanting to change the visible data range of your axes (presumably as data points are dynamically added or removed from your DataAdapters) you should not need to swap out any axes. 

If you set the default range on your axis before data is loaded it should honour that range upon the redraw following the data load. The axes should also display the default range when the zoom is reset (for example when you zoom out beyond the internal limits, the chart will animate back to its default range). 

Generally, if you wish to have the visible ranges update after your data has been loaded (as in the event of continuous dynamic updating) we recommend you use the requestCurrentDisplayedRange method on the Axis class:

http://www.shinobicontrols.com/docs/ShinobiControls/ShinobiChartsAndroid/1.5.1/Premium/Normal/apidocs/docs/reference/com/shinobicontrols/charts/Axis.html#requestCurrentDisplayedRange(T, T, boolean, boolean)

This method will honour the requested range providing that in doing so it does not violate any restrictions which have been placed on the visible ranges. For example, if allowPanningOutOfDefaultRange has been set to false, and you request a range beyond this, it will not be honoured. 

I would recommend that rather than dynamically swapping out axes you use this approach. By using this approach you may well find that your concurrency problems evaporate.

I hope that this information helps you, if you need any further help please do not hesitate to get back in touch,

Thanks and kind regards,

Kai