Aligning CCMenu to a grid - objective-c

Does anybody know the best practice approach to getting an array of CCMenuItems to align to a grid? This is a cocos2d question
For example :
int levelCount = 10;
CCMenu *menuArray = [CCMenu menuWithItems:nil];
for (int x = 1; x<=levelCount; x++) {
CCLOG(#"Creating level icon for Level %i", x);
[menuArray addChild:[CCMenuItemImage itemFromNormalImage:#"Button2n.png"
selectedImage:#"Button2s.png"
target:self
selector:#selector(onPlay:)]];
}
[menuArray alignToGridWouldbeGreat????!!!!];
[self addChild:menuArray];
I can align vertically, horizontally, in columns or rows however cannot wrap a column or row configuration.
Thanks in advance!

You just have to call one of the overloaded alignItemsInColumns or alignItemsInRows methods. For example if you have 15 menu items and you want 3 rows of 5 columns, do this:
CCMenu* menu = [CCMenu menuWithItems:...];
NSNumber* itemsPerRow = [NSNumber numberWithInt:5];
[menu alignItemsInColumns:itemsPerRow, itemsPerRow, itemsPerRow, nil];
The only down side is that there doesn't seem to be a way to set padding when aligning to a grid.

Ok, while not as flexible as I would like, I've got a decent enough solution for my purposes. Anyone else can feel free to use this code if they too find it useful.
//////// Put images (or whatever) for all levels in an array /////////
int levelCount = 15;
NSMutableArray* menuArray = [NSMutableArray arrayWithCapacity:levelCount];
for (int x = 1; x<=levelCount; x++) {
CCLOG(#"Creating level icon for Level %i", x);
CCMenuItemImage* item = [CCMenuItemImage itemFromNormalImage:#"Button2n.png"
selectedImage:#"Button2s.png"
target:self
selector:#selector(onPlay:)];
[menuArray addObject:item];
}
//////// arrange in a grid with specific number of columns /////////
CGSize screenSize = [CCDirector sharedDirector].winSize;
int columns = 5;
int spaceBetweenColumns = columns + 1;
int spacing = screenSize.width / spaceBetweenColumns;
CCLOG(#"screenWidth (%f) / columnsWithEdges (%i) = spacing = %i, ", screenSize.width, spaceBetweenColumns, spacing);
CGPoint currentDrawPoint = CGPointMake(0, screenSize.height - spacing); // start at the top
for (CCMenuItem *item in menuArray) {
currentDrawPoint.x = currentDrawPoint.x + spacing;
if (currentDrawPoint.x > (columns * spacing)) {
// start a new line as we have reached the end of the previous one
currentDrawPoint.x = spacing;
currentDrawPoint.y = currentDrawPoint.y - spacing;
}
item.position = currentDrawPoint;
[self addChild:item];
}

Here is my solution, i hope it helps.
First define this struct somewhere:
typedef struct
{
int cols;
}RowInfo;
Then:
-(void)layoutMenu:(CCMenu *)menu rowInfo:(RowInfo[])inf rows:(int)rows padding:(CGPoint)padding
{
CCMenuItem *dummy = (CCMenuItem *)[menu.children objectAtIndex:0];
int itemIndex = 0;
float w = dummy.contentSize.width;
float h = dummy.contentSize.height;
CGSize screenSize = [[CCDirector sharedDirector]winSize];
CCArray *items = [menu children];
float startX;
for (int i = rows - 1; i >=0; i--)
{
int colsNow = info[i].cols;
startX = (screenSize.width - (colsNow * w + padding.x * (colsNow - 1)))/2;
float y = i * (padding.y + h);
for (int j = 0; j < colsNow; j++)
{
CCMenuItem *item = (CCMenuItem *)[items objectAtIndex:itemIndex];
item.anchorPoint = ccp(0,0);
item.position = ccp(startX, y);
startX += padding.x + w;
itemIndex++;
}
}
}
The call goes like this(a custom keyboard):
//create custom keyboard
NSArray *captions = [NSArray arrayWithObjects:
#"Q", #"W", #"E", #"R", #"T", #"Y", #"U", #"I", #"O", #"P",
#"A", #"S", #"D", #"F", #"G",#"H", #"J", #"K", #"L",
#"Z", #"X", #"C", #"V", #"B", #"N", #"M", nil];
CCMenu *menu = [CCMenu menuWithItems:nil];
[self addChild:menu];
for (NSString *caption in captions)
{
CCLabelTTF *label = [CCLabelTTF labelWithString:caption fontName:#"Courier" fontSize:25];
CCMenuItemLabel *item = [CCMenuItemLabel itemWithLabel:label target:self selector:#selector(callDelegate:)];
[menu addChild:item];
}
RowInfo info[3] = {{7}, {9}, {10}}; //inverse order
[self layoutMenu:menu withRowInfo:info rows:3 padding:ccp(15, 15)];

May be you can try this....
[menuArray alignItemsVerticallyWithPadding:20.0];
or
[first_menu alignItemsHorizontallyWithPadding:20.0];

To the best of my knowledge Anish's answer is your best course of action. It would be the same as aligning to a grid and it is what I personally use. Just set your menu position and alignment padding and you should have what you are looking for.

Related

multiple function curves in core-plot

I'm currently trying to add more than one mathematical function curves. Below is part of my code.
// draw all expression curves (in viewDidLoad)
for ( j=0; j<self.expNum; j++ ) {
[self getDataForPlot1:self.plotIndex]; // get DataForPlot of one selected expression
[self addCurve:self.plotIndex];
}
I'm trying to add all curves after drawing the axes, but it is only the last input curve that is drawn. How can I separate the dataForPlot for each function?
-(void)getDataForPlot1:(int)index
{
int i;
NSString *exp;
int bound, plotNum;
double interval;
bound = 3 * scaleX;
plotNum = 3 * 60;
interval = (double)bound / plotNum;
NSMutableArray *contentArray = [NSMutableArray arrayWithCapacity:2*plotNum];
for ( i = -plotNum; i < plotNum; i++ ) {
id x;
x = [NSNumber numberWithFloat: i * interval];
// get one expression
.......
id y = [exp numberByEvaluatingString]; // get y values from the expression
[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, #"x", y, #"y", nil]];
}
dataForPlot = contentArray;
}
-(void)addCurve:(int)index {
CPTScatterPlot *boundLinePlot = [[CPTScatterPlot alloc] init];
CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.miterLimit = 1.0f;
lineStyle.lineWidth = 3.0f;
lineStyle.lineColor = [CPTColor blueColor];
boundLinePlot.dataLineStyle = lineStyle;
boundLinePlot.identifier = #"Blue Plot";
boundLinePlot.dataSource = self;
[graph addPlot:boundLinePlot toPlotSpace:plotSpace];
boundLinePlot.interpolation = CPTScatterPlotInterpolationCurved;
}
(Answering the question based on comments above)
Save a copy of each dataset separately. It looks like the calculated plot data gets overwritten each time you call -getDataForPlot1:.
Also, set a unique identifier for each plot so the datasource can know which one is requesting data.

Reg locationmanager: didUpdateLocation

Hi !!
I am new to Objective-C.
I am developing a tracker application, in which I have to store all the gps coordinates and then analyse them to track the path in which the vehicle was. I am using two arrays for storing the latitude and longitude points. When trying to use the Latitude points for calculations later, its giving me an error saying "Out of bound exception at index 1", but the size of the array is being shown to me as 4. Here is the code snippet of my ViewController.h, please take a look and let me know how I do this.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[trackingMapView addPoint:newLocation];
float time = -[startDate timeIntervalSinceNow];
displayLabel.text = [NSString stringWithFormat:#"Speed: %.02f mph", distance * 2.2369 / time];
// if there was a previous location
if (oldLocation != nil)
{
// add distance from the old location tp the total distance
distance += [newLocation getDistanceFrom:oldLocation];
}
// create a region centered around the new point
MKCoordinateSpan span = MKCoordinateSpanMake(0.005, 0.005);
// create a new MKCoordinateRegion centered around the new location
MKCoordinateRegion region = MKCoordinateRegionMake(newLocation.coordinate, span);
//New Added Code
CLLocationSpeed speed = newLocation.speed ;
speed = speed * 2.2369 ;
/* if (speed > 10.000)
{
NSString *message = #"Slow Down !!" ;
UIAlertView *alertforspeed = [[UIAlertView alloc] initWithTitle:#"Speed Monitor" message: message delegate:self cancelButtonTitle:#"Return" otherButtonTitles:nil];
[alertforspeed show];
[alertforspeed release];
}*/
//NEW CODE 2
//----------------------------------------------
arraywithlat= [[NSMutableArray alloc]init];
arraywithlong= [[NSMutableArray alloc]init];
NSNumber *lati = [NSNumber numberWithFloat:newLocation.coordinate.latitude];
NSNumber *longi = [NSNumber numberWithFloat:newLocation.coordinate.longitude];
[arraywithlat addObject:lati];
[arraywithlong addObject:longi];
//[locations addObject:newLocation];
NSLog(#"Array with lat : %#" , arraywithlat);
NSLog(#"Array with long: %#", arraywithlong);
//-----------------------------------------------
int i;
float r1 = 0.0, r2, result ;
NSLog(#"IN LANE TRACKING, BEFORE IFF");
int exsize = sizeof(arraywithlat);
NSLog(#"SIze of array before the loop: %d", exsize);
if (sizeof(arraywithlat) >= 4) {
NSLog(#"CROSSED THE IFFFFF");
NSLog(#"SIXE OF ARRAYWITHLAT: %lu" , sizeof(arraywithlat));
for (i = 0; i <= sizeof(arraywithlat); i++) {
NSNumber *tla1 = [arraywithlat objectAtIndex:i];
float temp1 = [tla1 floatValue];
NSLog(#"temp111111111: %f",temp1);
NSNumber *tla2 = [arraywithlat objectAtIndex:i+1] ;
float temp2 = [tla2 floatValue];
float r1 = temp1 - temp2 ;
// float r1 = [NSNumber numberWithFloat:tla2] - [NSNumber numberWithFloat:tla1];
//float r1 = [tla2 floatValue] - [tla1 floatValue];
r1 = r1 * r1 ;
//float tla = arraywithlat objectAtIndex: i+1) - (arraywithlat objectAtIndex: i);
//float tlo = [arraywithlong obj]
// float tr1 = powf(((arraywithlat objectAtIndex:(i+1))-([arraywithlat objectatIndex:(i)])), <#float#>)
}
}
NSLog(#"r1 after cal: %f",r1);
// reposition the map t show the new point
[mapView setRegion:region animated:YES];
}
I think your problem is here:
for (i = 0; i <= sizeof(arraywithlat); i++) {
NSNumber *tla1 = [arraywithlat objectAtIndex:i];
float temp1 = [tla1 floatValue];
NSLog(#"temp111111111: %f",temp1);
NSNumber *tla2 = [arraywithlat objectAtIndex:i+1] ;
float temp2 = [tla2 floatValue];
float r1 = temp1 - temp2 ;
// float r1 = [NSNumber numberWithFloat:tla2] - [NSNumber numberWithFloat:tla1];
//float r1 = [tla2 floatValue] - [tla1 floatValue];
r1 = r1 * r1 ;
//float tla = arraywithlat objectAtIndex: i+1) - (arraywithlat objectAtIndex: i);
//float tlo = [arraywithlong obj]
// float tr1 = powf(((arraywithlat objectAtIndex:(i+1))-([arraywithlat objectatIndex:(i)])), <#float#>)
}
first indexes in array starts from 0 to n-1, so i <= sizeof(arraywithlat) here wrong, i < sizeof(arraywithlat) should be.
And NSNumber *tla2 = [arraywithlat objectAtIndex:i+1] is wrong. change it, coz when i will be equal to n-1 then you get exception out of bound. And can you explain what does this loop, may be we help you to rewrite it
Also note that - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation method of delegate is deprecated. Use locationManager:didUpdateLocations: instead.

How to rapidly create an NSMutableArray with CFDataRef image pixel data in Xcode for iOS

My question is simple, I have the following code, it creates an array of Hues got from a function that returns the UIColor of an image (this is not important, just context). So, I need to create this array as fast as possible, this test runs with only a 5x5 pixels image and it takes about 3sec, I want to be able to run a 50x50 pixels image (at least) in about 2 secods (tops), any ideas?
- (void)createArrayOfHues: (UIImage *)imageScaned{
if (imageScaned != nil) {
NSLog(#"Creating Array...");
UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];
img.contentMode = UIViewContentModeScaleToFill;
img.image = imageScaned;
img.contentMode = UIViewContentModeRedraw;
img.hidden = YES;
int i = 0;
CGFloat hue = 0;
CGFloat sat = 0;
CGFloat brit = 0;
CGFloat alph = 0;
CGFloat hue2 = 0;
CGFloat sat2 = 0;
CGFloat brit2 = 0;
CGFloat alph2 = 0;
[_colorsArray removeAllObjects];
[_satForHue removeAllObjects];
[_britForHue removeAllObjects];
[_alphForHue removeAllObjects];
_colorsArray = [[NSMutableArray alloc] initWithCapacity:(25)];
_satForHue = [[NSMutableArray alloc] initWithCapacity:(25)];
_britForHue = [[NSMutableArray alloc] initWithCapacity:(25)];
_alphForHue = [[NSMutableArray alloc] initWithCapacity:(25)];
while (i<25) {
for (int y=1; y <= 5; y++){
for (int x = 1; x <= 2.5; x++){
if (x != (5-x)){
UIColor *color = [self colorMatch:imageScaned :x :y];
UIColor *color2 = [self colorMatch:imageScaned :(5-x) :y];
if([color getHue:&hue saturation:&sat brightness:&brit alpha:&alph] && [color2 getHue:&hue2 saturation:&sat2 brightness:&brit2 alpha:&alph2]){
NSNumber *hueId = [NSNumber numberWithFloat:(float)hue];
NSNumber *satId = [NSNumber numberWithFloat:(float)sat];
NSNumber *britId = [NSNumber numberWithFloat:(float)brit];
NSNumber *alphId = [NSNumber numberWithFloat:(float)alph];
NSNumber *hueId2 = [NSNumber numberWithFloat:(float)hue2];
NSNumber *satId2 = [NSNumber numberWithFloat:(float)sat2];
NSNumber *britId2 = [NSNumber numberWithFloat:(float)brit2];
NSNumber *alphId2 = [NSNumber numberWithFloat:(float)alph2];
[_colorsArray insertObject:hueId atIndex:i];
[_satForHue insertObject:satId atIndex:i];
[_britForHue insertObject:britId atIndex:i];
[_alphForHue insertObject:alphId atIndex:i];
[_colorsArray insertObject:hueId2 atIndex:(i+1)];
[_satForHue insertObject:satId2 atIndex:(i+1)];
[_britForHue insertObject:britId2 atIndex:(i+1)];
[_alphForHue insertObject:alphId2 atIndex:(i+1)];
}
NSLog(#"color inserted at %i with x: %i and y: %i" , i , x, y);
i++;
}else {
UIColor *color = [self colorMatch:imageScaned :x :y];
if([color getHue:&hue saturation:&sat brightness:&brit alpha:&alph]){
NSNumber *hueId = [NSNumber numberWithFloat:(float)hue];
NSNumber *satId = [NSNumber numberWithFloat:(float)sat];
NSNumber *britId = [NSNumber numberWithFloat:(float)brit];
NSNumber *alphId = [NSNumber numberWithFloat:(float)alph];
[_colorsArray insertObject:hueId atIndex:i];
[_satForHue insertObject:satId atIndex:i];
[_britForHue insertObject:britId atIndex:i];
[_alphForHue insertObject:alphId atIndex:i];
}
}
}
}
}
NSLog(#"Returns the array");
}else{
NSLog(#"Returns nothing");
}
}
The code for colorMatch:
- (UIColor *) colorMatch: (UIImage *)image :(int) x :(int) y {
isBlackColored = NO;
if (image == nil){
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL customColor = [defaults boolForKey:#"custom_color"];
if (customColor){
float red = [defaults floatForKey:#"custom_color_slider_red"];
float green = [defaults floatForKey:#"custom_color_slider_green"];
float blue = [defaults floatForKey:#"custom_color_slider_blue"];
return [UIColor colorWithRed:red green:green blue:blue alpha:1];
}else
isDefaultS = YES;
}
else{
CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
const UInt8* data = CFDataGetBytePtr(pixelData);
int pixelInfo = ((image.size.width * y) + x ) * 4;
UInt8 red = data[pixelInfo];
UInt8 green = data[(pixelInfo + 1)];
UInt8 blue = data[pixelInfo + 2];
UInt8 alpha = data[pixelInfo + 3];
CFRelease(pixelData);
float redC = red/255.0f;
float greenC = green/255.0f;
float blueC = blue/255.0f;
UIColor* color = [UIColor colorWithRed:redC green:greenC blue:blueC alpha:alpha/255.0f];
return color;
}
return nil;
}
I think your main performance bottleneck is not the initialization of NSMutableArray instances, but the way you index your image:
UIColor *color = [self colorMatch:imageScaned :x :y];
I guess this method converts the UIImage to a CGImageRef, copies its data, indexes it, then destroys/releases these temporary objects, or something like this - for every single pixel...
You should refactor this code to get hold of the image buffer only once, and then work with it like a regular C pointer/array. If that doesn't solve your performance problem, you should do some profiling.

Drawing an Bar graph on cocoa using core plot

I'm new to mac app development. I'm drawing a bar graph using core plot frame work.
What actually i want to is, when i select a month i want to draw graph for last 6 months.when i select '12/2012' I'm able to draw the graph correctly for last 6 months. But when i select '02/2013' the graph is showing only January and February and not the previous months.
- (int)maxVal:(NSMutableArray *)arr {
NSDictionary *dict = [arr objectAtIndex:0];
NSString* dictValue = [dict objectForKey:#"X_VAL"];
int mxm = [dictValue intValue];
for (int i=0; i<[arr count]; i++) {
if ([[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue] > mxm) {
mxm = [[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue];
}
}
return mxm;
}
- (int)minVal:(NSMutableArray *)arr {
int mn = [[[arr objectAtIndex:0] objectForKey:#"X_VAL"] intValue];
for (int i=0; i<[arr count]; i++) {
if ([[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue] < mn) {
mn = [[[arr objectAtIndex:i] objectForKey:#"X_VAL"] intValue];
}
}
return mn;
}
- (void)drawGraph {
if ([graphMutableArray count] > 0) {
NSRect viewRect = [aGraphView bounds];
double xAxisStart = 0, yAxisStart = 0, xAxisLength = [graphMutableArray count], yAxisLength = [[graphMutableArray valueForKeyPath:#"#max.Y_VAL"] doubleValue], tenthPartOfYAxis = (yAxisLength + (yAxisLength / 10));
NSLog(#"Y Axis Length = %f", yAxisLength);
for (int k = 0; k < xAxisLength; k++) {
NSDictionary *dict1 = [graphMutableArray objectAtIndex:k];
NSDictionary *dict2 = [dict1 objectForKey:#"X_VAL"];
NSDictionary *dict3 = [dict1 valueForKey:#"Y_VAL"];
NSLog(#"dict 2 = %# and dict 3 = %#", dict2, dict3);
}
graph = [[CPTXYGraph alloc] initWithFrame:viewRect];
[graph applyTheme:[CPTTheme themeNamed:kCPTSlateTheme]];//kCPTDarkGradientTheme]];//kCPTStocksTheme]];
aGraphView.hostedGraph = graph;
graph.plotAreaFrame.masksToBorder = NO;
graph.paddingLeft = 90.0;
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 70.0;
// Add plot space for horizontal bar charts
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(xAxisStart)
length:CPTDecimalFromDouble(xAxisLength + 1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(yAxisStart)
length:CPTDecimalFromDouble(tenthPartOfYAxis)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
NSString *cptDecimalstr = [NSString stringWithFormat:#"%f", xAxisLength /[x.axisLabels count]];
x.majorIntervalLength = CPTDecimalFromString(cptDecimalstr);
x.minorTicksPerInterval = 1;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
x.axisLineStyle = nil;
x.titleLocation = CPTDecimalFromFloat(1.0f);
x.titleOffset = 55.0f;
// Define some custom labels for the data elements
x.labelRotation = M_PI/4;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
NSLog(#"Max = %d and Min = %d", [self maxVal:graphMutableArray], [self minVal:graphMutableArray]);
NSMutableArray *tempCustomTickLocations = [NSMutableArray arrayWithObjects:[NSNumber numberWithFloat:0.5],[NSNumber numberWithFloat:1.7],[NSNumber numberWithFloat:3.0],[NSNumber numberWithFloat:4.1],[NSNumber numberWithFloat:5.3],[NSNumber numberWithFloat:6.5],[NSNumber numberWithFloat:6.9],[NSNumber numberWithFloat:7.1],[NSNumber numberWithFloat:7.5],[NSNumber numberWithFloat:8.1],[NSNumber numberWithFloat:8.5],[NSNumber numberWithFloat:8.9],nil];
NSMutableArray *tempMonthsArr = [NSMutableArray arrayWithObjects:#"",#"January", #"February", #"March", #"April", #"May", #"June", #"July", #"August", #"September", #"October", #"November", #"December", nil];
NSMutableArray *tempMonthsMutArr
= [[[NSMutableArray alloc] initWithCapacity:[graphMutableArray count]] autorelease], *tempMutCustomTickLocations
= [[[NSMutableArray alloc] initWithCapacity:[graphMutableArray count]] autorelease];
int k = 0;
for (int l = [self minVal:graphMutableArray]; l <=[self maxVal:graphMutableArray]; l++) {
NSString *tempMonth = [tempMonthsArr objectAtIndex:l];
[tempMonthsMutArr addObject:tempMonth];
[tempMutCustomTickLocations addObject:[tempCustomTickLocations objectAtIndex:k]];
k = k + 1;
NSLog(#"tempMutCustomTickLocations= %#",tempMutCustomTickLocations);
}
if ([self minVal:graphMutableArray] == [self maxVal:graphMutableArray]) {
NSString *tempMonth = [tempMonthsArr objectAtIndex:[self minVal:graphMutableArray]];
[tempMonthsMutArr addObject:tempMonth];
[tempMutCustomTickLocations addObject:[tempCustomTickLocations objectAtIndex:0]];
}
NSMutableArray *customTickLocations = [NSMutableArray arrayWithArray:tempMutCustomTickLocations];
NSArray *xAxisLabels = [NSArray arrayWithArray:tempMonthsMutArr];
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[graphMutableArray count]];
for (NSNumber *tickLocation in customTickLocations) {
//NSLog(#"tickLocation==%d",tickLocation.intValue);
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];//[tickLocation decimalValue];
newLabel.offset = x.labelOffset + x.majorTickLength;
// NSLog(#"[tickLocation floatValue] = %f", [tickLocation floatValue]);
newLabel.offset = x.labelOffset + x.majorTickLength;
//NSLog(#"x.labelOffset = %f, x.majorTickLength = %f and newLabel.offset = %f", x.labelOffset, x.majorTickLength, newLabel.offset);
newLabel.rotation = M_PI/4;
//NSLog(#"-=-=-=--=-=-=- %f",x.labelOffset);
//NSLog(#"%f", x.majorTickLength );
[customLabels addObject:newLabel];
//NSLog(#"%#",customLabels);
[newLabel release];
}
x.axisLabels = [NSSet setWithArray:customLabels];
NSLog(#"%#",x.axisLabels);
CPTXYAxis *y = axisSet.yAxis;
y.axisLineStyle = nil;
y.majorTickLineStyle = nil;
y.minorTickLineStyle = nil;
NSString *cptDecimalStr = [NSString stringWithFormat:#"%f", yAxisLength / 10];
y.majorIntervalLength = CPTDecimalFromString(cptDecimalStr);
//y.constantCoordinateValue = CPTDecimalFromString(#"0");
// y.title = #"Y Axis";
y.titleOffset = 45.0f;
y.titleLocation = CPTDecimalFromFloat(150.0f);
//CPTPieChart
CPTBarPlot *plot = [[CPTBarPlot alloc] initWithFrame:CGRectZero];
plot.plotRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0)
length:CPTDecimalFromDouble(xAxisLength)];
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:#"0.50"]
decimalValue]; //CPTDecimalFromDouble(0.50f);
plot.fill = [CPTFill fillWithColor:[CPTColor lightGrayColor]];
plot.dataSource = self;
[graph addPlot:plot ];//toPlotSpace:plotSpace];
}
else {
aGraphView.hostedGraph = nil;
[[NSAlert alertWithMessageText:#"No Data Found" defaultButton:#"Ok" alternateButton:nil otherButton:nil informativeTextWithFormat:#""] runModal];
}
}
Can Anyone Help me to solve the problem!!!
You need to update the xRange of the plot space. This will move the axis labels to the correct position and draw data points in the new range. You'll also need to add the new data points to the plot.

unable to show anything on x-axis and y-axis labels in core-plot

I'm using core plot in an application and from past one week I am trying to show labels on x-axis and y-axis. But haven't succeed yet. I'm posting my code here with screen shot. If someone knows any solution to fix the problem let me know urgently.
Code -
-(void)viewDidLoad {
[super viewDidLoad];
// Initialize all graph dependent data.
//self.dataForPlot = [[NSMutableArray alloc] initWithCapacity:0];
minYValues = [[NSMutableArray alloc] initWithCapacity:0];
maxYValues = [[NSMutableArray alloc] initWithCapacity:0];
[self createGraph];
[self customizeGraph];
}
- (void) createGraph{
// Create graph
graph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
CPGraphHostingView *hostingView = (CPGraphHostingView *)self.view;
hostingView.collapsesLayers = YES;
hostingView.hostedGraph = graph;
hostingView.frame = self.view.frame;
//Create a blue plot area
CPScatterPlot *boundLinePlot = [[[CPScatterPlot alloc] init] autorelease];
boundLinePlot.dataLineStyle.miterLimit = 1.0f;
boundLinePlot.dataLineStyle.lineWidth = 1.0f;
UIColor* color = [UIColor orangeColor];
boundLinePlot.dataLineStyle.lineColor = [CPColor colorWithCGColor:[color CGColor]];
boundLinePlot.dataSource = self;
[graph addPlot:boundLinePlot];
}
- (void) customizeGraph{
if(graph)
{
graph.paddingLeft = 20.0;
graph.paddingTop = 20.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 20.0;
CPScatterPlot *goalWeightPlot = [[[CPScatterPlot alloc] init] autorelease];
goalWeightPlot.identifier = kGoalWeightPlot;
//boundLinePlot.dataLineStyle.miterLimit = 5.0f;
goalWeightPlot.dataLineStyle.lineWidth = 1.0f;
goalWeightPlot.dataLineStyle.lineColor = [CPColor redColor];
goalWeightPlot.dataLineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:5.0],[NSNumber numberWithFloat:2.0],nil];
goalWeightPlot.dataSource = self;
[graph addPlot:goalWeightPlot];
// Create a blue plot area
CPScatterPlot *boundLinePlot = [[[CPScatterPlot alloc] init] autorelease];
boundLinePlot.identifier = kActualWeightPlot;
//boundLinePlot.dataLineStyle.miterLimit = 5.0f;
boundLinePlot.dataLineStyle.lineWidth = 1.0f;
boundLinePlot.dataLineStyle.lineColor = [CPColor orangeColor];
boundLinePlot.dataSource = self;
// Add plot symbols
CPLineStyle *symbolLineStyle = [CPLineStyle lineStyle];
symbolLineStyle.lineColor = [CPColor orangeColor];
CPPlotSymbol *plotSymbol = [CPPlotSymbol ellipsePlotSymbol];
plotSymbol.fill = [CPFill fillWithColor:[CPColor orangeColor]];
plotSymbol.lineStyle = symbolLineStyle;
plotSymbol.size = CGSizeMake(5.0, 5.0);
boundLinePlot.plotSymbol = plotSymbol;
[graph addPlot:boundLinePlot];
}
}
- (void) resetData{
dataForPlot = nil;
}
- (void) setGraphData:(NSArray*)graphData andRefrenceValue:(float)goalValue{
self.refereceValue = goalValue;
[self setGraphData:graphData];
}
- (void) setGraphData:(NSArray*)graphData{
//Check if we have any single weight entry in the array
if(graphData && [graphData count] > 0) {
[self prepareGraphData:graphData];
[self setRangeForGraph];
[graph reloadData];
}
}
- (NSArray *)sortedWeightEntriesByWeightDate:(NSArray *)unsortedArray {
NSMutableArray *tempArray = [NSMutableArray array];
for(int i=0;i<[unsortedArray count];i++) {
NSDateFormatter *df = [[NSDateFormatter alloc]init];
WeightEntry *entry = [unsortedArray objectAtIndex:i];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [df dateFromString:entry.weightDate];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
if(date) {
[dict setObject:entry forKey:#"entity"];
[dict setObject:date forKey:#"date"];
[tempArray addObject:dict];
}
[df release];
}
NSInteger counter = [tempArray count];
NSDate *compareDate;
NSInteger index;
for(int i = 0 ; i < counter; i++) {
index = i;
compareDate = [[tempArray objectAtIndex:i] valueForKey:#"date"];
NSDate *compareDateSecond;
for(int j = i+1 ; j < counter; j++)
{
compareDateSecond=[[tempArray objectAtIndex:j] valueForKey:#"date"];
NSComparisonResult result = [compareDate compare:compareDateSecond];
if(result == NSOrderedDescending)
{
compareDate = compareDateSecond;
index=j;
}
}
if(i!=index)
[tempArray exchangeObjectAtIndex:i withObjectAtIndex:index];
}
NSMutableArray *sortedArray = [NSMutableArray arrayWithCapacity:0];
NSInteger counterIndex = [tempArray count];
for(int i = 0; i < counterIndex ; i++) {
[sortedArray addObject:[[tempArray objectAtIndex:i] valueForKey:#"entity"]];
}
return [NSArray arrayWithArray:sortedArray];
}
- (void) prepareGraphData:(NSArray*)data{
data = [self sortedWeightEntriesByWeightDate:data];
NSNumber* minYValue = nil;
NSNumber* maxYValue = nil;
NSMutableArray *contentArray = [NSMutableArray arrayWithCapacity:[data count]];
NSUInteger i;
for ( i = 0; i < [data count]; i++ ) {
WeightEntry* weightEntry = [data objectAtIndex:i];
if(i == 0){
maxYValue = [NSNumber numberWithFloat:weightEntry.weight];
minYValue = [NSNumber numberWithFloat:weightEntry.weight];
}
//id x = [NSNumber numberWithFloat:weightEntry.weight];
//id y = [NSNumber numberWithFloat:1.2*rand()/(float)RAND_MAX + 1.2];
id x = [NSNumber numberWithFloat:i];
id y = [NSNumber numberWithFloat:weightEntry.weight];
if([y floatValue] > [maxYValue floatValue])
maxYValue = y;
if([y floatValue] < [minYValue floatValue])
minYValue = y;
//[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, #"x", y, #"y",[NSNumber numberWithFloat:goalWeight],#"goalY",nil]];
[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, #"x", y, #"y",nil]];
}
self.dataForPlot = [NSArray arrayWithArray:contentArray];
[minYValues addObject:minYValue];
[maxYValues addObject:maxYValue];
lblHighValue.text = [NSString stringWithFormat:#"High = %0.2f", [maxYValue floatValue]];
lblLowValue.text = [NSString stringWithFormat:#"Low = %0.2f", [minYValue floatValue]];
lblRefrenceValue.text = [NSString stringWithFormat:#"Goal = %0.2f", self.refereceValue];
}
// Update the Plot Space Range to cover all graphs
- (void) setRangeForGraph{
NSNumber* minimumYValue;
NSNumber* maxmumYValue;
if([minYValues count] > 0 && [maxYValues count] > 0){
minimumYValue = [minYValues objectAtIndex:0];
maxmumYValue = [maxYValues objectAtIndex:0];
// Calculate minimum y value among all graphs.
for (int i = 0 ; i < [minYValues count] ; i++) {
if([[minYValues objectAtIndex:i] floatValue] < [minimumYValue floatValue])
minimumYValue = [minYValues objectAtIndex:i];
}
// Calculate maximum y value among all graphs.
for (int i = 0 ; i < [maxYValues count] ; i++) {
if([[maxYValues objectAtIndex:i] floatValue] > [maxmumYValue floatValue])
maxmumYValue = [maxYValues objectAtIndex:i];
}
NSDecimalNumber *high = [NSDecimalNumber decimalNumberWithDecimal:[maxmumYValue decimalValue]];
high = [high decimalNumberByAdding:[NSDecimalNumber decimalNumberWithString:#"30"]];
// Modify the y range for plot space to cover all values.
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:[high decimalValue]];
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:CPDecimalFromInt([self.dataForPlot count])];
CPPlotAreaFrame *area = (CPPlotAreaFrame *)graph.plotAreaFrame;
area.paddingLeft = 20;
area.paddingBottom = 10;
CPXYAxisSet *axisSet = (CPXYAxisSet*)graph.axisSet;
//axis.paddingLeft = 20.0;
axisSet.xAxis.paddingBottom = 50.0;
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromInteger([self.dataForPlot count]);
CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPDecimalFromFloat([high floatValue]);
axisSet.xAxis.orthogonalCoordinateDecimal = CPDecimalFromFloat([minimumYValue floatValue]);
//axisSet.xAxis.labelOffset = 0.0;
CPLineStyle *lineStyle = [CPLineStyle lineStyle];
lineStyle.lineColor = [CPColor colorWithCGColor:((UIColor*)kProtienColor).CGColor];
lineStyle.lineWidth = 1.0f;
// style the graph with white text and lines
CPTextStyle *whiteText = [CPTextStyle textStyle];
whiteText.color = [CPColor redColor];
//CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromString(#"1");
x.axisLineStyle = lineStyle;
//x.majorGridLineStyle=lineStyle;
//x.minorTicksPerInterval = 0;
//x.minorTickLineStyle = lineStyle;
x.title = #"Weight";
x.titleOffset = 3.0f;
x.titleLocation = CPDecimalFromFloat(3.0f);
x.titleTextStyle = whiteText;
x.labelTextStyle = whiteText;
//y.majorIntervalLength = CPDecimalFromString(#"150");
//y.minorTicksPerInterval = 10;
y.axisLineStyle = lineStyle;
y.title = #"Date";
y.titleTextStyle = whiteText;
y.titleOffset = 0;
y.minorTickLineStyle = lineStyle;
//y.titleLocation = CPDecimalFromFloat(graph.frame.origin.y+10);
//y.majorGridLineStyle=lineStyle;
//y.labelTextStyle=whiteText;
}
}
- (NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot {
int nofOfRecords = 0;
#try {
nofOfRecords = [self.dataForPlot count];
}
#catch (NSException * e) {
NSLog(#"Exception while calculating graph index : %#", [e description]);
}
#finally {
//NSLog(#"Number of Records : %d For Graph Index : %d", nofOfRecords, graphIndex);
return nofOfRecords;
}
}
- (NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSNumber *num = 0;
//int plotIndex = [(NSString *)plot.identifier intValue];
if([self.dataForPlot count] > 0){
if(![((NSString*)[plot identifier]) isEqualToString:kGoalWeightPlot]){
num = [[dataForPlot objectAtIndex:index] valueForKey:(fieldEnum == CPScatterPlotFieldX ? #"x" : #"y")];
}else {
if(fieldEnum == CPScatterPlotFieldX)
num = [[dataForPlot objectAtIndex:index] valueForKey:#"x"];
else {
num = [NSNumber numberWithFloat:self.refereceValue];
}
}
}
return num;
}
Screenshot -
I want to show custom labels on x-axis and default labels on y-axis.
EDIT:
I've tried adding sample class of barChart+XIB from CPTest-iPhoneApp. The bar chart appears but axis label's don't. Here is the screenshot form CPTest-iPhone app and mine.
CPXYAxis *yy = axisSet.yAxis;
yy.axisLineStyle.lineColor=[CPColor whiteColor];
yy.majorTickLineStyle = nil;
yy.minorTickLineStyle = nil;
yy.title = #"Y Axis";
yy.titleLocation = CPDecimalFromFloat(100.0f);
yy.titleOffset = 245.0f;
// Define some custom labels for the data elements
yy.labelingPolicy = CPAxisLabelingPolicyNone;
NSArray *customTickLocations1 = [NSArray arrayWithObjects:[NSDecimalNumber numberWithInt:0], [NSDecimalNumber numberWithInt:10],[NSDecimalNumber numberWithInt:20], [NSDecimalNumber numberWithInt:30], nil];
NSArray *yAxisLabels = [NSArray arrayWithObjects:#"a",#"b", #"c",nil];
NSUInteger labelLocation1 = 0;
NSMutableArray *customLabels1 = [NSMutableArray arrayWithCapacity:[yAxisLabels count]];
for (NSNumber *tickLocation1 in customTickLocations1)
{
CPAxisLabel *newLabel1 = [[CPAxisLabel alloc]
initWithText: [yAxisLabels objectAtIndex:labelLocation1++]
textStyle:yy.labelTextStyle];
newLabel1.tickLocation = [tickLocation1 decimalValue];
newLabel1.offset = yy.labelOffset + yy.majorTickLength;
[customLabels1 addObject:newLabel1];
[newLabel1 release];
}
yy.axisLabels = [NSSet setWithArray:customLabels1];
I have resolved my problem. All I have to do is start adding core-plot from beginning. I removed core-plot from my project again add voila! it's working