I am following the tutorial here about core plot here....
http://www.switchonthecode.com/tutorials/using-core-plot-in-an-iphone-application
I am getting errors with the following lines of code
//SAYING INCOMPATIBLE TYPE FOR AURGUMENT 1 'setMajorIntervalLength'
axisSet.xAxis.majorIntervalLength = [NSDecimalNumber decimalNumberWithString:#"5"];
// request for member 'axisLabelOffset' in something not a structure or union
axisSet.xAxis.axisLabelOffset = 3.0f;
//request for member 'bounds' in something not a structure or union
CPScatterPlot *xSquaredPlot = [[[CPScatterPlot alloc] initWithFrame:graph.defaultPlotSpace.bounds] autorelease];
Here is my code now I am not getting any compiler errors anymore but its crashing and not loading the view please take a look if you can
#implementation FirstCorePlotViewController
(void)viewDidLoad
{
[super viewDidLoad];
graph = [[CPXYGraph alloc] initWithFrame: self.view.bounds];
CPLayerHostingView *hostingView = (CPLayerHostingView *)self.view;
hostingView.hostedLayer = graph;
graph.paddingLeft = 20.0;
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 20.0;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-6)
length:CPDecimalFromFloat(12)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-5)
length:CPDecimalFromFloat(30)];
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPLineStyle *lineStyle = [CPLineStyle lineStyle];
lineStyle.lineColor = [CPColor blackColor];
lineStyle.lineWidth = 2.0f;
axisSet.xAxis.majorIntervalLength =CPDecimalFromString(#"5");
axisSet.xAxis.minorTicksPerInterval = 4;
axisSet.xAxis.majorTickLineStyle = lineStyle;
axisSet.xAxis.minorTickLineStyle = lineStyle;
axisSet.xAxis.axisLineStyle = lineStyle;
axisSet.xAxis.minorTickLength = 5.0f;
axisSet.xAxis.majorTickLength = 7.0f;
axisSet.xAxis.labelOffset = 3.0f;
axisSet.yAxis.majorIntervalLength = CPDecimalFromString(#"5");
axisSet.yAxis.minorTicksPerInterval = 4;
axisSet.yAxis.majorTickLineStyle = lineStyle;
axisSet.yAxis.minorTickLineStyle = lineStyle;
axisSet.yAxis.axisLineStyle = lineStyle;
axisSet.yAxis.minorTickLength = 5.0f;
axisSet.yAxis.majorTickLength = 7.0f;
axisSet.yAxis.labelOffset = 3.0f;
CPScatterPlot *xSquaredPlot = [[(CPScatterPlot *)[CPScatterPlot alloc] initWithFrame:graph.bounds] autorelease];
xSquaredPlot.identifier = #"X Squared Plot";
xSquaredPlot.dataLineStyle.lineWidth = 1.0f;
xSquaredPlot.dataLineStyle.lineColor = [CPColor redColor];
xSquaredPlot.dataSource = self;
[graph addPlot:xSquaredPlot];
CPPlotSymbol *greenCirclePlotSymbol = [CPPlotSymbol ellipsePlotSymbol];
greenCirclePlotSymbol.fill = [CPFill fillWithColor:[CPColor greenColor]];
greenCirclePlotSymbol.size = CGSizeMake(2.0, 2.0);
//xSquaredPlot.defaultPlotSymbol = greenCirclePlotSymbol;
CPScatterPlot *xInversePlot = [[(CPScatterPlot *)[CPScatterPlot alloc] initWithFrame:graph.bounds] autorelease];
xInversePlot.identifier = #"X Inverse Plot";
xInversePlot.dataLineStyle.lineWidth = 1.0f;
xInversePlot.dataLineStyle.lineColor = [CPColor blueColor];
xInversePlot.dataSource = self;
[graph addPlot:xInversePlot];
}
-(NSUInteger)numberOfRecords
{
return 51;
}
-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum
recordIndex:(NSUInteger)index
{
double val = (index/5.0)-5;
if(fieldEnum == CPScatterPlotFieldX)
{
return [NSNumber numberWithDouble:val];
}
else
{
if(plot.identifier == #"X Squared Plot")
{
return [NSNumber numberWithDouble:val*val];
}
else
{
return [NSNumber numberWithDouble:1/val];
}
}
}
#end
None of these errors are caused by #import problems. That tutorial is known to be somewhat out of date and some parts of the Core Plot framework have changed.
The majorIntervalLength property expects an NSDecimal, not NSDecimalNumer. Core Plot includes several utility functions that convert other types to NSDecimal such as CPDecimalFromString and CPDecimalFromDouble.
axisSet.xAxis.majorIntervalLength = CPDecimalFromString(#"5");
The axisLabelOffset property has been renamed to labelOffset.
The third error is caused by two things. Both UIView and CPLayer (the root class for all Core Plot layers) having an -initWithFrame: method. Because -alloc returns an id, the compiler doesn't know which -initWithFrame: to use and sometimes guesses wrong. You can fix it with a typecast. Also, plot spaces are not layers; just get the bounds of the graph.
CPScatterPlot *xSquaredPlot = [[(CPScatterPlot *)[CPScatterPlot alloc] initWithFrame:graph.bounds] autorelease];
// request for member 'axisLabelOffset' in something not a structure or union
... means that the complier doesn't recognize the name provided in the dot syntax as belonging to the object. Typos are a common cause of this error. Another is not properly importing the header for class preceding the dot.
//SAYING INCOMPATIBLE TYPE FOR AURGUMENT 1 'setMajorIntervalLength'
This means that the property majorIntervalLength does not take a NSDecimalNumber.
I'm going to say that all your problems are caused by problems with #import statements. You not importing headers where you should be and the complier doesn't understand what symbol goes with which class.
There is a divide by zero error in your -numberForPlot:field:recordIndex: method. When index == 25, the statement 1/val will blow up.
Follow this Tute
This Ray's tutorial is really helpful.
Related
hi i am creating a graph using core plot, i want to change line style for major and minor line ,line style is changed but we have two major line top and bottom line in core plot how to remove top major line
- (void) setupGraphAxis: (CPTXYGraph *) graph {
CPTColor *axisColor = [CPTColor colorWithComponentRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:0.75];
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 1.5f;
axisLineStyle.lineColor = axisColor;
CPTMutableLineStyle *dashLineStyle = [CPTMutableLineStyle lineStyle];
dashLineStyle.lineColor = axisColor;
dashLineStyle.lineWidth = 1.5f;
dashLineStyle.dashPattern = [NSArray arrayWithObjects:[NSDecimalNumber numberWithInt:1],[NSDecimalNumber numberWithInt:2],nil];
dashLineStyle.patternPhase = 0.0f;
CPTMutableLineStyle *fullLineStyle = [CPTMutableLineStyle lineStyle];
fullLineStyle.lineColor = axisColor;
fullLineStyle.lineWidth = 1.5f;
//fullLineStyle.dashPattern = [NSArray arrayWithObjects:[NSDecimalNumber numberWithInt:1],nil];
fullLineStyle.lineCap = 0;
fullLineStyle.patternPhase = 0.0f;
//Configure x-axis
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.axisLineStyle = nil;
x.orthogonalCoordinateDecimal = CPTDecimalFromString(#"0");
x.minorTickLineStyle = nil;
x.majorTickLineStyle = nil;
CPTAxisLabelingPolicy policy = CPTAxisLabelingPolicyAutomatic;
x.labelingPolicy = policy;
x.labelTextStyle = nil;
x.preferredNumberOfMajorTicks = 1;
CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = nil;
y.orthogonalCoordinateDecimal = CPTDecimalFromString(#"0");
y.minorTickLineStyle = nil;
y.majorTickLineStyle = nil;
y.majorGridLineStyle = fullLineStyle;
y.minorGridLineStyle = dashLineStyle;
y.labelingPolicy = policy;
y.preferredNumberOfMajorTicks = 1;
}
You can use the labelExclusionRanges property of the axis to tell it to skip over certain values when creating ticks, grid lines, and labels. If you still want ticks and/or labels at that point, you might need to add another invisible y-axis that only draws the grid lines and let the original y-axis draw everything else.
I encountered a problem when using a custom label in Core Plot:
My Core Plot supports zoom.
The x-axis label is custom x.axisLabels
On first load, the interface is normal, but when I narrow Core Plot, the axis labels overlap together.
How to design a level on the label? For example, when the minimum level only shows a year, in level display date, the maximum level shows the date.
- (void)initPlotGraph
{
graph = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
self.hostedGraph = graph;
locationLabels = [[NSMutableArray alloc]init];
graph.plotAreaFrame.paddingLeft += 5.0;
graph.plotAreaFrame.paddingTop += 5.0;
graph.plotAreaFrame.paddingRight += 5.0;
graph.plotAreaFrame.paddingBottom += 17.5;
//[self setAllowPinchScaling:NO];
// Setup scatter plot space
plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.delegate = self;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0)length:CPTDecimalFromFloat(1+0.3)];
plotSpace.globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0)length:CPTDecimalFromFloat(1+0.3)];
[self initPlotAxis];
}
- (void)initPlotAxis
{
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2;
axisLineStyle.lineColor = [CPTColor colorWithComponentRed:CPTFloat(0.11765) green:CPTFloat(0.49804) blue:CPTFloat(0.87451) alpha:CPTFloat(1)];
CPTMutableLineStyle *axisTickLineStyle = [CPTMutableLineStyle lineStyle];
axisTickLineStyle.lineWidth = 0;
CPTLineCap *lineCap = [CPTLineCap sweptArrowPlotLineCap];
lineCap.size = CGSizeMake(10, 10);
lineCap.lineCapType = CPTLineCapTypeNone;
// Axes
// Label x axis with a fixed interval policy
lineCap.lineStyle = axisLineStyle;
lineCap.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:CPTFloat(0.29019) green:CPTFloat(0.54118) blue:CPTFloat(0.76471) alpha:CPTFloat(1)]];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPTDecimalFromInt(1);
x.axisLineStyle = axisLineStyle;
x.axisConstraints = [CPTConstraints constraintWithRelativeOffset:0];
x.axisLineCapMax = lineCap;
x.axisLabels = [self buildLabelTitle];
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.minorTickLocations = [NSSet setWithArray:locationLabels];
// Label y with an automatic label policy.
lineCap.lineStyle = axisLineStyle;
lineCap.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:CPTFloat(0.29019) green:CPTFloat(0.54118) blue:CPTFloat(0.76471) alpha:CPTFloat(1)]];
CPTXYAxis *y = axisSet.yAxis;
// y.majorIntervalLength = CPTDecimalFromDouble(5);
y.majorTickLineStyle = axisTickLineStyle;
y.minorTickLineStyle = axisTickLineStyle;
y.axisLineStyle = axisLineStyle;
y.axisLineCapMax = lineCap;
y.axisConstraints = [CPTConstraints constraintWithRelativeOffset:0];
// Set axes
graph.axisSet.axes = [NSArray arrayWithObjects:x, y, nil];
}
- (NSMutableSet*)buildLabelTitle
{
NSMutableSet *newAxisLabels = [NSMutableSet set];
CPTMutableTextStyle *textStyleB = [CPTMutableTextStyle textStyle];
textStyleB.color = [CPTColor colorWithComponentRed:CPTFloat((float)0x09/0xFF) green:CPTFloat((float)0x31/0xFF) blue:CPTFloat((float)0x4A/0xFF) alpha:CPTFloat(1)];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(corePlotNums - 9)length:CPTDecimalFromInt(10)];
plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(corePlotNums + 1)];
for ( NSUInteger i = 1; i < corePlotNums + 1; i++)
{
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText:[[m_labelStr objectAtIndex:i-1] substringWithRange:NSMakeRange(5, 11)] textStyle:textStyleB];
newLabel.tickLocation = CPTDecimalFromUnsignedInteger(i);
newLabel.offset = 5;
[newAxisLabels addObject:newLabel];
[newLabel release];
}
return newAxisLabels;
}
If the user is allowed to change the plot ranges (i.e., by pinch zooming), use a plot space delegate to monitor changes to the plot space. Use the new plot ranges and the size of the plot area to determine what time scale to use and how many labels to display. Adjust the axis labeling properties as needed.
Am breaking my head on this since yesterday and can't get it to work! All I get is a plain x-axis line, y-axis line (not even the ticks or labels!) and chart title! Please help! Seems so simple, but so elusive!
Am plotting the last 5 values of memory usage of a server. The values are for each minute approximately (sometimes, it's for two minutes once). For example, one set of last 5 values I might want to show is like this:
Date (vs) Memory Usage (bytes)
2013-05-02 11:50:33 +0000 - 157888512.000000
2013-05-02 11:51:33 +0000 - 157839360.000000
2013-05-02 11:52:14 +0000 - 157888512.000000
2013-05-02 11:56:36 +0000 - 157863936.000000
2013-05-02 11:57:48 +0000 - 157888512.000000
I refresh this graph every minute.
The 'numberForPlot', 'numberOfRecordsForPlot' seems to get called, but no plotting is seen/visible in the graph.
My graph is initialized with this method :
-(void) initializeGraph {
NSLog(#"View_Visualizer.initializeGraph");
if ((self.graph == nil) || (self.graph == NULL)) {
self.graphHostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:self.view.bounds];
self.graph = [[CPTXYGraph alloc] initWithFrame:self.graphHostView.bounds];
graph.paddingLeft = 10.0;
graph.paddingRight = 10.0;
graph.paddingTop = 10.0;
graph.paddingBottom = 10.0;
graph.title = #"Processor Usage";
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
NSTimeInterval xLow = 0.0f;
NSTimeInterval oneMin = 60.0f;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xLow)
length:CPTDecimalFromFloat(oneMin*6.0)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0)
length:CPTDecimalFromFloat(6)];
// plotting style is set to line plots
CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.lineColor = [CPTColor blackColor];
lineStyle.lineWidth = 2.0f;
NSTimeInterval oneMin = 60.0f;
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.graph.axisSet;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(oneMin);
axisSet.xAxis.minorTicksPerInterval = 0;
axisSet.xAxis.majorTickLineStyle = lineStyle;
axisSet.xAxis.majorTickLength = 7.0f;
//axisSet.yAxis.orthogonalCoordinateDecimal = CPTDecimalFromFloat(oneMin);
//axisSet.xAxis.majorTickLineStyle = lineStyle;
//axisSet.xAxis.minorTickLineStyle = lineStyle;
//axisSet.xAxis.axisLineStyle = lineStyle;
//axisSet.xAxis.minorTickLength = 5.0f;
//axisSet.xAxis.majorTickLength = 5.0f;
//axisSet.xAxis.labelOffset = 3.0f;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// Example date format : 2013-05-02 11:23:16 +0000
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss z"];
//dateFormatter.dateStyle = kCFDateFormatterShortStyle;
//dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
timeFormatter.referenceDate = [NSDate dateWithTimeIntervalSince1970:([[NSDate date] timeIntervalSince1970] - (6*oneMin))];
axisSet.xAxis.labelFormatter = timeFormatter;
//axisSet.yAxis.majorIntervalLength = [NSDecimal decimalNumberWithString:#"5"];
//axisSet.yAxis.minorTicksPerInterval = 4;
//axisSet.yAxis.majorTickLineStyle = lineStyle;
//axisSet.yAxis.minorTickLineStyle = lineStyle;
//axisSet.yAxis.axisLineStyle = lineStyle;
//axisSet.yAxis.minorTickLength = 5.0f;
//axisSet.yAxis.majorTickLength = 5.0f;
//axisSet.yAxis.labelOffset = 3.0f;
CPTScatterPlot *xSquaredPlot = [[CPTScatterPlot alloc]
initWithFrame:self.graph.bounds];
xSquaredPlot.identifier = #"X Squared Plot";
CPTMutableLineStyle *dataLineStyle = [CPTMutableLineStyle lineStyle];
dataLineStyle.lineWidth = 1.0f;
dataLineStyle.lineColor = [CPTColor redColor];
xSquaredPlot.dataLineStyle = dataLineStyle;
xSquaredPlot.dataSource = self;
[self.graph addPlot:xSquaredPlot];
self.graphHostView.allowPinchScaling = NO;
self.graphHostView.hostedGraph = self.graph;
[self.view addSubview:self.graphHostView];
}
}
#pragma mark - CPTPlotDataSource methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
return [dictHealth count];
}
-(NSNumber *) numberForPlot:(CPTPlot *)plot
field:(NSUInteger)fieldEnum
recordIndex:(NSUInteger)index {
Health_MemUse *healthData = (Health_MemUse *) [dictHealth objectForKey: [self.arrayHealthKeys objectAtIndex:index]];
if ( fieldEnum == CPTScatterPlotFieldX ) {
return [NSDecimalNumber numberWithFloat:[healthData.currDate timeIntervalSince1970]];
/*
return [NSNumber numberWithDouble:([healthData.currDate timeIntervalSince1970] + [[NSTimeZone localTimeZone] secondsFromGMT])];
*/
} else {
NSLog(#"Plot memuse %f on date %# for index %d",
healthData.memUse, healthData.currDate, index);
return [NSNumber numberWithFloat:(healthData.memUse/(1024*1024*1024))]; // convert bytes to GB
}
}
Please help! I realize I might mostly be wrong in setting the range for the axes, but I tried Googl'ing, Stackoverflow'ing and tried several variations to it, all in vain.
So my problem is simple. I am trying to switch my chart from a bar graph to a line graph but my line chart does not show/plot. I use similar code for my CPTBarPlot 'Bar Chart' and this plots/shows correctly.
My Bar Plot Code which plots correctly is:
CPTBarPlot *barPlot = nil;
barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor colorWithComponentRed:0.9294f green:0.3960f blue:0.5921f alpha:1.0f] horizontalBars:NO];
barPlot.fill = [CPTFill fillWithColor:[CPTColor colorWithComponentRed:0.9294f green:0.3960f blue:0.5921f alpha:1.0f]];
barPlot.opacity = 0.8f;
barPlot.dataSource = self;
barPlot.delegate = self;
barPlot.baseValue = CPTDecimalFromString(#"0");
barPlot.barOffset = CPTDecimalFromFloat(0.50f);
switch (graphType) {
case kWeightThreeMonth:
{
barPlot.identifier = [GraphsViewController threeMonthBarPlotIdentifier];
}
break;
case kWeightSixMonth:
{
barPlot.identifier = [GraphsViewController sixMonthBarPlotIdentifier];
}
break;
case kWeightNineMonth:
{
barPlot.identifier = [GraphsViewController nineMonthBarPlotIdentifier];
}
break;
default:
break;
}
barPlot.barCornerRadius = 2.0f;
barPlot.lineStyle = nil;
[lineGraph addPlot:barPlot toPlotSpace:plotSpace];
My Line Plot Code which does not show is:
// Create a blue plot area
CPTScatterPlot *boundLinePlot = [[[CPTScatterPlot alloc] init] autorelease];
CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.miterLimit = 1.0f;
lineStyle.lineWidth = 3.0f;
lineStyle.lineColor = [CPTColor redColor];
boundLinePlot.dataLineStyle = lineStyle;
switch (graphType) {
case kWeightThreeMonth:
{
boundLinePlot.identifier = [GraphsViewController threeMonthBarPlotIdentifier];
}
break;
case kWeightSixMonth:
{
boundLinePlot.identifier = [GraphsViewController sixMonthBarPlotIdentifier];
}
break;
case kWeightNineMonth:
{
boundLinePlot.identifier = [GraphsViewController nineMonthBarPlotIdentifier];
}
break;
default:
break;
}
boundLinePlot.dataSource = self;
boundLinePlot.delegate = self;
[lineGraph addPlot:boundLinePlot toPlotSpace:plotSpace];
// Do a blue gradient
CPTColor *areaColor1 = [CPTColor colorWithComponentRed:0.3 green:0.3 blue:1.0 alpha:0.8];
CPTGradient *areaGradient1 = [CPTGradient gradientWithBeginningColor:areaColor1 endingColor:[CPTColor clearColor]];
areaGradient1.angle = -90.0f;
CPTFill *areaGradientFill = [CPTFill fillWithGradient:areaGradient1];
boundLinePlot.areaFill = areaGradientFill;
boundLinePlot.areaBaseValue = [[NSDecimalNumber zero] decimalValue];
// Add plot symbols
CPTMutableLineStyle *symbolLineStyle = [CPTMutableLineStyle lineStyle];
symbolLineStyle.lineColor = [CPTColor blackColor];
CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
plotSymbol.fill = [CPTFill fillWithColor:[CPTColor blueColor]];
plotSymbol.lineStyle = symbolLineStyle;
plotSymbol.size = CGSizeMake(10.0, 10.0);
boundLinePlot.plotSymbol = plotSymbol;
Am I missing something here? I would of thought that the datasource etc would all work the same way considering the Bar Plot works correctly. I am simply just trying to switch from a bar chart, to a line chart.
Any help would be much appreciated.
Kind regards,
Dan
You may need to reload your plot's data. Try doing this:
[lineGraph reloadData]
This was actually my own fault.
In the dataSource methods;
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
I was doing an If statement of;
if ( [plot isKindOfClass:[CPTBarPlot class]] ){
Ofcourse I was using a CPTScatterPlot so my code was not being called. Doh.
I'm attempting to load a CPXYGraph into the detail view of a split view controller. I'm getting an EXC_BAD_ACCESS when it attempts to display the plot data.
I create a new project based on "Split View-based application". After adding the CorePlot framework I make the following modifications:
1- add a GraphController (.m, .h and .xib). The xib contains a UIView with a subordinate view of type CPLayerHostingView.
2- add the following line to the app delegate didFinishLaunchingWithOptions
[detailViewController performSelector:#selector(configureView) withObject:nil afterDelay:0];
3- add the following to DetailViewController configureView
CGRect graphFrame = CGRectMake(0, 43, 662, 450);
GraphController *graphController = [[[GraphController alloc]
initWithNibName:#"GraphController" bundle:nil] autorelease];
[graphController.view setFrame:graphFrame];
[self.view addSubview:graphController.view];
[graphController reloadData];
4- the reloadData method in GraphController is pretty much pasted from one of the CorePlot samples (DatePlot) and I will copy and paste (most of) it here-
-(void)reloadData
{
if (!graph)
{
[self parentViewController];
[self.view addSubview:layerHost];
// Create graph from theme
graph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
CPTheme *theme = [CPTheme themeNamed:#"Dark Gradients"];
[graph applyTheme:theme];
....
[layerHost setHostedLayer: graph];
....
// Setup scatter plot space
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
NSTimeInterval xLow = 0.0f;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(xLow) length:CPDecimalFromFloat(oneDay*5.0f)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(1.0) length:CPDecimalFromFloat(3.0)];
// Axes
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromFloat(oneDay);
x.orthogonalCoordinateDecimal = CPDecimalFromString(#"2");
x.minorTicksPerInterval = 0;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateStyle = kCFDateFormatterShortStyle;
CPTimeFormatter *timeFormatter = [[[CPTimeFormatter alloc] initWithDateFormatter:dateFormatter] autorelease];
timeFormatter.referenceDate = refDate;
x.labelFormatter = timeFormatter;
CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPDecimalFromString(#"0.5");
y.minorTicksPerInterval = 5;
y.orthogonalCoordinateDecimal = CPDecimalFromFloat(oneDay);
// Create a plot that uses the data source method
CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = #"Date Plot";
dataSourceLinePlot.dataLineStyle.lineWidth = 3.f;
dataSourceLinePlot.dataLineStyle.lineColor = [CPColor greenColor];
dataSourceLinePlot.dataSource = self;
**[graph addPlot:dataSourceLinePlot];**
// Add some data
NSMutableArray *newData = [NSMutableArray array];
NSUInteger i;
for ( i = 0; i < 5; i++ ) {
NSTimeInterval x = oneDay*i;
id y = [NSDecimalNumber numberWithFloat:1.2*rand()/(float)RAND_MAX + 1.2];
[newData addObject:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSDecimalNumber numberWithFloat:x], [NSNumber numberWithInt:CPScatterPlotFieldX],
y, [NSNumber numberWithInt:CPScatterPlotFieldY],
nil]];
}
plotData = newData;
}
}
The offending line is [graph addPlot:dataSourceLinePlot]; If I comment this out the simulator comes up and displays the x and y axis of the graph and of course no data. Adding this line back causes the following SIGART-
2010-09-15 14:35:58.959 SplitViewWithCorePlot[17301:207] relabel <<CPScatterPlot: 0x4c458c0> bounds: {{0, 0}, {558, 386}}>
Program received signal: “EXC_BAD_ACCESS”.
Can anyone help?
It doesn't look like you're retaining the data array anywhere. Try changing the last statement to
plotData = [newData retain];
or, if you have a property defined for it,
self.plotData = newData;
Eric