Jean
Jean

Reputation: 2625

Core Plot : X Axis Labels don't appear the first time the graph is drawn

Am trying to draw some graphs in an iPhone App using Core Plot. Here is one such graph from the App :

enter image description here

As you can see, the X Axis labels are just showing 1,2,3... labels, whereas I have configured the corresponding date to be displayed in them. This graph re-draws every few minutes. When it re-draws, it displays the x-axis labels (i.e. the date values) correctly, as seen below :

enter image description here

Whereas the first time, it just shows 1,2,3....

How am I setting the X Axis Labels?

I am doing it in 'numberOfRecordsForPlot', not when setting all other parameters (like color, padding, etc) for the graph. This is because I get the values for plotting only after I have set the colors, etc for the graph, & so in numberOfRecordsForPlot(), I calculate the axis ranges for both the axes (depending on the values that come in every few minutes) and also calculate the custom tick locations & the x-axis labels & set it there. Here's the code snippet :

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
...
...

NSArray *customTickLocations = [NSArray arrayWithObjects :
                                [NSDecimalNumber numberWithInt:0],
                                [NSDecimalNumber numberWithInt:1],
                                [NSDecimalNumber numberWithInt:2],
                                [NSDecimalNumber numberWithInt:3],
                                [NSDecimalNumber numberWithInt:4],
                                nil];
// assume that we are plotting 5 points at a time
NSMutableArray *xAxisLabels = [[NSMutableArray alloc] init];
for (int i=0; i<self.arrayKeys.count ; i++) {

    NSString *myData = [dict objectForKey:[self.arrayKeys objectAtIndex:i]];
    if ((myData == nil) || (myData == NULL)) {
        NSLog(@"WARN : Invalid data");
        continue;
    }
    NSDate *date = (NSDate *) [self.arrayKeys objectAtIndex:i];
    [xAxisLabels addObject:date];
}
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:xAxisLabels.count];
CPTMutableTextStyle *textStyle = [[CPTMutableTextStyle alloc] init];
textStyle.fontSize = 10.0;
textStyle.color = [CPTColor darkGrayColor];
for (int i=0 ; i<dictHealth.count ; i++) {
    NSNumber *tickLocation = [customTickLocations objectAtIndex:i];
    NSDateComponents *dateComponents = [self getComponentFromDate:
                                        (NSDate *)[xAxisLabels objectAtIndex:labelLocation++]];
    CPTAxisLabel *newLabel = [[CPTAxisLabel alloc]
                              initWithText:[NSString stringWithFormat:@"%d-%d-%d\n%d:%d:%d",
                                            dateComponents.year, dateComponents.month, dateComponents.day,
                                            dateComponents.hour, dateComponents.minute, dateComponents.second]
                              textStyle:textStyle];
    newLabel.tickLocation = [tickLocation decimalValue];
    newLabel.offset = 7.5;
    newLabel.rotation = M_PI/3;
    [customLabels addObject:newLabel];
}
axisSet.xAxis.axisLabels =  [NSSet setWithArray:customLabels];

...
...
}

Can someone please help?

Upvotes: 1

Views: 1046

Answers (1)

Eric Skroch
Eric Skroch

Reputation: 27381

Don't do a lot of calculations or graph configuration in the datasource. -numberOfRecordsForPlot: can be called multiple times during a data loading cycle. By the time the datasource is queried for the data, it should already know how much data is available. Computing the data count should be as simple as reading an instance variable or retrieving the count of a collection.

Setting up the axes is typically a function of the view controller. If you need to adjust the plot space ranges and create new axis labels when you receive new data, do it in the controller.

The plot data is independent of how it is displayed. If the graph will be drawn before you have any data, give the plot ranges and axis labels some reasonable defaults when you create it. Have -numberOfRecordsForPlot: return zero (0) until you have data to plot. When you receive data to display, have the controller update the plot ranges and axes and tell the plot it has new data to display using -reloadData or -insertDataAtIndex:numberOfRecords:.

Upvotes: 2

Related Questions