问题
how to plot months of the year on x-axis using core plot and on y-axis i need multiples of 200 morever this data i used to get from an excel sheet.can anyone help me out from this. Thanks in advance....
回答1:
Here is some sample code taken from a recent project. My x-axis data was an array of NSDates. I set up my axisSet as normal, and then added the following code below:
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
NSMutableArray *countingXPoints=[[NSMutableArray alloc] init];
NSMutableArray *datesAsStrings=[[NSMutableArray alloc] init];
NSDateFormatter *df=[[NSDateFormatter alloc] init];
[df setDateFormat:@"MM-yy"];
for(int i=0; i<[self.xAxisData count]; i++)
{
[countingXPoints addObject:[NSNumber numberWithInt:i]];
[datesAsStrings addObject:[df stringFromDate:[self.xAxisData objectAtIndex:i]]];
}
NSArray *xCustomTickLocations = [NSArray arrayWithArray:(NSArray *)countingXPoints];
NSArray *xAxisLabels = [NSArray arrayWithArray:(NSArray *) datesAsStrings];
NSUInteger xLabelLocation = 0;
NSMutableArray *xCustomLabels = [[NSMutableArray alloc] initWithCapacity:[xAxisLabels count]];
for (NSNumber *xTickLocation in xCustomTickLocations)
{
CPTAxisLabel *newXLabel = [[CPTAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:xLabelLocation++] textStyle:axisSet.xAxis.labelTextStyle];
newXLabel.tickLocation = [xTickLocation decimalValue];
newXLabel.offset = 0.0f;
newXLabel.rotation = M_PI/4.0;
[xCustomLabels addObject:newXLabel];
}
axisSet.xAxis.axisLabels=[NSSet setWithArray:xCustomLabels];
For the y-axis part of your question, you can adjust the tick intervals (attributes of CPTXYAxis). To achieve the correct axis height/length, take a look at the xRange, yRange, globalXRange, and globalYRance attributes of your plotspace.
回答2:
i have done something you want like this code. Sorry i don't make it clear code here but just pasting whole method what i am using here.
i hope this may help what you want. Here i have implemented graph in new way that you can refresh it like tableview. just change values of array then call [graph reloadData];
- (void)constructScatterPlotForFeedback
{
// Create graph from theme
[graph release];
graph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
graph.delegate = self;
CPTheme *theme = [CPTheme themeNamed:kCPPlainWhiteTheme];
[graph applyTheme:theme];
feedbackChart.hostedGraph = graph;
[feedbackChart setBackgroundColor:[UIColor clearColor]];
graph.paddingLeft = 0.0;
graph.paddingTop = 0.0;
graph.paddingRight = 0.0;
graph.paddingBottom = 0.0;
graph.plotAreaFrame.paddingLeft = 5.0;
graph.plotAreaFrame.paddingTop = 10.0;
graph.plotAreaFrame.paddingRight = 10.0;
graph.plotAreaFrame.paddingBottom = 10.0;
NSTimeInterval oneHour = 60 * 60;
// Setup plot space
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.delegate = self;
float xRange;
xRange = [chartData count] + 1.0;
if (xRange>5) {
xRange = 5.0;
}
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:CPDecimalFromFloat(fiveHour*3)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-20.0) length:CPDecimalFromFloat(40.0)];
CPLineStyle *gridline = [CPLineStyle lineStyle];
gridline.lineColor = [CPColor grayColor];
gridline.lineWidth = 1.0f;
// Axes
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPXYAxis *x = axisSet.xAxis;
// x.orthogonalCoordinateDecimal = CPDecimalFromString(@"0");
x.majorIntervalLength = CPDecimalFromFloat(fiveHour);
//x.majorIntervalLength = CPDecimalFromFloat(10.0);
//x.majorIntervalLength = CPDecimalFromString(@"10");
x.minorTicksPerInterval = 0;
x.labelOffset=0;
// x.labelingPolicy = CPAxisLabelingPolicyNone;
NSDate *refDate = [NSDate date];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
// dateFormatter.dateStyle = kCFTimeZoneNameStyleShortGeneric;
dateFormatter.dateFormat = @"HH:mm:ss";
// dateFormatter.dateStyle = kCFDateFormatterShortStyle;
CPTimeFormatter *timeFormatter = [[[CPTimeFormatter alloc] init WithDateFormatter:dateFormatter] autorelease];
timeFormatter.referenceDate = refDate;
x.labelFormatter = timeFormatter;
//NSLog(@"refence date : %@", timeFormatter);
CPXYAxis *y = axisSet.yAxis;
y.minorTicksPerInterval = 0;
y.orthogonalCoordinateDecimal = CPDecimalFromString(@"0.0");
y.majorIntervalLength = CPDecimalFromString(@"5");
y.majorGridLineStyle = nil;
//y.visibleRect
y.visibleRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-20.0f) length:CPDecimalFromFloat(40.0f)];
CPConstraints yConstraints = {CPConstraintNone, CPConstraintFixed};
y.isFloatingAxis=YES;
y.constraints=yConstraints;
// Create a green plot area
CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = @"FeedBack Plot";
dataSourceLinePlot.dataLineStyle.lineWidth = 3.f;
dataSourceLinePlot.dataLineStyle.lineColor = [CPColor blackColor];
dataSourceLinePlot.dataLineStyle.dashPattern = [NSArray arrayWithObjects:[NSNumber numberWithFloat:1.0f], [NSNumber numberWithFloat:1.0f], nil];
dataSourceLinePlot.dataSource = self;
// Animate in the new plot, as an example
dataSourceLinePlot.opacity = 0.0f;
dataSourceLinePlot.cachePrecision = CPPlotCachePrecisionDecimal;
CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeInAnimation.duration = 1.0f;
fadeInAnimation.removedOnCompletion = NO;
fadeInAnimation.fillMode = kCAFillModeForwards;
fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0];
[dataSourceLinePlot addAnimation:fadeInAnimation forKey:@"animateOpacity"];
CPColor *areaColor1 = [CPColor colorWithComponentRed:0.3 green:0.3 blue:1.0 alpha:0.8];
CPGradient *areaGradient1 = [CPGradient gradientWithBeginningColor:areaColor1 endingColor:[CPColor clearColor]];
areaGradient1.angle = -90.0f;
NSUInteger i;
[graph addPlot:dataSourceLinePlot];
NSMutableArray *contentArray1 = [NSMutableArray arrayWithCapacity:100];
NSMutableArray *customTickLocations = [[NSMutableArray alloc] init];
NSMutableArray *xAxisLabels = [[NSMutableArray alloc] init];
for ( i = 0; i < [chartData count]; i++ ) {
//for ( i = 0; i < 10; i++ ) {
[customTickLocations addObject:[NSDecimalNumber numberWithInt:i]];
[xAxisLabels addObject:[NSString stringWithFormat:@"%0.1f", 5.0 * i]];
Pulse *objPulse1 = (Pulse *)[chartData objectAtIndex:i];
//id x = [NSNumber numberWithFloat:i*fiveHour];
id x = [NSNumber numberWithFloat:i];
id y = [NSNumber numberWithFloat:[objPulse1.feedBack floatValue]];
NSLog(@"point of gragh for Performance x:%@, y : %@ ", x, y);
[contentArray1 addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x", y, @"y", nil]];
}
NSLog(@"Axis lable count : %d", [xAxisLabels count]);
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[chartData count]];
NSUInteger labelLocation = 0;
for (NSNumber *tickLocation in customTickLocations) {
NSLog(@">>>>>>>>>>>>>>>>> tick location");
CPAxisLabel *newLabel = [[CPAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];
newLabel.offset = x.labelOffset + x.majorTickLength - 5.0f;
// newLabel.rotation = M_PI/(2);
newLabel.rotation = 0;
[customLabels addObject:newLabel];
[newLabel release];
}
x.axisLabels = [NSSet setWithArray:customLabels];
// [arrScatter removeAllObjects];
arrScatter = contentArray1;
[arrScatter retain];
// NSLog(@">>>>>>>>>>>> :%d", [arrScatter count]);
}
-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot
{
if ( [(NSString *)plot.identifier isEqualToString:@"FeedBack Plot"] ) {
return [chartData count];
// return 10;
}
return 0;
}
-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:( NSUInteger)index
{
switch ( fieldEnum ) {
case CPScatterPlotFieldX:
return (NSDecimalNumber *)[NSDecimalNumber numberWithUnsignedInteger:index*fiveHour];
case CPScatterPlotFieldY:
{
Pulse *objPulse1 = (Pulse *)[chartData objectAtIndex:index];
return [NSNumber numberWithFloat:[objPulse1.feedBack floatValue]];
}
}
return nil;
}
-(CGPoint)plotSpace:(CPPlotSpace *)space willDisplaceBy:(CGPoint)displacement {
// NSLog(@">>>>>>>>>>>>>>>>>> : %f", displacement.x);
return CGPointMake(displacement.x, 0);
}
/*
-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex: (NSUInteger)index
{
NSDecimalNumber *num = nil;
if ( [(NSString *)plot.identifier isEqualToString:@"FeedBack Plot"] ) {
if ( [arrScatter count] != 0) {
num = [[arrScatter objectAtIndex:index] valueForKey:(fieldEnum == CPScatterPlotFieldX ? @"x" : @"y")];
}
}
return num;
}
*/
-(CPLayer *)dataLabelForPlot:(CPPlot *)plot recordIndex:(NSUInteger)index {
Pulse *objPulse1 = (Pulse *)[chartData objectAtIndex:index];
float value = [objPulse1.feedBack floatValue];
//CPTextLayer *textLayer = [[CPTextLayer alloc] initWithText:[NSString stringWithFormat:@"%d", value]];
CPTextStyle *textStyle = [CPTextStyle textStyle];
textStyle.color = [CPColor blackColor];
CPTextLayer *textLayer = [[CPTextLayer alloc] initWithText:[NSString stringWithFormat:@"%0.1f", value] style:textStyle];
return textLayer;
}
回答3:
Use CPTCalendarFormatter instead of CPTTimeFormatter as stated in the other answers. CPTTimeFormatter is good when you have to set time interval offset in seconds (ex. hour= 60*60, day=24*60*60), but months have a variable number of days/seconds (30*24*60*60 or 31*24*60*60, 28, leap years ecc.). CPTCalendarFormatter let you decide the calendar unit for date calculations on labels. In this way, fixed a reference date and a reference calendar unit, in the datasource method you will have to return the number of those units starting from the reference date.
Here's full code, enjoy.
In your viewDidLoad or elsewhere you initialize the graph:
[...]
// Graph host view
CPTGraphHostingView* hostView = [[CPTGraphHostingView alloc] initWithFrame:self.view.frame];
[self.view addSubview: hostView];
// Your graph
CPTGraph* graph = [[CPTXYGraph alloc] initWithFrame:hostView.bounds];
hostView.hostedGraph = graph;
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)[graph axisSet];
// xAxis configuration
CPTXYAxis *xAxis = [axisSet xAxis];
[xAxis setLabelingPolicy:CPTAxisLabelingPolicyFixedInterval];
// Prepare dateFormat for current Locale, we want "JAN 2014" "FEB 2014" and so on
NSString *dateComponents = @"MMMYY";
NSString *localDateFormat = [NSDateFormatter dateFormatFromTemplate:dateComponents options:0 locale:[NSLocale currentLocale]];
NSDateFormatter *labelDateFormatter=[[NSDateFormatter alloc] init];
labelDateFormatter.dateFormat=localDateFormat;
// Set xAxis date Formatter
CPTCalendarFormatter *xDateYearFormatter = [[CPTCalendarFormatter alloc] initWithDateFormatter:labelDateFormatter];
//Keep in mind this reference date, it will be used to calculate NSNumber in dataSource method
xDateYearFormatter.referenceDate = [NSDate dateWithTimeIntervalSince1970:0];
xDateYearFormatter.referenceCalendarUnit=NSMonthCalendarUnit;
[xAxis setLabelFormatter:xDateYearFormatter];
// yAxis configuration
CPTXYAxis *yAxis = [axisSet yAxis];
[yAxis setMajorIntervalLength:CPTDecimalFromFloat(_YOURYINTERVAL_)];
[yAxis setLabelingPolicy:CPTAxisLabelingPolicyFixedInterval];
[yAxis setLabelFormatter:_YOURYFORMATTER_];
[yAxis setAxisConstraints:[CPTConstraints constraintWithLowerOffset:0.0]]
// Get the (default) plotspace from the graph so we can set its x/y ranges
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
NSDate *startDate=_YOURSTARTINGDATE_
//Number of months since the reference date
NSInteger xStart=[[[NSCalendar currentCalendar] components: NSCalendarUnitMonth
fromDate: xDateYearFormatter.referenceDate
toDate: _YOURSTARTINGDATE_
options: 0] month];
[plotSpace setXRange: [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInteger(xStart) length:CPTDecimalFromInteger(_YOURDATESARRAY_.count-1)]];
[plotSpace setYRange: [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(_YOURMAXYVALUE_)]];
[...]
Datasource method to return values on axis:
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
switch (fieldEnum) {
case CPTScatterPlotFieldX: {
NSInteger monthsOffset=[[[NSCalendar currentCalendar] components: NSCalendarUnitMonth fromDate: [NSDate dateWithTimeIntervalSince1970:0] toDate: [_YOURDATESARRAY_ objectAtIndex:index] options: 0] month];
NSNumber *val = [NSNumber numberWithInteger:monthsOffset];
return val;
break;
}
case CPTScatterPlotFieldY: {
NSNumber *val=_YOURVALUEFORYAXIS_;
return val;
break;
}
default:
break;
}
return nil;
}
回答4:
A bit late with an answer but I just happen to have just done this:
First the label has to be defined:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"MMM"]; CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
This gives a result of: Jan, Feb, Mar etc.
Then set the axis to days: In Core Plot examples you can see this done in the date plot. A rough estimation is 30 days for each month so using these defines:
define ONE_DAY (24*60*60) define ONE_MONTH (30*ONE_DAY)
then setting the X-axis:
x.majorIntervalLength = CPTDecimalFromFloat(ONE_MONTH);
The Y-axis is: y.majorIntervalLength = CPTDecimalFromFloat(200);
来源:https://stackoverflow.com/questions/10876884/how-to-plot-months-of-the-year-on-x-axis-using-core-plot-in-iphone