开发者

Core-Plot: Personalizing Plot

开发者 https://www.devze.com 2023-03-05 20:09 出处:网络
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 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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号