I have two classes, GraphViewController and AppController. AppController (the delegate) implements the datasource protocol of GraphViewController. The problem I have is that those methods are not called by GraphViewController.
However, when I set the datasource of GraphViewController to self and leave the protocol methods in the GraphViewController (like in the CorePlot example provided with CorePlot) everything works fine without any reloadData or setNeedsDisplay methods called.
The problem is not the setup of the view. The theme and the axis are drawn fine, just the plot is missing.
None of the provided answers to very similar questions solved my particular problem. I guess (or hope) that it's just a small thing I'm missing, but I just can't find it.
See the source of the two classes below. Oh, and by the way: this is for OS-X not iOS.
GraphViewController.h:
#import <Cocoa/Cocoa.h>
#import <CorePlot/CorePlot.h>
@interface GraphViewController : NSObject{
IBOutlet CPTGraphHostingView *graphHostingViewOutlet;
CPTXYGraph *graph;
}
@property (weak) id<CPTPlotDataSource> delegate;
@end
GraphViewController.m:
#import "GraphViewController.h"
@implementation GraphViewController
@synthesize delegate;
-(void)awakeFromNib {
[super awakeFromNib];
// create graph
graph = [(CPTXYGraph *)[CPTXYGraph alloc] initWithFrame:CGRectZero];
// apply theme to graph
[graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
// connect graph to host view
graphHostingViewOutlet.hostedGraph = graph;
// get a pointer to the default plot space of the graph
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
// setup axes limits
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-0.2f) length:CPTDecimalFromFloat(1.2f)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(-0.2f) length:CPTDecimalFromFloat(1.2f)];
// get a pointer to the axis set of the graph
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
// get the x axis element of the axis set and set propertys for x axis
CPTXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPTDecimalFromFloat(0.2f);
// get the y axis element of the axis set and set propertys for y axis
CPTXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPTDecimalFromFloat(0.2f);
// create a new plot
CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];
// set the identifier for the plot
dataSourceLinePlot.identifier = @"ThePlot";
// set data source for plot
dataSourceLinePlot.dataSource = delegate;
// add the plot to the graph
[graph addPlot:dataSourceLinePlot];
}
@end
AppController.h:
#import <Foundation/Foundation.h>
#import "GraphViewController.h"
#import <CorePlot/CorePlot.h>
@interface AppController : NSObject <CPTPlotDataSource>
@property (weak) GraphViewController *graphViewController;
- (IBAction)doSomething:(id)sender; // connected to a button
@end
AppController.m:
#import "AppController.h"
@implementation AppController{
NSArray *_plotData;
}
@synthesize graphViewController = _graphViewController;
-(void)awakeFromNib {
[super awakeFromNib];
[_graphViewController setDelegate:self];
// create data array
NSMutableArray *newData = [NSMutableArray array];
for (NSUInteger i = 0; i < 20; i++ ) {
// create random y values
id y = [NSDecimalNumber numberWithFloat: rand() / (float)RAND_MAX];
[newData addObject: [NSDictionary dictionaryWithObjectsAndKeys:
[NSDecimalNumber numberWithFloat:0.05 * i], // x object
[NSNumber numberWithInt:CPTScatterPlotFieldX], // key
y, // y object
[NSNumber numberWithInt:CPTScatterPlotFieldY], // key
nil]];
} // end of for
_plotData = newData;
}
- (IBAction)doSomething:(id)sender{ // connected to a working button
NSLog(@"Button was pressed.");
// tell the graphViewController to reload its data from its delegate (me), but how?
// this does not work: [[NSNotificationCenter defaultCenter] postNotificationName:@"CPTGraphNeedsRedrawNotification" object:nil];
}
// implementation of delegate methods
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDecimalNumber *num = [[_plotData objectAtIndex:index] objectForKey:[NSNumber numberWithLongLong:fieldEnum]];
NSLog(@"numberForPlot was called, num is %@",num);
return num;
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
NSLog(@"numberForPlot was called.");
return _plotData.count;
}
@end
I hope the source I posted can serve as a simple prototype for others once the bug was found.