Core Plot需要很长时间才能加载

时间:2022-10-19 18:51:13

I have the following code in a method for setting up a CPTBarPlot:

我在设置CPTBarPlot的方法中有以下代码:

CPTGraphHostingView *chartView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(10, 100, 290, 330)];
    [self.view addSubview:chartView];

    CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:chartView.bounds];
    graph.plotAreaFrame.masksToBorder = NO;
    chartView.hostedGraph = graph;

    graph.paddingLeft = 20.0f;
    graph.paddingTop = 0.0f;
    graph.paddingRight = 0.0f;
    graph.paddingBottom = 20.0f;

    CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
    textStyle.color = [CPTColor grayColor];
    textStyle.fontName = @"Helvetica-Bold";
    textStyle.fontSize = 8.0f;;

    CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
    axisTitleStyle.color = [CPTColor grayColor];
    axisTitleStyle.fontName = @"Helvetica-Bold";
    axisTitleStyle.fontSize = 12.0f;
    CPTMutableLineStyle *axisLineStyleX = [CPTMutableLineStyle lineStyle];
    axisLineStyleX.lineWidth = 2.0f;
    axisLineStyleX.lineColor = [CPTColor grayColor];
    CPTMutableLineStyle *axisLineStyleY = [CPTMutableLineStyle lineStyle];
    axisLineStyleY.lineWidth = 2.0f;
    axisLineStyleY.lineColor = [CPTColor grayColor];

    CPTXYAxisSet *axisSet = (CPTXYAxisSet *) chartView.hostedGraph.axisSet;

    axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyFixedInterval;
    axisSet.xAxis.title = @"Ferientage pro Jahr";
    axisSet.xAxis.titleTextStyle = axisTitleStyle;
    axisSet.xAxis.titleOffset = 10.0f;
    axisSet.xAxis.axisLineStyle = axisLineStyleX;
    axisSet.xAxis.labelTextStyle = textStyle;
    axisSet.xAxis.labelOffset = -7.0f;
    axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(10.0f);
    axisSet.xAxis.labelFormatter.maximumFractionDigits = 0;

    axisSet.yAxis.labelingPolicy = CPTAxisLabelingPolicyNone;
    axisSet.yAxis.title = @"Bundesländer";
    axisSet.yAxis.titleTextStyle = axisTitleStyle;
    axisSet.yAxis.titleOffset = 5.0f;
    axisSet.yAxis.axisLineStyle = axisLineStyleY;

    CPTXYPlotSpace *plotspace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
            plotspace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0) length:CPTDecimalFromFloat(110)];
    plotspace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0) length:CPTDecimalFromFloat(17)];
    [graph addPlotSpace:plotspace];

    CPTBarPlot *plot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor redColor] horizontalBars:YES];
    plot.plotRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.5) length:CPTDecimalFromFloat(16)];
    plot.labelTextStyle = textStyle;
    plot.labelFormatter.maximumFractionDigits = 0;
    plot.labelOffset = -3.0f;
    plot.identifier = @"bl";
    plot.dataSource = self;
    plot.delegate = self;
    [graph addPlot:plot];

    plot.anchorPoint = CGPointMake(0.0, 0.0);
    CABasicAnimation *scaling = [CABasicAnimation
                                         animationWithKeyPath:@"transform.scale.x"];
    scaling.fromValue = [NSNumber numberWithFloat:0.0];
    scaling.toValue = [NSNumber numberWithFloat:1.0];
    scaling.duration = 1.0f;
    scaling.removedOnCompletion = NO;
    scaling.fillMode = kCAFillModeForwards;
    [plot addAnimation:scaling forKey:@"scaling"];

Loading it takes about 4 seconds on an iPhone 5 and twice the time on an iPhone 4. Is that normal?

在iPhone 5上加载它需要大约4秒钟,在iPhone 4上加载它需要两倍。这是正常的吗?

I also tried to circumvent that by detaching that method from the main thread and using aUIActivityIndicatorView, however there's a second strange behavior:

我还尝试通过从主线程中分离该方法并使用UIActivityIndi​​catorView来避免这种情况,但是还有第二种奇怪的行为:

Sometimes it shows the spinner and the plot gets animated after a while, sometimes the spinner doesn't show up and the plot is displayed without an animation.

有时它会显示微调器,并且一段时间后绘图会动画,有时微调器不显示,并且没有动画显示绘图。

So as you can see I'm actually struggling with two issues, but maybe the second one is intertwined with the first one.

所以你可以看到我实际上正在努力解决两个问题,但也许第二个问题与第一个问题交织在一起。


Maybe I show you other methods that are in conjunction with the Core Plot work:

也许我会向您展示与Core Plot工作相关的其他方法:

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
return 16;
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
Ferien *ferien = [[Ferien alloc] init];

NSNumber *num = nil;
if ([plot isKindOfClass:[CPTBarPlot class]]) {
    NSArray *reversedArrayCount = [[ferien.getToplist reverseObjectEnumerator] allObjects];
    num = (NSNumber *)[NSNumber numberWithFloat:[[reversedArrayCount objectAtIndex:index] floatValue]];
    }
return num;

}

-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index {
if ( [plot.identifier isEqual: @"bl"] ) {
    Ferien *ferien = [[Ferien alloc] init];
    CPTMutableTextStyle *textStyle = [CPTMutableTextStyle textStyle];
    textStyle.fontName = @"Helvetica-Bold";
    textStyle.fontSize = 8.0f;
    textStyle.color = [CPTColor blackColor];

    NSArray *reversedArrayBl = [[ferien.bundeslandListWithManagedObjects reverseObjectEnumerator] allObjects];
    NSArray *reversedArrayCount = [[ferien.getToplist reverseObjectEnumerator] allObjects];

    CPTTextLayer *label = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"%@ (%@)", [reversedArrayBl objectAtIndex:index], [reversedArrayCount objectAtIndex:index]]];
    label.textStyle = textStyle;

    return label;
}

CPTTextLayer *defaultLabel = [[CPTTextLayer alloc] initWithText:@"Label"];
return defaultLabel;

}

-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index {
if ([barPlot.identifier isEqual:@"bl"] ) {
    Ferien *ferien = [[Ferien alloc] init];

    NSMutableArray *colors = [[NSMutableArray alloc] initWithObjects:[UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], [UIColor lightGrayColor], nil];

    [colors replaceObjectAtIndex:15-ferien.currentBundesland withObject:[UIColor orangeColor]];

    for (int i = 0; i < 16; i++) {
        CPTGradient *gradient = [CPTGradient gradientWithBeginningColor:[colors objectAtIndex:index]
                                                        endingColor:[CPTColor whiteColor]
                                                  beginningPosition:0.0 endingPosition:1.5 ];
        [gradient setGradientType:CPTGradientTypeAxial];
        [gradient setAngle:320.0];

        CPTFill *fill = [CPTFill fillWithGradient:gradient];

        return fill;
    }
}
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:1.0]];

}

- (void)initView {
self.labelFerienName.text = self.ferienName;
self.labelFeriendauer.text = self.feriendauer;

}

- (void)mergeChanges:(NSNotification *)notification {
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [delegate managedObjectContext];

// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                              withObject:notification
                           waitUntilDone:YES];

}

1 个解决方案

#1


1  

You can do the data calculations anywhere, including other threads, but the graph setup and all other Core Plot interaction must be on the main thread. Call -initGraph when you're ready to display the graph, even if the data isn't ready yet. Do the data calculations on a background thread and cache the results in a structure that can be accessed quickly by the datasource. Call -reloadData on the plot (from the main thread) when the data is ready to force the plot to read the new data from the datasource.

您可以在任何地方进行数据计算,包括其他线程,但图形设置和所有其他Core Plot交互必须位于主线程上。当您准备好显示图表时,请调用-initGraph,即使数据尚未准备就绪。在后台线程上进行数据计算,并将结果缓存在可由数据源快速访问的结构中。当数据准备好强制绘图从数据源读取新数据时,在绘图上(从主线程)调用-reloadData。

#1


1  

You can do the data calculations anywhere, including other threads, but the graph setup and all other Core Plot interaction must be on the main thread. Call -initGraph when you're ready to display the graph, even if the data isn't ready yet. Do the data calculations on a background thread and cache the results in a structure that can be accessed quickly by the datasource. Call -reloadData on the plot (from the main thread) when the data is ready to force the plot to read the new data from the datasource.

您可以在任何地方进行数据计算,包括其他线程,但图形设置和所有其他Core Plot交互必须位于主线程上。当您准备好显示图表时,请调用-initGraph,即使数据尚未准备就绪。在后台线程上进行数据计算,并将结果缓存在可由数据源快速访问的结构中。当数据准备好强制绘图从数据源读取新数据时,在绘图上(从主线程)调用-reloadData。