change the y axis Label interval in core plot - iphone

I implemented core plot library for scatter graph in my app. But I want show the Y Axis Labels like 1.0,2.0,3.0,4.0,5.0,.. and plot the graph accordingly.
When I change the interval of y Label as follow by multiplying with 25 as shown below
NSInteger majorIncrement = 2;
NSInteger minorIncrement = 1;
CGFloat yMax = 10.0f;// should determine dynamically based on max price
NSMutableSet *yLabels = [NSMutableSet set];
NSMutableSet *yMajorLocations = [NSMutableSet set];
NSMutableSet *yMinorLocations = [NSMutableSet set];
for (NSInteger j = minorIncrement; j <= yMax; j += minorIncrement) {
NSUInteger mod = j % majorIncrement;
if (mod == 0) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"%i", j] textStyle:y.labelTextStyle];
NSDecimal location = CPTDecimalFromInteger(j*25); **//multiply with 25**`
label.tickLocation = location;
label.offset = -y.majorTickLength - y.labelOffset;
if (label) {
[yLabels addObject:label];
}
[yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];
} else {
[yMinorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:CPTDecimalFromInteger(j)]];
}
}
y.axisLabels = yLabels;
y.majorTickLocations = yMajorLocations;
y.minorTickLocations = yMinorLocations;
But when the graph is ploted , it shows me wrong.
e.g. if my score is 150 then it start plot as 150/25=6th point.

You can set the orthogonalCoordinateDecimal, To determine the point where your graph starts
CPTXYAxis *y = axisSet.yAxis;
y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(150/25);
further more ,setting the plotRange,
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:(150/25) length:25];

Related

scatterplot with Xcode for iPhone data not sync with axis and major thick not shown

I'm a beginner in Stackoverflow and Xcode for iPhone.
English is not my native language, so please bear with me.
I've been trying to make a graph between dates (x axis) and the Fuel Economy value (y axis).
I'm using core plot 1.4.
My problem are:
The data somehow is not sync directly to x axis.
Major checklist somehow is not shown. (solved)
Is there any way to make the graph only shows the positif axis? (solved)
I've doing a lot of NSLog to debug the data. I've search google (including this site) for the tutorial of how to use the custom label and how to make scatter plot graph).
I have the following data:
(
{
0 = "31-Jan-2014";
1 = 10;
},
{
0 = "02-Feb-2014";
1 = "10.07";
},
{
0 = "24-Feb-2014";
1 = "8.75";
}
)
I've got strange result with above data. Please see the included graph
this is the picture of my graph:
in the graph, the y data is not mapped to x axis.
here's the relevant code
- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
NSLog(#"Number of Records for Plot = %lu",(unsigned long)[self.plotData count]);
return [_plotData count];
}
- (NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx
{
//NSDecimalNumber *result = [[_plotData objectAtIndex:idx]objectForKey:[NSNumber numberWithInt:fieldEnum]];
NSNumber *result;
switch (fieldEnum) {
case CPTScatterPlotFieldX:
// NSDate * observationDate = [[_plotData objectAtIndex:idx]objectForKey:[NSNumber numberWithInt:fieldEnum]];
// NSTimeInterval secondsSince1970 = [_observationDate timeIntervalSince1970];
result = [[_plotData objectAtIndex:idx]objectForKey:[NSNumber numberWithInt:fieldEnum]];
break;
case CPTScatterPlotFieldY:
result = [[_plotData objectAtIndex:idx] objectForKey:[NSNumber numberWithInt:fieldEnum]];
}
//result = [[_plotData objectAtIndex:idx] objectForKey:[NSNumber numberWithInt:fieldEnum]];
NSLog(#"Number tobe Plot with index = %# %lu, %lu",result,(unsigned long)idx,(unsigned long)fieldEnum);
return result;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self initPlot];
// Do any additional setup after loading the view.
}
- (void)initPlot
{
//NSDate *refDate = [NSDate dateWithNaturalLanguageString:#"12:00 Oct 29, 2009"];
[self fetchResultOneWeek];
[self configureHost];
[self configureFEGraph];
[self configurePlots];
[self configureAxis];
}
- (void)configureHost
{
CGRect frame1 = CGRectMake(0,80,320,200);
FESubView = [[CPTGraphHostingView alloc]initWithFrame:frame1];
FESubView.allowPinchScaling = YES;
[self.view addSubview:FESubView];
CGRect frame2 = CGRectMake(0,410,320,400);
GasPriceSubView = [[CPTGraphHostingView alloc]initWithFrame:frame2];
GasPriceSubView.allowPinchScaling = YES;
[self.view addSubview:GasPriceSubView];
}
- (void)configureFEGraph
{
CPTGraph *graph = [[CPTXYGraph alloc]initWithFrame:FESubView.bounds];
[graph applyTheme:[CPTTheme themeNamed:kCPTStocksTheme]];
FESubView.hostedGraph = graph;
graph.title = #"Fuel Economy Graph";
CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle];
titleStyle.color = [CPTColor whiteColor];
titleStyle.fontName = #"Helvetica-Bold";
titleStyle.fontSize = 14.0f;
graph.titleTextStyle = titleStyle;
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
graph.titleDisplacement = CGPointMake(0.0f, 10.0f);
// 4 - Set padding for plot area
[graph.plotAreaFrame setPaddingLeft:10.0f];
[graph.plotAreaFrame setPaddingBottom:10.0f];
[graph.plotAreaFrame setPaddingTop:10.0f];
[graph.plotAreaFrame setPaddingRight:10.0f];
// 5 - Enable user interactions for plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
}
- (void)configurePlots
{
NSMutableArray *dataTobePlotted = [NSMutableArray array];
NSUInteger i;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"dd-MMM-YYY"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT+0:07"]];
//NSTimeInterval oneDay = 24 * 60 * 60;
for (i = 0;i < [[self.fullTransaction valueForKey:#"tDate"]count]; i++)
{
NSDate *observationDate = [[self.fullTransaction valueForKey:#"tDate"]objectAtIndex:i];
NSLog(#"observationDate is : %#",observationDate);
NSTimeInterval x = [observationDate timeIntervalSince1970];
NSLog(#"x is : %f",x);
id y = [[self.fullTransaction valueForKey:#"tFuelEconomy"]objectAtIndex:i];
NSLog(#"y is : %#",y);
[dataTobePlotted addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:x],[NSNumber numberWithInt:CPTScatterPlotFieldX],y,[NSNumber numberWithInt:CPTScatterPlotFieldY],nil]];
//[dataTobePlotted addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSDecimalNumber numberWithFloat:x],[NSNumber numberWithInt:CPTScatterPlotFieldX],y,[NSNumber numberWithInt:CPTScatterPlotFieldY],nil]];
NSLog(#" int X is %#",[NSNumber numberWithInt:CPTScatterPlotFieldX]);
NSLog(#" int Y is %#",[NSNumber numberWithInt:CPTScatterPlotFieldY]);
NSLog(#"ScatterPlotField X is %#",[NSNumber numberWithInt:CPTScatterPlotFieldX]);
NSLog(#"ScatterPlotField Y is %#",[NSNumber numberWithInt:CPTScatterPlotFieldY]);
NSLog(#"Data to be Plotted: %#",dataTobePlotted);
}
self.plotData = dataTobePlotted;
CPTGraph *graph = FESubView.hostedGraph;
[graph applyTheme:[CPTTheme themeNamed:kCPTStocksTheme]];
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
//create plot
CPTScatterPlot *fePlot = [[CPTScatterPlot alloc]init];
fePlot.dataSource = self;
CPTColor *feColor = [CPTColor greenColor];
[graph addPlot:fePlot];
//setup plot space
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects: fePlot,Nil]];
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromString(#"3.0") length:CPTDecimalFromString(#"10.0")];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromString(#"8.0") length:CPTDecimalFromString(#"2.0")];
//set up plot space
//[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:fePlot,nil]];
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
[xRange expandRangeByFactor:CPTDecimalFromCGFloat(2.0f)];
plotSpace.xRange = xRange;
CPTMutablePlotRange *yRange = [plotSpace.yRange mutableCopy];
[yRange expandRangeByFactor:CPTDecimalFromCGFloat(5.0f)];
plotSpace.yRange = yRange;
// //create styles and symbols
CPTMutableLineStyle *feLineStyle = [fePlot.dataLineStyle mutableCopy];
CPTColor *areaColor = [CPTColor colorWithComponentRed:0.3 green:1.0 blue:0.3 alpha:0.3];
CPTGradient *areaGradient = [CPTGradient gradientWithBeginningColor:areaColor endingColor:[CPTColor clearColor]];
areaGradient.angle = -90.0f;
CPTFill *areaGradientFill = [CPTFill fillWithGradient:areaGradient];
fePlot.areaFill = areaGradientFill;
feLineStyle.lineWidth = 2.5;
feLineStyle.lineColor = feColor;
fePlot.dataLineStyle = feLineStyle;
CPTMutableLineStyle *feSymbolLineStyle = [CPTMutableLineStyle lineStyle];
feSymbolLineStyle.lineColor = feColor;
CPTPlotSymbol *feSymbol = [CPTPlotSymbol ellipsePlotSymbol];
feSymbol.fill = [CPTFill fillWithColor:feColor];
feSymbol.lineStyle = feSymbolLineStyle;
feSymbol.size = CGSizeMake(6.0f, 6.0f);
fePlot.plotSymbol = feSymbol;
}
- (void)configureAxis
{
// 1 - Create styles
// 2 - Get axis set
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor whiteColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 12.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [CPTColor whiteColor];
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor whiteColor];
axisTextStyle.fontName = #"Helvetica-Bold";
axisTextStyle.fontSize = 11.0f;
CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor whiteColor];
tickLineStyle.lineWidth = 2.0f;
CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor blackColor];
tickLineStyle.lineWidth = 1.0f;
CPTMutableTextStyle *labelXTextStyle = [CPTMutableTextStyle textStyle];
labelXTextStyle.fontName = #"Helvetica";
labelXTextStyle.fontSize = 10;
labelXTextStyle.color = [CPTColor whiteColor];
// 2 - Get Axis Set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) FESubView.hostedGraph.axisSet;
// 3 Configure x-Axis
CPTXYAxis *x = axisSet.xAxis;
x.orthogonalCoordinateDecimal = CPTDecimalFromString(#"4");
x.title = #"Date";
x.titleTextStyle = axisTitleStyle;
x.titleOffset = 47.0f;
//x.title = #"Date";
x.minorTicksPerInterval = 0;
x.majorTickLength = 10.0f;
x.tickDirection = CPTSignPositive;
//NSArray *customTickLocations = [NSArray arrayWithObjects:[NSDecimalNumber numberWithInt:5], [NSDecimalNumber numberWithInt:10], [NSDecimalNumber numberWithInt:10], [NSDecimalNumber numberWithInt:15],
// [NSDecimalNumber numberWithInt:20], [NSDecimalNumber numberWithInt:25],[NSDecimalNumber numberWithInt:30],nil];
NSInteger i;
NSMutableArray *customTickLocations = [NSMutableArray array];
for (i = 0; i < [[self.fullTransaction valueForKey:#"tDate"]count];i++)
{
[customTickLocations addObject:[NSDecimalNumber numberWithInt:((i+1)*5)]];
}
CPTPlotRange *xAxisRange=[CPTPlotRange plotRangeWithLocation:CPTDecimalFromString(#"0.0") length:CPTDecimalFromString(#"24.0")];
x.visibleRange=xAxisRange;
NSLog(#"dates are %#", [self.fullTransaction valueForKey:#"tDate"]);
NSLog(#"Transaction FE %#", [self.fullTransaction valueForKey:#"tFuelEconomy"]);
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[self.plotData count]];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"dd-MMM-YYY"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT+0:07"]];
NSMutableSet *xLocations = [NSMutableSet setWithCapacity:[[self.fullTransaction valueForKey:#"tDate"]count]];
x.labelingPolicy=CPTAxisLabelingPolicyNone;
x.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:#"1"] decimalValue];
NSInteger location;
for (location = 0; location < [[self.fullTransaction valueForKey:#"tDate"]count];location++)
{
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText: [dateFormatter stringFromDate:[[self.fullTransaction valueForKey:#"tDate"] objectAtIndex:location]] textStyle:labelXTextStyle];
NSLog(#"Custom Labels = %#",newLabel);
NSLog(#"Real Date = %#",[[self.fullTransaction valueForKey:#"tDate"] objectAtIndex:location]);
NSLog(#"After assigned date = %#",[dateFormatter stringFromDate:[[self.fullTransaction valueForKey:#"tDate"] objectAtIndex:location]]);
newLabel.tickLocation = CPTDecimalFromInt([[customTickLocations objectAtIndex:location] integerValue]);
newLabel.offset = 2;
newLabel.rotation = (1*M_PI)/4;
[customLabels addObject:newLabel];
[xLocations addObject:[NSNumber numberWithInteger:[[customTickLocations objectAtIndex:location] integerValue]]];
}
x.axisLabels = [NSSet setWithArray:customLabels];
NSLog(#"Custom Labels = %#",customLabels);
x.majorTickLocations = xLocations;
//x.majorTickLocations = customTickLocations;
x.majorTickLength = 5.0f;
NSLog(#"Major TickLocations: %#",customTickLocations);
CPTXYAxis *y = axisSet.yAxis;
//y.orthogonalCoordinateDecimal = CPTDecimalFromCGFloat(0.0);
y.majorIntervalLength = CPTDecimalFromString(#"1.0");
y.minorTicksPerInterval = 5;
y.majorTickLength = 5.0f;
y.preferredNumberOfMajorTicks = 5;
y.labelTextStyle = labelXTextStyle;
}
The following is the result of nslog for the id x and id y data
2014-02-25 16:09:01.855 Fuel Eco[12079:70b] x is : 31-Jan-2014
2014-02-25 16:09:01.855 Fuel Eco[12079:70b] y is : 10
2014-02-25 16:09:01.855 Fuel Eco[12079:70b] int X is 0
2014-02-25 16:09:01.856 Fuel Eco[12079:70b] int Y is 1
2014-02-25 16:09:01.856 Fuel Eco[12079:70b] ScatterPlotField X is 0
2014-02-25 16:09:01.856 Fuel Eco[12079:70b] ScatterPlotField Y is 1
2014-02-25 16:09:01.857 Fuel Eco[12079:70b] Data to be Plotted: (
{
0 = "31-Jan-2014";
1 = 10;
}
)
2014-02-25 16:09:01.857 Fuel Eco[12079:70b] x is : 02-Feb-2014
2014-02-25 16:09:01.857 Fuel Eco[12079:70b] y is : 10.07
2014-02-25 16:09:01.858 Fuel Eco[12079:70b] int X is 0
2014-02-25 16:09:01.858 Fuel Eco[12079:70b] int Y is 1
2014-02-25 16:09:01.858 Fuel Eco[12079:70b] ScatterPlotField X is 0
2014-02-25 16:09:01.859 Fuel Eco[12079:70b] ScatterPlotField Y is 1
2014-02-25 16:09:01.859 Fuel Eco[12079:70b] Data to be Plotted: (
{
0 = "31-Jan-2014";
1 = 10;
},
{
0 = "02-Feb-2014";
1 = "10.07";
}
)
2014-02-25 16:09:01.859 Fuel Eco[12079:70b] x is : 24-Feb-2014
2014-02-25 16:09:01.860 Fuel Eco[12079:70b] y is : 8.75
2014-02-25 16:09:01.860 Fuel Eco[12079:70b] int X is 0
2014-02-25 16:09:01.860 Fuel Eco[12079:70b] int Y is 1
2014-02-25 16:09:01.861 Fuel Eco[12079:70b] ScatterPlotField X is 0
2014-02-25 16:09:01.861 Fuel Eco[12079:70b] ScatterPlotField Y is 1
2014-02-25 16:09:01.861 Fuel Eco[12079:70b] Data to be Plotted: (
{
0 = "31-Jan-2014";
1 = 10;
},
{
0 = "02-Feb-2014";
1 = "10.07";
},
{
0 = "24-Feb-2014";
1 = "8.75";
}
)
Below is the result of the nslog to show the result of "- (NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx" with the data,idx,fieldEnum.
2014-02-25 16:09:01.862 Fuel Eco[12079:70b] Number of Records for Plot = 3
2014-02-25 16:09:01.862 Fuel Eco[12079:70b] Number of Records for Plot = 3
2014-02-25 16:09:01.863 Fuel Eco[12079:70b] Number tobe Plot with index = 31-Jan-2014 0, 0
2014-02-25 16:09:01.863 Fuel Eco[12079:70b] Number tobe Plot with index = 02-Feb-2014 1, 0
2014-02-25 16:09:01.863 Fuel Eco[12079:70b] Number tobe Plot with index = 24-Feb-2014 2, 0
2014-02-25 16:09:01.864 Fuel Eco[12079:70b] Number of Records for Plot = 3
2014-02-25 16:09:01.864 Fuel Eco[12079:70b] Number tobe Plot with index = 10 0, 1
2014-02-25 16:09:01.864 Fuel Eco[12079:70b] Number tobe Plot with index = 10.07 1, 1
2014-02-25 16:09:01.865 Fuel Eco[12079:70b] Number tobe Plot with index = 8.75 2, 1
2014-02-25 16:09:01.865 Fuel Eco[12079:70b] Number of Records for Plot = 3
Thanks all
UPDATE ***
I rewrote the code to become like this, and it works:
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
switch (fieldEnum)
{
case CPTScatterPlotFieldX:
{
NSDecimalNumber *num = [[plotData objectAtIndex:index] objectForKey:[NSNumber numberWithInt:fieldEnum]];
return num;
}
case CPTScatterPlotFieldY:
{
if ([plot.identifier isEqual:#"Honda Plot"])
{
NSDecimalNumber *num = [[plotData1 objectAtIndex:index] objectForKey:[NSNumber numberWithInt:fieldEnum]];
return num;
}
else
{
NSDecimalNumber *num = [[plotData objectAtIndex:index] objectForKey:[NSNumber numberWithInt:fieldEnum]];
return num;
}
}
}
return nil;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self fetchResult];
[self filterarray];
[self filterArray1];
//CGRect frame1 = CGRectMake(0,200,300,600);
[self generateData];
//FESubView = [[CPTGraphHostingView alloc]initWithFrame:frame1];
[self renderInLayer:FESubView withTheme:Nil animated:NO];
}
-(void)generateData
{
if ( !plotData ) {
//const NSTimeInterval oneDay = 24 * 60 * 60 ;
gregorian = [self setCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[self.fullTransaction valueForKey:#"tDate" ] objectAtIndex:0]];
NSDate *refDate = [gregorian dateFromComponents:dateComponents];
NSDate *dataDate = [[NSDate alloc]init];
NSDateComponents *comps;
int days;
// Add some data
NSMutableArray *newData = [NSMutableArray array];
NSMutableArray *newData1 = [NSMutableArray array];
NSUInteger i;
for ( i = 0; i < [[self.fullTransaction valueForKey:#"tDate"]count]; i++ ) {
dataDate = [[self.fullTransaction valueForKey:#"tDate"]objectAtIndex:i];
NSLog(#"RefDate is: %#",refDate);
NSLog(#"DateDate is: %#",dataDate);
comps = [gregorian components:NSDayCalendarUnit fromDate:refDate toDate:dataDate options:0];
days = [comps day];
NSTimeInterval x = oneDay *days;
//id y = [[self.fullTransaction valueForKey:#"tFuelEconomy"]objectAtIndex:i];
int counts = [self.filteredTransaction count];
id y;
id z;
int count1 = [self.filteredTransaction1 count];
if (i < counts)
{
y = [[self.filteredTransaction valueForKey:#"tFuelEconomy"]objectAtIndex:i];
}else y = NULL;
if (i < count1)
{
z = [[self.filteredTransaction1 valueForKey:#"tFuelEconomy"]objectAtIndex:i];
}else z = NULL;
[newData addObject:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSDecimalNumber numberWithFloat:x], [NSNumber numberWithInt:CPTScatterPlotFieldX],
y, [NSNumber numberWithInt:CPTScatterPlotFieldY],
nil]];
[newData1 addObject:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSDecimalNumber numberWithFloat:x], [NSNumber numberWithInt:CPTScatterPlotFieldX],
z, [NSNumber numberWithInt:CPTScatterPlotFieldY],
nil]];
}
plotData = newData;
plotData1 = newData1;
NSLog(#"Data are: %#",plotData);
NSLog(#"Data are: %#",plotData1);
}
}
-(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme animated:(BOOL)animated
{
// If you make sure your dates are calculated at noon, you shouldn't have to
// worry about daylight savings. If you use midnight, you will have to adjust
// for daylight savings time.
CGRect frame1 = CGRectMake(10,150,320,250);
FESubView = [[CPTGraphHostingView alloc]initWithFrame:frame1];
FESubView.allowPinchScaling = YES;
[self.view addSubview:FESubView];
//NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
gregorian = [self setCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[self.fullTransaction valueForKey:#"tDate" ] objectAtIndex:0]];
NSDate *refDate = [gregorian dateFromComponents:dateComponents];
NSLog(#"RefDate is :%#",refDate);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
CGRect bounds = layerHostingView.bounds;
#else
CGRect bounds = NSRectToCGRect(layerHostingView.bounds);
#endif
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:bounds];
[graph applyTheme:[CPTTheme themeNamed:kCPTDarkGradientTheme]];
FESubView.hostedGraph = graph;
graph.title = #"Fuel Economy Graph";
CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle];
titleStyle.color = [CPTColor whiteColor];
titleStyle.fontName = #"Helvetica-Bold";
titleStyle.fontSize = 14.0f;
graph.titleTextStyle = titleStyle;
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
graph.titleDisplacement = CGPointMake(0.0f, 10.0f);
// 4 - Set padding for plot area
[graph.plotAreaFrame setPaddingLeft:40.0f];
[graph.plotAreaFrame setPaddingBottom:65.0f];
[graph.plotAreaFrame setPaddingTop:3.0f];
[graph.plotAreaFrame setPaddingRight:3.0f];
graph.legend = [CPTLegend legendWithGraph:graph];
graph.legend.fill = [CPTFill fillWithColor:[CPTColor darkGrayColor]];
graph.legend.cornerRadius = 5.0;
graph.legend.swatchSize = CGSizeMake(25.0, 25.0);
graph.legendAnchor = CPTRectAnchorCenter;
graph.legendDisplacement = CGPointMake(2.40, 12.0);
// Setup scatter plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
NSTimeInterval xLow = 0.0f;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(xLow) length:CPTDecimalFromFloat(oneDay * 10)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(5.0) length:CPTDecimalFromFloat(10.0f)];
//symbol
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
[xRange expandRangeByFactor:CPTDecimalFromCGFloat(1)];
//
plotSpace.allowsUserInteraction = YES;
// Create a plot that uses the data source method
CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];
dataSourceLinePlot.identifier = #"Nisan Plot";
CPTColor *feColor = [CPTColor redColor];
CPTMutableLineStyle *feLineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy];
feLineStyle.lineWidth = 2.5;
feLineStyle.lineColor = feColor;
dataSourceLinePlot.dataLineStyle = feLineStyle;
CPTMutableLineStyle *feSymbolLineStyle = [CPTMutableLineStyle lineStyle];
feSymbolLineStyle.lineColor = feColor;
CPTPlotSymbol *feSymbol = [CPTPlotSymbol ellipsePlotSymbol];
feSymbol.fill = [CPTFill fillWithColor:feColor];
feSymbol.lineStyle = feSymbolLineStyle;
feSymbol.size = CGSizeMake(6.0f, 6.0f);
dataSourceLinePlot.plotSymbol = feSymbol;
CPTMutableTextStyle *feLabelStyle = [CPTMutableTextStyle textStyle];
feLabelStyle.fontSize = 10;
feLabelStyle.color = [CPTColor whiteColor];
dataSourceLinePlot.labelTextStyle = feLabelStyle;
dataSourceLinePlot.title = #"Nissan Terano";
dataSourceLinePlot.dataSource = self;
[graph addPlot:dataSourceLinePlot];
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor whiteColor];
axisTextStyle.fontName = #"Helvetica-Bold";
axisTextStyle.fontSize = 8.0f;
CPTScatterPlot *dataSourceLinePlot1 = [[CPTScatterPlot alloc] init];
dataSourceLinePlot1.identifier = #"Honda Plot";
CPTColor *feColor1 = [CPTColor blueColor];
CPTMutableLineStyle *feLineStyle1 = [dataSourceLinePlot1.dataLineStyle mutableCopy];
feLineStyle1.lineWidth = 2.5;
feLineStyle1.lineColor = feColor1;
dataSourceLinePlot1.dataLineStyle = feLineStyle1;
CPTMutableLineStyle *feSymbolLineStyle1 = [CPTMutableLineStyle lineStyle];
feSymbolLineStyle1.lineColor = feColor1;
CPTPlotSymbol *feSymbol1 = [CPTPlotSymbol ellipsePlotSymbol];
feSymbol1.fill = [CPTFill fillWithColor:feColor1];
feSymbol1.lineStyle = feSymbolLineStyle1;
feSymbol1.size = CGSizeMake(6.0f, 6.0f);
dataSourceLinePlot1.plotSymbol = feSymbol1;
//CPTTextStyle *test = [CPTTextStyle textStyle];
//test.fontSize = 12;
CPTMutableTextStyle *feLabelStyle1 = [CPTMutableTextStyle textStyle];
feLabelStyle1.fontSize = 10;
feLabelStyle1.color = [CPTColor whiteColor];
dataSourceLinePlot1.labelTextStyle = feLabelStyle1;
dataSourceLinePlot1.dataSource = self;
[graph addPlot:dataSourceLinePlot1];
dataSourceLinePlot1.title = #"Honda Jazz";
//
// Axes
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPTDecimalFromFloat(oneDay);
x.orthogonalCoordinateDecimal = CPTDecimalFromString(#"5");
x.minorTicksPerInterval = 0;
x.labelTextStyle = axisTextStyle;
//x.axisLineStyle = axisLineStyle;
//x.axisLineStyle = feLabelStyle;
dateFormatter = [self setDateFormatterLabel];
//dateFormatter.dateStyle = kCFDateFormatterShortStyle;
CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
timeFormatter.referenceDate = refDate;
x.labelFormatter = timeFormatter;
x.labelRotation = M_PI / 4;
x.tickLabelDirection = CPTSignPositive;
x.tickDirection = CPTSignPositive;
//x.labelTextStyle = feLabelStyle;
//x.visibleRange=plotSpace.xRange;
x.labelOffset = -70;
CPTXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPTDecimalFromString(#"5.0");
y.minorTicksPerInterval = 10;
y.orthogonalCoordinateDecimal = CPTDecimalFromString(#"-1");
}
I'm not sure what you mean. Can you explain the question more clearly?
You never add any locations to the xLocations set. If the customTickLocations array contains all of the locations you need, just set the tick locations directly:
x.majorTickLocations = [NSSet setWithArray:customTickLocations];
Why are you using -expandRangeByFactor:? If you know the plot range you want, just set it directly:
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0)
length:CPTDecimalFromDouble(10.0)];

How to dynamically change Core Plot‘s label

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.

Core plot majorIntervalLength : unable to make it work

am trying to plot a simple graph (cannot be so tough! I have used core plot successfully before!). I have some dates to be plotted in the x-axis. And some small float values in the y-axis, like 0.139503, 0.139481, etc. I have to plot 5 such values (which I fetch from the backend).
For the y-axis range, am finding the lowest of these values and setting it as the start of the y-axis range. And am setting the majorIntervalLength to (highestValue - LowestValue)/5, which is (for example) 0.007946. But the y-axis interval seems to be fixed at interval of 1. So, since my y-axis values are really small (difference between them is in the order of 0.01), all plots are being drawn at y=0.0. Here's the code snippet :
-(void) 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 = 2.0;
graph.paddingRight = 2.0;
graph.paddingTop = 2.0;
graph.paddingBottom = 2.0;
graph.title = #"Graph Plot";
// plotting style is set to line plots
CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.lineColor = [CPTColor blackColor];
lineStyle.lineWidth = 2.0f;
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.graph.axisSet;
axisSet.xAxis.majorTickLineStyle = lineStyle;
axisSet.xAxis.majorTickLength = 7.0f;
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyEqualDivisions;
axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyEqualDivisions;
axisSet.xAxis.labelRotation = 90.0;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) self.graph.defaultPlotSpace;
// Determine the lowest and highest values to be plotted in Y Axis)
CGFloat yLow = 0.1;
CGFloat yHigh = yLow;
for (int i=0 ; i<self.dict.count ; i++) {
MyCustomObject *myData = (MyCustomObject *) [dict objectForKey:
[self.arrayKeys objectAtIndex:i]];
if (myData.mem < yLow) {
yLow = myData.mem;
}
if (yHigh < myData.mem) {
yHigh = myData.mem;
}
}
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0)
length:CPTDecimalFromFloat(5)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(yLow)
length:CPTDecimalFromFloat(5)];
// To determine the point where your graph starts
//axisSet.yAxis.orthogonalCoordinateDecimal = CPTDecimalFromFloat(yLow);
axisSet.yAxis.majorIntervalLength = CPTDecimalFromCGFloat((yHigh-yLow)/5.0);
NSLog(#"Y axis interval : %f", (yHigh-yLow)/5.0);
...
}
-(NSNumber *) numberForPlot:(CPTPlot *)plot
field:(NSUInteger)fieldEnum
recordIndex:(NSUInteger)index {
if ( fieldEnum == CPTScatterPlotFieldY ) {
return [NSNumber numberWithFloat:myData.mem];
} else {
return [NSNumber numberWithInt:index];
}
}
Why is that the majorIntervalLength for y axis that am setting not working?
are you setting the axisSet.yAxis.majorTickLength anywhere? i don't see it in your code above.
if the majorTickLength is nil nothing will show up for the tick's.
Setting length of yRange (as Erik Skroch suggested) to (yHigh-yLow) helped

Core plot : ios show two y axis and ScaterPlot and Bar Plot in Same CPTGraph

Hi please guide me write way to show two Y axis (left side and right side) with one x axis using core plot , and also i have to draw Scaterplot and barplot both in single CPTGraph.
CPTScatter plot show on right side Y axis with -ve direction .
My Code snippet
-(void)configureAxes
{
// 1 - Configure styles
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor whiteColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 8.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = 2.0f;
axisLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:1];
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor whiteColor];
axisTextStyle.fontName = #"Helvetica-Bold";
axisTextStyle.fontSize = 8.0f;
CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor whiteColor];
tickLineStyle.lineWidth = 2.0f;
CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor blackColor];
tickLineStyle.lineWidth = 1.0f;
// 2 - Get the graph's axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;
// 3 - Configure the x-axis
// axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
// axisSet.xAxis.title = #"";
// axisSet.xAxis.labelAlignment = CPTAlignmentRight;
// axisSet.xAxis.titleTextStyle = axisTitleStyle;
// axisSet.xAxis.titleOffset = 38.0f;
// axisSet.xAxis.axisLineStyle = axisLineStyle;
// axisSet.xAxis.labelTextStyle = axisTextStyle;
CGFloat dateCount = [self.arrayData count];
NSMutableSet *xLabels = [NSMutableSet setWithCapacity:dateCount];
NSMutableSet *xLocations = [NSMutableSet setWithCapacity:dateCount];
NSInteger i = 0;
for (ResolutionData *d in self.arrayData)
{
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[[d.appName componentsSeparatedByString:#"-"]objectAtIndex:0] textStyle:axisSet.xAxis.labelTextStyle];
// [label setRotation:45.0];
CGFloat location = i++;
label.tickLocation = CPTDecimalFromCGFloat(location);
label.offset = axisSet.xAxis.majorTickLength;
if (label) {
[xLabels addObject:label];
[xLocations addObject:[NSNumber numberWithFloat:location]];
}
}
axisSet.xAxis.axisLabels = xLabels;
axisSet.xAxis.majorTickLocations = xLocations;
// 4 - Configre the y-axis
CPTAxis *y = axisSet.yAxis;
y.title = #"count";
y.labelAlignment = CPTAlignmentCenter;
y.titleTextStyle = axisTitleStyle;
y.titleOffset = -40.0f;
y.axisLineStyle = axisLineStyle;
y.majorGridLineStyle = gridLineStyle;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelTextStyle = axisTextStyle;
y.labelOffset = 16.0f;
y.majorTickLineStyle = axisLineStyle;
// y.majorTickLength = 4.0f;
// y.minorTickLength = 2.0f;
y.tickDirection = CPTSignPositive;
NSInteger majorIncrement = 20;
NSInteger minorIncrement = 10;
CGFloat yMax = 100.0f; // should determine dynamically based on max price
NSMutableSet *yLabels = [NSMutableSet set];
NSMutableSet *yMajorLocations = [NSMutableSet set];
NSMutableSet *yMinorLocations = [NSMutableSet set];
int x =1;
for (NSInteger j = minorIncrement; j <= yMax; j += minorIncrement) {
NSUInteger mod = j % majorIncrement;
if (mod == 0) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"%i", x] textStyle:y.labelTextStyle];
[label setAlignment:CPTAlignmentTop];
NSDecimal location = CPTDecimalFromInteger(j);x++;
label.tickLocation = location;
label.offset = -y.majorTickLength - y.labelOffset;
if (label) {
[yLabels addObject:label];
}
[yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];
} else {
[yMinorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:CPTDecimalFromInteger(j)]];
}
}
y.axisLabels = yLabels;
y.majorTickLocations = yMajorLocations;
y.minorTickLocations = yMinorLocations;
}
Please help me.
Create a new y-axis object, configure it as desired, and add it to the axis set.
axisSet.axes = [NSArray arrayWithObjects:x, y, y2, nil];
If you want a different scale for the right y-axis, you need another plot space. Create a new one, configure it, set the xRange to the same xRange as the default plot space, and add it to the graph. Make sure the new y-axis has its plotSpace set to the new plot space object.
CPTXYPlotSpace *oldPlotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
CPTXYPlotSpace *newPlotSpace = [[[CPTXYPlotSpace alloc] init] autorelease];
newPlotSpace.xRange = oldPlotSpace.xRange;
newPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:/* location */
length:/* length */];
[graph addPlotSpace:linearPlotSpace];
See the "Axis Demo" and "Plot Space Demo" in the Plot Gallery example app for sample code.

OBJ-C: Getting the minimum/maximum value in a NSMutableArray

I want to get the maximum and minimum values of a NSMutableArray so I can create a core-plot plotspace and graph based around those max and min values.
My code is as follows:
NSMutableArray *contentArray = [NSMutableArray arrayWithCapacity:100];
NSUInteger i;
for (i=0; i<60; i++){
id x = [NSNumber numberWithFloat:i*0.05];
id y = [NSNumber numberWithFloat:1.2*rand()/(float)RAND_Max + 0.6];
[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, #"x", y, #"y", nil]];
}
self.dataForPlot = contentArray;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat() length:CPDecimalFromFloat()];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat() length:CPDecimalFromFloat()];
What do I fill in the blanks for xRange and yRange assignment if I want the graph to span only the space of what's specified in contentArray?
In this case, you should use -[CPPlotSpace scaleToFitPlots:]. For more general calculations on array values, read on...
This is an ideal use for Key-Value coding and associated array operators. In your example,
float maxX = [[contentArray valueForKeyPath:#"#max.x"] floatValue];
float minY = [[contentArray valueForKeyPath:#"#min.x"] floatValue];
float maxY = [[contentArray valueForKeyPath:#"#max.y"] floatValue];
float minY = [[contentArray valueForKeyPath:#"#min.y"] floatValue];
The array operators call valueForKeyPath: on the contentArray which gives an array built by calling the same valueForKeyPath: on each member of the array with the key path to the right of the array operator (i.e. #min and #max). The orignal call then applies the given operator to the resulting array. You could easily define a category on NSArray to give you back a struct of min/max values:
typedef struct {
float minX;
float minY;
float maxX;
float maxY;
} ArrayValueSpace;
#implementation NSArray (PlotSpaceAdditions)
- (ArrayValueSpace)psa_arrayValueSpace {
ArrayValueSpace result;
result.maxX = [[contentArray valueForKeyPath:#"#max.x"] floatValue];
result.minX = [[contentArray valueForKeyPath:#"#min.x"] floatValue];
result.maxY = [[contentArray valueForKeyPath:#"#max.y"] floatValue];
result.minY = [[contentArray valueForKeyPath:#"#min.y"] floatValue];
return result;
}
You can find max and min values when you fill it, but it would work just when used in your snippet. If you want something more generic you should simply go through the list and searching for it.
// contentArray already defined
int maxX = 0, minX = 1000, maxY = 0, minY = 1000;
for (int i = 0; i < [contentArray count]; ++1)
{
int curX = [[[contentArray objectForKey:#"x"] objectAtIndex:i] integerValue];
int curY = [[[contentArray objectForKey:#"y"] objectAtIndex:i] integerValue];
if (curX < minX)
minX = curX;
else if (curX > maxX)
maxX = curX;
if (curY < minY)
minY = curY;
else if (curY > maxY)
maxY = curY;
}
You could use fast enumeration through the array.
.
NSUInteger maxX = 0;
NSUInteger minX = 0xFFFFFFFF; //(for 32 bit)
NSUInteger maxY = 0;
NSUInteger minY = 0xFFFFFFFF; //(for 32 bit)
for ( NSDictionary *dict in contentArray )
{
NSUInteger newX = [[dict objectForKey:#"x"] integerValue];
NSUInteger newY = [[dict objectForKey:#"y"] integerValue];
if (maxX > newX) maxX = newX;
if (minX > newX) minX = newX;
if (maxY > newY) maxY = newY;
if (minY > newY) minX = newY;
}
if you have NSMutableArray of NSDictionary objects you can use this:
-(float)findMax:array arrayKey:obj {
float max = [[[array objectAtIndex:0] objectForKey:obj] floatValue];
for ( NSDictionary *dict in array ) {
if(max<[[dict objectForKey:obj] floatValue])max=[[dict objectForKey:obj] floatValue];
}
return max;
}
-(float)findMin:array arrayKey:obj {
float min = [[[array objectAtIndex:0] objectForKey:obj] floatValue];
for ( NSDictionary *dict in array ) {
if (min > [[dict objectForKey:obj] floatValue])min = [[dict objectForKey:obj] floatValue];
}
return min;
}
You would access methods like this if in another class:
GraphData *c=[[GraphData alloc] init];
float maxY=[c findMax:plotData arrayKey:[NSNumber numberWithInt:1]]; //1 or 0 depending on axis
[c release];
//This gives Max and Min Value in NSMutableArrray
-(void)FindingMinAndMaxValueInNSMutableArray{
NSMutableArray *array=[[NSMutableArray alloc]initWithObjects:#"0.987",#"0.951",#"0.881",#"0.784",#"0.662",#"0.522",#"0.381",#"-0.265",#"-0.197", #"0.189",#"-0.233",#"0.310",#"0.402",#"0.402",#"0.988",#"0.633",#"0.661",#"0.656",#"0.617",#"0.634",#"0.690",#"0.767",#"0.836",nil];
NSLog(#"The Array Value is %#",array);
NSLog(#"The Array Count is %lu",(unsigned long)array.count);
NSNumber *maxValue = [array valueForKeyPath:#"#max.doubleValue"];
NSLog(#"The maxValue is %#",maxValue);
NSString *str=[NSString stringWithFormat:#"%#",maxValue];
NSInteger path=[array indexOfObject:str];
NSIndexPath *indexpath=[NSIndexPath indexPathForItem:path inSection:0];
NSLog(#"Max Value = %# and index = %ld",maxValue,(long)indexpath.row);
NSNumber *minValue = [array valueForKeyPath:#"#min.doubleValue"];
NSLog(#"The minValue is %#",minValue);
NSString *str1 = [NSString stringWithFormat:#"%#",minValue];
NSInteger path1 = [array indexOfObject:str1];
NSIndexPath *indexPath1 = [NSIndexPath indexPathForItem:path1 inSection:0];
NSLog(#"Min Value =%# and index = %ld",minValue,(long)indexPath1.row);
}