SChartTickLabelFormatter subclass methods never called


#1

Hi guys, I’m trying to update a project that used ShinobiCharts 2.1 to the 2.3 release, and I cannot get my axis label formatters to work correctly. 

TBDCategorisedDatesTickLabelFormatter *xAxisLabelFormatter = [[TBDCategorisedDatesTickLabelFormatteralloc] init];
 chart.xAxis.labelFormatter = xAxisLabelFormatter;

There’s nothing special about my label formatter. I’ve set a breakpoint on the stringForObjectValue:onAxis: method on both SChartTickLabelFormatter and my subclass, and it is only ever breaking for your SChartTickLabelFormatter class.

I’ve placed an observer on the axis’ labelFormatter property, and it is only ever being set to my subclass. 

Any idea what’s going on here?


#2

Further to this, it looks like the x axis label formatter is reset somewhere outside of my control, after I set my custom formatter but before the chart is reloaded. Is this a known issue? Is there a workaround? 


#3

Hi Tony,

Sorry about the trouble you’re having - I’ve tried to reproduce your issue and my stringForObjectValue:onAxis: method is being called just fine. The class I’ve used is simply:

@interface MyFormatter : SChartTickLabelFormatter
@end
@implementation MyFormatter

-(NSString *)stringForObjectValue:(id)obj onAxis:(SChartAxis *)axis
{
    return [obj description];
}

@end

and my assignment:

chart.xAxis = [[[SChartDateTimeAxis alloc] init] autorelease];

chart.xAxis.labelFormatter = [[MyFormatter new] autorelease];

If you reduce your code to this, do you still see the problem? Either way, are you able to provide any code which will reproduce it?
Are you able to provide a stack trace when the formatter is reset? This might indicate to us where abouts in our code the issue is occuring.

Best regards,
Rob


#4

I don’t believe I’m triggering this directly. Here’s the backtrace that occurs after I’ve done all my setup of this axis:

(lldb) bt
* thread #1: tid = 0x58668, 0x001c2f0a The iOS App`-[SChartAxis setLabelFormatter:], queue = 'com.apple.main-thread, stop reason = breakpoint 4.1
    frame #0: 0x001c2f0a The iOS App`-[SChartAxis setLabelFormatter:]
    frame #1: 0x001c766a The iOS App`-[SChartNumberAxis setDefaults] + 385
    frame #2: 0x001c7723 The iOS App`-[SChartNumberAxis init] + 74
    frame #3: 0x01da288d libobjc.A.dylib`+[NSObject new] + 52
    frame #4: 0x001c28dd The iOS App`-[SChartAxis stubCopyOfAxisForDataLoading] + 54
    frame #5: 0x0020334b The iOS App`-[ShinobiChart loadNewChartSeriesEntries] + 628
    frame #6: 0x0020a046 The iOS App`-[ShinobiChart layoutSubviews] + 2608
    frame #7: 0x00d472dd UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 279
    frame #8: 0x01da26b0 libobjc.A.dylib`-[NSObject performSelector:withObject:] + 70
    frame #9: 0x00ba3fc0 QuartzCore`-[CALayer layoutSublayers] + 240
    frame #10: 0x00b9833c QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 468
    frame #11: 0x00b98150 QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 26
    frame #12: 0x00b160bc QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 324
    frame #13: 0x00b17227 QuartzCore`CA::Transaction::commit() + 395
    frame #14: 0x00b178e2 QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 96
    frame #15: 0x01f31afe CoreFoundation` __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
    frame #16: 0x01f31a3d CoreFoundation`__CFRunLoopDoObservers + 381
    frame #17: 0x01f0f7c2 CoreFoundation`__CFRunLoopRun + 1106
    frame #18: 0x01f0ef44 CoreFoundation`CFRunLoopRunSpecific + 276
    frame #19: 0x01f0ee1b CoreFoundation`CFRunLoopRunInMode + 123
    frame #20: 0x02e947e3 GraphicsServices`GSEventRunModal + 88
    frame #21: 0x02e94668 GraphicsServices`GSEventRun + 104
    frame #22: 0x00cf6ffc UIKit`UIApplicationMain + 1211
    frame #23: 0x000057ed The iOS App`main(argc=1, argv=0xbffff098) + 141 at main.m:16

#5

Hi Tony,

It looks like this may be an issue with our background data loading, however the backtrace that you’ve posted shouldn’t be relevant - we use a stub-axis to load the data, and then we throw away this axis, so the label formatter you’re seeing is just a default one created by the stub axis. This default formatter isn’t copied back to the chart’s actual axes and should be discarded. Are there any other situations where the label formatter is replaced?

Best regards,

Rob


#6

No, it doesn’t seem that there is (outside of where I explicitly set it myself).

I only set the label for the x axis in one class in my app, in one specific method that is called after the datasource and delegate have been changed. The custom label formatter is initialised, but never called.

Are there specific preconditions for -stringForObjectValue:onAxis: being called? Can you get someone to check this in ShinobiCharts’ code and let me know?


#7

Further to this: even creating a simple SChartTickLabelFormatter on my SChartCategoryAxis and changing the default NSDateFormatter does nothing at all.


#8

This might be relevant: I’m seeing this printed to my console when the app first starts: “No primary x-axis to customize.” 

Unrelated to my query: Why is this being logged by your framework through my app? If it’s relevant to me as a developer, you should pass me an NSError or throw an NSException and let me handle it appropriately. I get that Objective-C/Cocoa might not be your primary focus with all the C# love going on for your libraries, but things like this and the earlier issues I reported where the framework called abort() on errors (!!!) make me worried that there are deeper issues here. 


#9

Hi Tony,

That message will be your problem - you’re setting the label formatter on a nil object / before the chart has an xAxis. Regarding the chart error handling, this is a known issue which we are gradually addressing in the charts, and we’re moving towards a more library-oriented design, using exceptions.

Best regards,

Rob


#10

Thanks Rob, but I’m not sure that’s my issue. Here’s what I call after I’ve set my datasource and delegate:


#11

Hey Tony,

I’ve sent you an email  :grin:

Simon

Edit: Also deleted your double-post for you!


#12

Just for anyone else reading - this has been fixed in the next release, but we have a work around if needed :slight_smile:


#13

Hi all,

Our new version of ShinobiCharts (version 2.5.5) is now out, which should fix this issue.

Many thanks,

Dan


#14

Has this been fixed? I am seeing very similar behavior. I have a simple bar chart but some of the labels on the xAxis are longer than others so I was hoping to resize the labels of a greater length. IE: make their font size smaller and wrap the text. I was hoping to accomplish this using the labelFormatter NSFormatter and overriding the attributed string return.


#15

Hi Stubiell,

This should have been fixed in version 2.5.5. Which version are you using?

If you are able to reproduce this issue in 2.5.5 or later then please let us know how to do so (either with some sample code or a stripped-down project), so that we can take a look and consider re-opening the issue.

Thanks

Ryan