核心情节:个性化情节
我正在试验 iOS 的 Core Plot 库。我已经成功地显示了包含我的信息的图表,但是我无法根据需要个性化可视化。
我正在尝试使用一个简单的散点图来显示用户在两个日期之间每天行驶的距离。我已经设法创建用于绘图的数据,但我很难个性化绘图,也许使用过此库的人可以帮助我;)
我的问题是:
- 如果我只显示 x 轴和 y 轴的正方向,我将看不到标签。
- 例如,如果两个日期之间有 31 天,则 x 轴从 0 到 30。如何更改标签以显示日期,例如 startDate + x。 这是我到目前为止所做的:
@interface DistanceChart : CPGraphHostingView <CPPlotDataSource> {
CPXYGraph *graph;
NSMutableArray *dataForPlot;
RouteManager *routeManager;
NSDate *startDate;
NSDate *endDate;
}
@property (nonatomic, retain) NSMutableArray *dataForPlot;
@property (nonatomic, retain) RouteManager *routeManager;
@property (nonatomic, retain) NSDate *startDate;
@property (nonatomic, retain) NSDate *endDate;
- (void)initPlot;
@end
@implementation DistanceChart
@synthesize dataForPlot;
@synthesize routeManager;
@synthesize startDate;
@synthesize endDate;
- (void)initPlot {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
self.startDate = [dateFormatter dateFromString:@"01-05-2011"];
self.endDate = [dateFormatter dateFromString:@"31-05-2011"];
//get the data
self.dataForPlot = [routeManager getTotalDistanceByDay:routeManager.routes from:startDate to:endDate];
NSLog(@"Data: %@", dataForPlot);
graph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
self.hostedGraph = graph;
graph.paddingLeft = 5;
graph.paddingTop = 5;
graph.paddingRight = 5;
graph.paddingBottom = 5;
// Setup plot space
int days = [endDate timeIntervalSinceDate:startDate] / 60 / 60 / 24 + 1;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0) length:CPDecimalFromFloat(days)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0) length:CPDecimalFromFloat(15)]; //TODO: set maximum Y according to max distance
// Axes
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromString(@"1");
x.orthogonalCoordinateDecimal = CPDecimalFromString(@"0");
x.minorTicksPerInterval = 1;
CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPDecimalFromString(@"1");
y.minorTicksPerInterval = 1;
y.orthogonalCoordinateDecimal = CPDecimalFromString(@"0");
x.labelRotation = M_PI/8;
// Create a green plot area
CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = @"Green Plot";
CPMutableLineStyle *lineStyle = [[dataSourceLinePlot.dataLineStyle mutableCopy] autorelease];
lineStyle.lineWidth = 2.f;
lineStyle.lineColor = [CPColor greenColor];
dataSourceLinePlot.dataLineStyle = lineStyle;
dataSourceLinePlot.dataSource = self;
// Put an area gradient under the plot above
CPColor *areaColor = [CPColor colorWithComponentRed:0.3 green:1.0 blue:0.3 alpha:0.8];
CPGradient *areaGradient = [CPGradient gradientWithBeginningColor:areaColor endingColor:[CPColor clearColor]];
areaGradient.angle = -90.0f;
CPFill *areaGradientFill = [CPFill fillWithGradient:areaGradient];
dataSourceLinePlot.areaFill = areaGradientFill;
dataSourceLinePlot.areaBaseValue = CPDecimalFromString(@"1.75");
// Animate in the new plot, as an example
dataSourceLinePlot.opacity = 0.0f;
dataSourceLinePlot.cachePrecision = CPPlotCachePrecisionDecimal;
[graph addPlot:dataSourceLinePlot];
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"];
}
#pragma mark -
#pragma mark Plot Data Source Methods
- (NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot
{
return [dataForPlot count];
}
- (NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDecimalNumber *num = [[dataForPlot objectAtIndex:index] valueForKey:(fieldEnum == CPScatterPlotFieldX ? @"x" : @"y")];
return num;
}
- (CPLayer *)dataLabelForPlot:(CPPlot *)plot recordIndex:(NSUInteger)index
{
return nil;
}
- (void)dealloc {
[dataForPlot release];
[routeManager release];
[startDate release];
[endDate release];
[super dealloc];
}
@end
I'm experimenting the Core Plot library for iOS. I've managed to show a graph with my information, however i'm unable to personalize the visualization as I want.
I'm trying to use a simple scatter plot to show the distance a user has traveled by day, between two dates. I've managed to create the data for plotting, but i'm having a hard time personalizing the plot, maybe somebody that has used this lib can help me ;)
My question is:
- If I only show the positive side of both x and y axis, I'm not able to see the labels.
- For example, if there are 31 days between the two dates, the x axis goes from 0 to 30. How do i change the labels to show the date, for instance startDate + x.
This is what I've done so far:
@interface DistanceChart : CPGraphHostingView <CPPlotDataSource> {
CPXYGraph *graph;
NSMutableArray *dataForPlot;
RouteManager *routeManager;
NSDate *startDate;
NSDate *endDate;
}
@property (nonatomic, retain) NSMutableArray *dataForPlot;
@property (nonatomic, retain) RouteManager *routeManager;
@property (nonatomic, retain) NSDate *startDate;
@property (nonatomic, retain) NSDate *endDate;
- (void)initPlot;
@end
@implementation DistanceChart
@synthesize dataForPlot;
@synthesize routeManager;
@synthesize startDate;
@synthesize endDate;
- (void)initPlot {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
self.startDate = [dateFormatter dateFromString:@"01-05-2011"];
self.endDate = [dateFormatter dateFromString:@"31-05-2011"];
//get the data
self.dataForPlot = [routeManager getTotalDistanceByDay:routeManager.routes from:startDate to:endDate];
NSLog(@"Data: %@", dataForPlot);
graph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
self.hostedGraph = graph;
graph.paddingLeft = 5;
graph.paddingTop = 5;
graph.paddingRight = 5;
graph.paddingBottom = 5;
// Setup plot space
int days = [endDate timeIntervalSinceDate:startDate] / 60 / 60 / 24 + 1;
CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0) length:CPDecimalFromFloat(days)];
plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0) length:CPDecimalFromFloat(15)]; //TODO: set maximum Y according to max distance
// Axes
CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
CPXYAxis *x = axisSet.xAxis;
x.majorIntervalLength = CPDecimalFromString(@"1");
x.orthogonalCoordinateDecimal = CPDecimalFromString(@"0");
x.minorTicksPerInterval = 1;
CPXYAxis *y = axisSet.yAxis;
y.majorIntervalLength = CPDecimalFromString(@"1");
y.minorTicksPerInterval = 1;
y.orthogonalCoordinateDecimal = CPDecimalFromString(@"0");
x.labelRotation = M_PI/8;
// Create a green plot area
CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
dataSourceLinePlot.identifier = @"Green Plot";
CPMutableLineStyle *lineStyle = [[dataSourceLinePlot.dataLineStyle mutableCopy] autorelease];
lineStyle.lineWidth = 2.f;
lineStyle.lineColor = [CPColor greenColor];
dataSourceLinePlot.dataLineStyle = lineStyle;
dataSourceLinePlot.dataSource = self;
// Put an area gradient under the plot above
CPColor *areaColor = [CPColor colorWithComponentRed:0.3 green:1.0 blue:0.3 alpha:0.8];
CPGradient *areaGradient = [CPGradient gradientWithBeginningColor:areaColor endingColor:[CPColor clearColor]];
areaGradient.angle = -90.0f;
CPFill *areaGradientFill = [CPFill fillWithGradient:areaGradient];
dataSourceLinePlot.areaFill = areaGradientFill;
dataSourceLinePlot.areaBaseValue = CPDecimalFromString(@"1.75");
// Animate in the new plot, as an example
dataSourceLinePlot.opacity = 0.0f;
dataSourceLinePlot.cachePrecision = CPPlotCachePrecisionDecimal;
[graph addPlot:dataSourceLinePlot];
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"];
}
#pragma mark -
#pragma mark Plot Data Source Methods
- (NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot
{
return [dataForPlot count];
}
- (NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSDecimalNumber *num = [[dataForPlot objectAtIndex:index] valueForKey:(fieldEnum == CPScatterPlotFieldX ? @"x" : @"y")];
return num;
}
- (CPLayer *)dataLabelForPlot:(CPPlot *)plot recordIndex:(NSUInteger)index
{
return nil;
}
- (void)dealloc {
[dataForPlot release];
[routeManager release];
[startDate release];
[endDate release];
[super dealloc];
}
@end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可能需要增加填充才能显示标签。您可能还需要在
plotAreaFrame
上添加填充。Core Plot 中包含几个示例程序(“DatePlot”和“MinorTickLabels”),展示了如何在轴上设置日期和时间的格式。
You probably need to increase the padding to show the labels. You may also need to add padding on the
plotAreaFrame
.There are a couple of example programs ("DatePlot" and "MinorTickLabels") included with Core Plot that show how to format dates and times on the axes.