如何使用核心图在 x 轴上绘制一年中的月份,在 y 轴上我需要 200 的倍数,而且这些数据是我以前从 Excel 表中获得的。任何人都可以帮助我解决这个问题。提前致谢....
4 回答
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;
}
我已经做了一些你想要的事情,比如这段代码。抱歉,我在这里没有明确代码,只是粘贴了我在这里使用的整个方法。
我希望这可以帮助你想要什么。在这里,我以新的方式实现了图形,您可以像 tableview 一样刷新它。只需更改数组的值,然后调用 [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;
}
这是从最近的项目中获取的一些示例代码。我的 x 轴数据是 NSDates 数组。我正常设置了我的axisSet,然后在下面添加了以下代码:
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];
对于问题的 y 轴部分,您可以调整刻度间隔(CPTXYAxis 的属性)。要获得正确的轴高度/长度,请查看绘图空间的 xRange、yRange、globalXRange 和 globalYRance 属性。
答案有点晚了,但我碰巧刚刚这样做了:
首先必须定义标签:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"MMM"]; CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
这给出了以下结果:1 月、2 月、3 月等。
然后将轴设置为天:在 Core Plot 示例中,您可以在日期图中看到这一点。粗略估计是每个月 30 天,因此使用以下定义:
定义 ONE_DAY (24*60*60) 定义 ONE_MONTH (30*ONE_DAY)
然后设置X轴:
x.majorIntervalLength = CPTDecimalFromFloat(ONE_MONTH);
Y轴为:y.majorIntervalLength = CPTDecimalFromFloat(200);