Search code examples
iosobjective-ccore-plot

CorePlot slow performance


I have the following CorePlot (v1.2) code which is based around the tutorial from http://www.raywenderlich.com/13271/how-to-draw-graphs-with-core-plot-part-2 but extended a bit. With about 30 data points it takes around 3 seconds to render the graph on an iPhone 4S. The graph does load correctly, it's just slow. Is there anyway to improve the performance?

Here's the NSLog output form the code:

2013-05-30 17:41:20.386 myApp[2796:907] A
2013-05-30 17:41:20.387 myApp[2796:907] B
2013-05-30 17:41:20.388 myApp[2796:907] C
2013-05-30 17:41:20.389 myApp[2796:907] D
2013-05-30 17:41:21.158 myApp[2796:907] E
2013-05-30 17:41:21.160 myApp[2796:907] F
2013-05-30 17:41:22.594 myApp[2796:907] G

NB After the code finishes running there's about another 0.5 second delay before the graph is rendered.

And the code:

-(void)configureAxes {

    NSLog(@"A");
    // 1 - Create styles
    CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
    axisTitleStyle.color = [CPTColor whiteColor];
    axisTitleStyle.fontName = @"Helvetica-Bold";
    axisTitleStyle.fontSize = 12.0f;
    CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
    axisLineStyle.lineWidth = 2.0f;
    axisLineStyle.lineColor = [CPTColor whiteColor];
    CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
    axisTextStyle.color = [CPTColor whiteColor];
    axisTextStyle.fontName = @"Helvetica-Bold";
    axisTextStyle.fontSize = 11.0f;
    CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
    tickLineStyle.lineColor = [CPTColor whiteColor];
    tickLineStyle.lineWidth = 2.0f;
    NSLog(@"B");
    // 2 - Get axis set
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;

    // 3 - Configure x-axis
    CPTMutableLineStyle *lineStyle = [CPTMutableLineStyle lineStyle];
    lineStyle.lineColor = [CPTColor whiteColor];
    lineStyle.lineWidth = 2.0f;

    CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
    textStyle.fontName = @"Helvetica";
    textStyle.fontSize = 14;
    textStyle.color = [CPTColor whiteColor];

    axisSet.xAxis.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0.0");
    axisSet.xAxis.minorTicksPerInterval       = 0;

    NSLog(@"C");
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    if ([person.unitPreference isEqualToString:@"US"]) {
        [dateFormatter setDateFormat:@"MMM-dd"];
    } else {
        [dateFormatter setDateFormat:@"dd-MMM"];
    }
    NSLog(@"D");
    CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
    axisSet.xAxis.labelFormatter = timeFormatter;
    axisSet.xAxis.labelRotation = M_PI/4;
    axisSet.xAxis.titleOffset = 55.5f;
    axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyAutomatic;    
    NSLog(@"E");
    if ([measurementField isEqualToString:@"mWeight"]) {
        NSString *unit;
        if ([person.unitPreference isEqualToString:@"METRIC"]) {
            unit = @"Kgs";
        } else if ([person.unitPreference isEqualToString:@"US"]) {
            unit = @"lbs";
        } else {
            unit = @"st lbs";
        }
        axisSet.yAxis.title = [NSString stringWithFormat: @"Weight (%@)", unit];

        WeightFormatter *weightFormatter = [[WeightFormatter alloc] init];
        weightFormatter.person = person;
        axisSet.yAxis.labelFormatter = weightFormatter;
    } else if ([measurementField isEqualToString:@"mBodyFatPercentage"]) {
        axisSet.yAxis.title = @"Body Fat %";
        axisSet.yAxis.labelFormatter = [[BodyFatPercentageFormatter alloc] init];
    } else {
        NSString *unit;
        if ([person.unitPreference isEqualToString:@"METRIC"]) {
            unit = @"CMs";
        } else {
            unit = @"Inches";
        }
        axisSet.yAxis.title = [NSString stringWithFormat: @"Measurements (%@)", unit];

        MeasurementFormatter *measurementFormatter = [[MeasurementFormatter alloc] init];
        measurementFormatter.person = person;
        axisSet.yAxis.labelFormatter = measurementFormatter;
    }
    NSLog(@"F");
    axisSet.yAxis.titleTextStyle = textStyle;
    axisSet.yAxis.titleOffset = 40.0f + marginOffset;
    axisSet.yAxis.axisLineStyle = lineStyle;
    axisSet.yAxis.majorTickLineStyle = lineStyle;
    axisSet.yAxis.minorTickLineStyle = lineStyle;
    axisSet.yAxis.labelTextStyle = textStyle;
    axisSet.yAxis.labelOffset = 3.0f;
    axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat((yAxisMax-yAxisMin)/10.0f);
    axisSet.yAxis.minorTicksPerInterval = 1;
    axisSet.yAxis.minorTickLength = 5.0f;
    axisSet.yAxis.majorTickLength = 7.0f;
    axisSet.yAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0];
    axisSet.xAxis.orthogonalCoordinateDecimal = CPTDecimalFromFloat(yAxisMin);
    axisSet.xAxis.majorIntervalLength =  CPTDecimalFromFloat(oneDay);
    NSLog(@"G");
}

Solution

  • This was something introduced by coreplot 1.2. The following lines amongst others would cause the app to hang for a long time:

    axisSet.xAxis.labelRotation = M_PI/4;
    axisSet.xAxis.titleOffset = 55.5f;
    

    reverting back to 1.1 resolved the issue instantly. From @Eric Skroch's comment above, this will probably be fixed in 1.3, but I want to use a stable release until then, not least as I'm not using any of the new features in 1.2.

    As an aside, I think the reason the older library wasn't working with my iPhone 5 was not having the following in place:

    1. Add to Other Linker Flags in your target build settings:

      -ObjC -all_load