Can not differentiate between data for plots, CorePlot - objective-c

I am trying to plot 2 lines on 1 graph using CorePlot. Right now I am plotting the same data twice, I am not sure how to choose the other data source.
Any help would be appreciated.
Code:
graph view code .m:
CPTScatterPlot *limitplot = [[CPTScatterPlot alloc] init];
limitplot.dataSource = self;
limitplot.identifier = #"limplot";
limitplot.dataLineStyle = lineStylelimit;
limitplot.plotSymbol = plotSymbollimit;
[self.graph addPlot:limitplot];
CPTScatterPlot *calplot = [[CPTScatterPlot alloc] init];
calplot.dataSource = self;
calplot.identifier = #"plot";
calplot.dataLineStyle = lineStylecalc;
calplot.plotSymbol = plotSymbolcalc;
[self.graph addPlot:calplot];
}
// Delegate method that returns the number of points on the plot
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [plot.identifier isEqual:#"limplot"] )
{
return [self.graphData count];
}
else if ( [plot.identifier isEqual:#"plot"] )
{
return [self.graphData count];
}
return 0;
}
// Delegate method that returns a single X or Y value for a given plot.
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ( [plot.identifier isEqual:#"limplot"] )
{
NSValue *value = [self.graphData objectAtIndex:index];
CGPoint point = [value CGPointValue];
// FieldEnum determines if we return an X or Y value.
if ( fieldEnum == CPTScatterPlotFieldX )
{
return [NSNumber numberWithFloat:point.x];
}
else // Y-Axis
{
return [NSNumber numberWithFloat:point.y];
}
} else if ( [plot.identifier isEqual:#"plot"] )
{
NSValue *value = [self.graphData objectAtIndex:index];
CGPoint point = [value CGPointValue];
// FieldEnum determines if we return an X or Y value.
if ( fieldEnum == CPTScatterPlotFieldX )
{
return [NSNumber numberWithFloat:point.x];
}
else // Y-Axis
{
return [NSNumber numberWithFloat:point.y];
}
}
return [NSNumber numberWithFloat:0];
}
Data .m:
NSMutableArray *limitdata = [NSMutableArray array];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5477, 5400)]];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5292, 5400)]];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5053, 6425)]];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5029, 7154)]];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5138, 8300)]];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5503, 8300)]];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5570, 7100)]];
[limitdata addObject:[NSValue valueWithCGPoint:CGPointMake(5477, 5400)]];
self.lewis = [[TUTSimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:limitdata];
[self.lewis initialisePlot];
double cofullMass = [coTOMass doubleValue];
double cofullStation = [coTOstation doubleValue];
double coeeMass = [coEEmass doubleValue];
double coeeStation = [coEEstation doubleValue];
double cossMass = [coSSmass doubleValue];
double cossStation = [coSSstation doubleValue];
double codryMass = [coZmass doubleValue];
double codryStation = [coZstation doubleValue];
NSMutableArray *caldata = [NSMutableArray array];
[caldata addObject:[NSValue valueWithCGPoint:CGPointMake(cofullStation, cofullMass)]];
[caldata addObject:[NSValue valueWithCGPoint:CGPointMake(coeeStation, coeeMass)]];
[caldata addObject:[NSValue valueWithCGPoint:CGPointMake(cossStation, cossMass)]];
[caldata addObject:[NSValue valueWithCGPoint:CGPointMake(codryStation, codryMass)]];
self.lewis = [[TUTSimpleScatterPlot alloc] initWithHostingView:_graphHostingView andData:caldata];
[self.lewis initialisePlot];

You've got everything correct including testing the plot identifier and the fieldEnum. Once you determine which plot is asking for data, use that to choose the right data array instead of getting the count and data points from self.graphData for both plots.

Related

How can I display Latitude & Longitude in 19.0176° N, 72.8562° E format in Objective c

I am using the following code to get the current location,I have added the Corelocation framework
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
NSInteger degrees = newLocation.coordinate.latitude;
double decimal = fabs(newLocation.coordinate.latitude - degrees);
int minutes = decimal * 60;
double seconds = decimal * 3600 - minutes * 60;
NSString *lattitudeStr = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
_latitudeLabel.text = lattitudeStr;
degrees = newLocation.coordinate.longitude;
decimal = fabs(newLocation.coordinate.longitude - degrees);
minutes = decimal * 60;
seconds = decimal * 3600 - minutes * 60;
NSString *longitudeStr = [NSString stringWithFormat:#"%d° %d' %1.4f\"",
degrees, minutes, seconds];
_longitudeLabel.text = longitudeStr;
}
// Stop Location Manager
[locationManager stopUpdatingLocation];
NSLog(#"Resolving the Address");
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^
(NSArray *placemarks, NSError *error)
{
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0)
{
placemark = [placemarks lastObject];
_addressLabel.text = [NSString stringWithFormat:#"%#\n%# %#\n%#\n%#",
placemark.thoroughfare,
placemark.postalCode, placemark.locality,
placemark.administrativeArea,
placemark.country];
} else {
NSLog(#"%#", error.debugDescription);
}
} ];
}
I am getting the values for,Latitude:19° 1’ 3.4129” and Longitude:72° 51’ 22.1918” So I need this coordinate display in 19.0176° N,72.8562° E format in Objective c. How to get the exact latitude and longitude. where i am doing the mistake or do i need to add any other method or function or framework or sample code.
You already have these values, see the comment this is what you want
if (currentLocation != nil) {
NSInteger degrees = newLocation.coordinate.latitude; //<--- this is what you want
NSString *lattitudeStr = [NSString stringWithFormat:#"%f° N",
degrees];
_latitudeLabel.text = lattitudeStr;
degrees = newLocation.coordinate.longitude; //<--- this is what you want
NSString *longitudeStr = [NSString stringWithFormat:#"%f° E",
degrees];
_longitudeLabel.text = longitudeStr;
}
NSString *lat = [self convertCoordinateFromDegreeMinuteSecond:#"19° 1’ 3.4129”" position:#"N"];
NSString *lon = [self convertCoordinateFromDegreeMinuteSecond:#"72° 51’ 22.1918”" position:#"E"];
- ( NSString * )convertCoordinateFromDegreeMinuteSecond:( NSString * )string position:( NSString * )position; {
NSCharacterSet *notAllowedChars = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
NSArray *arrayLat = [string componentsSeparatedByString:#" "];
if ( arrayLat.count == 3 ) {
NSString *degree = [[arrayLat[ 0 ] componentsSeparatedByCharactersInSet:notAllowedChars] componentsJoinedByString:#""];
NSString *minute = [[arrayLat[ 1 ] componentsSeparatedByCharactersInSet:notAllowedChars] componentsJoinedByString:#""];
NSString *second = [[arrayLat[ 2 ] componentsSeparatedByCharactersInSet:notAllowedChars] componentsJoinedByString:#""];
int sign = degree.doubleValue < 0 ? -1 : 1;
double coordinate = ( degree.doubleValue + ( sign * ( minute.doubleValue / 60. ) ) + ( sign * ( second.doubleValue / 3600. ) ) );
NSString *str = [NSString stringWithFormat:#"%f° %#", coordinate, position];
return str;
} else {
return #"NaN";
}
}

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.

how to draw a path one place to another place in google map sdk iOS?

i need to find path in google map view one place to another place. how to draw a direction map using google map sdk iOS.
can any of give source code. and then explain how to achieve this.
Below i attached image also, i need to achieve this in iPhone app using Google Map SDK iOS.
Thanks,
-(void)showRoute:(id)routeDict {
NSString *pointStr = [[[[routeDict objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"overview_polyline"] objectForKey:#"points"];
float max_long = 0.0;
float min_long = 0.0;
float max_lat = 0.0;
float min_lat = 0.0;
NSMutableArray *routeArr = [self decodePolyLine:pointStr];
CLLocationCoordinate2D commuterLotCoords[[routeArr count]];
CLLocation *loc;
if ([routeArr count]) {
loc = [routeArr objectAtIndex:0];
max_long = loc.coordinate.longitude;
min_long = loc.coordinate.longitude;
max_lat = loc.coordinate.latitude;
min_lat = loc.coordinate.latitude;
}
for (int i=0; i<[routeArr count]; i++) {
CLLocation *loc = [routeArr objectAtIndex:i];
commuterLotCoords[i] = loc.coordinate;
if (loc.coordinate.latitude > max_lat) {
max_lat = loc.coordinate.latitude;
}
if (loc.coordinate.latitude < min_lat) {
min_lat = loc.coordinate.latitude;
}
if (loc.coordinate.longitude > max_long) {
max_long = loc.coordinate.longitude;
}
if (loc.coordinate.longitude < min_long) {
min_long = loc.coordinate.longitude;
}
}
MKPolyline *overflowRoutePolygon = [MKPolyline polylineWithCoordinates:commuterLotCoords count:[routeArr count]];
[mapView addOverlay:overflowRoutePolygon];
//NSLog(#"%f %f %f %f",min_lat,max_lat,min_long,max_long);
if ( max_lat == 0.0 || min_lat == 0.0 || max_long == 0.0 || min_long == 0.0 ) {
} else {
//calculate center of map
float center_long = (max_long + min_long) / 2;
float center_lat = (max_lat + min_lat) / 2;
//calculate deltas
float deltaLat = max_lat - min_lat + .00032;
float deltaLong = max_long - min_long + .00032;
//NSLog(#"%f %f %f %f",center_lat,center_long,deltaLat,deltaLong);
//create new region and set map
CLLocationCoordinate2D cordinate;
cordinate.latitude = center_lat;
cordinate.longitude = center_long;
MKCoordinateSpan span = MKCoordinateSpanMake(deltaLat, deltaLong);
MKCoordinateRegion region = {cordinate, span};
[mapView setRegion:region];
}
}
-(void)showRoute
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
float sourceLat = 0.00;
float sourceLong = 0.00;
float destinationLat = 0.00;
float destinationLong = 0.00;
id record = [routeArray objectAtIndex:selectedIndex];
sourceLat = [[[[record objectForKey:#"To"] objectForKey:#"Latitude"] objectForKey:#"text"] floatValue];
sourceLong = [[[[record objectForKey:#"To"] objectForKey:#"Longitude"] objectForKey:#"text"] floatValue];
destinationLat = [[[[record objectForKey:#"From"] objectForKey:#"Latitude"] objectForKey:#"text"] floatValue];
destinationLong = [[[[record objectForKey:#"From"] objectForKey:#"Longitude"] objectForKey:#"text"] floatValue];
if ( sourceLat == 0.00 || sourceLong == 0.00 || destinationLat == 0.00 || destinationLong == 0.00 ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Direction Error"
message: #"One of your destination is not valid."
delegate: self
cancelButtonTitle: #"OK"
otherButtonTitles: nil];
[alert show];
[alert release];
return;
}
NSString *urlStr = [NSString stringWithFormat: #"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false",
sourceLat, sourceLong,
destinationLat,destinationLong];
NSLog(#"urlStr : %#",urlStr);
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:urlStr]];
//NSLog(#"direction response : %#",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
JSONDecoder *jsonKitDecoder = [JSONDecoder decoder];
NSMutableDictionary *routeDic = [[jsonKitDecoder objectWithData:data] copy];
if ( ![[[routeDic objectForKey:#"status"] uppercaseString] isEqualToString:#"OK"] ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"Direction Error"
message: #"Not able to find direction from your default location."
delegate: self
cancelButtonTitle: #"OK"
otherButtonTitles: nil];
[alert show];
[alert release];
[pool release];
return;
}
[self performSelectorOnMainThread:#selector(showRoute:) withObject:routeDic waitUntilDone:YES];
[pool release];
return;
}
-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr
{
NSMutableString *encoded = [[NSMutableString alloc] initWithCapacity:[encodedStr length]];
[encoded appendString:encodedStr];
[encoded replaceOccurrencesOfString:#"\\\\" withString:#"\\" options:NSLiteralSearch range:NSMakeRange(0, [encoded length])];
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
NSInteger lat = 0;
NSInteger lng = 0;
while (index < len) {
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
NSNumber *latitute = [[[NSNumber alloc] initWithFloat:lat * 1e-5] autorelease];
NSNumber *longitute = [[[NSNumber alloc] initWithFloat:lng * 1e-5] autorelease];
CLLocation *loc = [[[CLLocation alloc] initWithLatitude:[latitute floatValue] longitude:[longitute floatValue]] autorelease];
[array addObject:loc];
}
[encoded release];
return array;
}
pragma mark MKMapKitDelegate
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
HAnnotation *ann = (HAnnotation *)annotation;
static NSString *AnnotationViewID = #"annotationViewID";
HAnnotationView *annotationView = (HAnnotationView *)[map dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[[HAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID type:ann.type] autorelease];
}
annotationView.type = ann.type;
annotationView.annotation = annotation;
[annotationView setNeedsDisplay];
return annotationView;
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView *aV;
for (aV in views) {
MKAnnotationView* annotationView = aV;
annotationView.canShowCallout = NO;
}
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay
{
if( [overlay isKindOfClass:[MKPolyline class]] ) {
MKPolylineView *view = [[MKPolylineView alloc] initWithOverlay:overlay];
view.lineWidth=2;
view.strokeColor=[UIColor blueColor];
view.fillColor=[[UIColor blueColor] colorWithAlphaComponent:0.5];
return [view autorelease];
} else {
MKPolygonView *view = [[MKPolygonView alloc] initWithOverlay:overlay];
view.lineWidth=2;
view.strokeColor=[UIColor yellowColor];
view.fillColor=[[UIColor yellowColor] colorWithAlphaComponent:0.3];
return [view autorelease];
}
return nil;
}
Try this code i have used this code in my project it is working fine.
First of all pass source and destination latitude and longitude in the google api you will get all the points between that place and after parsing using poly line method you will draw line.simply use this methods make changes according to your variable and data .
i hope this will help you. This is from google api. Draw polyline and give paths lat long in it .
https://developers.google.com/maps/documentation/ios/shapes#customize_a_polyline

Can't withdraw CGPoint Values from A mutableArray of NSValue

I made an NSMUtableArray of CGpoints and I stored them by subclassing as NSValue, but I cant get the values out. here I what I did.
CGPoint graphPoint;
NSMutableArray *pointValues = [[NSMutableArray alloc] init];
for( int x =0;x<5; x++)
{
NSDictionary* xValue = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:x] forKey:#"X"];
graphPoint.x =x;
graphPoint.y = [CalculatorBrain runProgram: self.graphingPoint usingVariableValues:xValue];
[pointValues addObject:[NSValue valueWithCGPoint:graphPoint]];
}
I tried using this to get the values but I just get null back
for( int x=0; x<5; x++) {
NSValue *val = [pointValues objectAtIndex:x];
CGPoint point = [val CGpointValue];
NSLog(#"Points = %#", point);
}
You can't print a CGPoint using the %# format specifier, as it is not an object. Instead, use NSStringFromCGPoint():
NSLog(#"%#", NSStringFromCGPoint(myPoint));

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