CorePlot CPU问题。实时向图表添加数据

时间:2014-04-16 05:01:02

标签: ios core-plot

我按照CorePlot中的示例在我获取散点图时向散点图添加新点。我从CoreData附带的RealTimePlot示例中建模了我的图形。我注意到,当我运行图表时,一旦屏幕开始滚动以呈现新数据,CPU就会固定为100%。我已经尝试了将数据添加到我的dataSource以及更新调用的不同方法,但我无法获得任何响应和可接受的CPU负载。

经过多次试验和错误后,我启动了RealTimePlot示例以查看CPU负载是多少,并且它也固定在100%。这是在iPhone 5s上,所以我很害怕看到4会如何行动。我的问题;有没有其他方法来更新图表?

无论如何,这是我的更新循环。我正在采用加速度计数据并绘制图表。

-(void)motionController:(VWWMotionController*)sender didUpdateAcceleremeters:(CMAccelerometerData*)accelerometers{
    static NSInteger counter = 0;

    CPTGraph *theGraph = self.graph;
    CPTPlot *thePlot   = [theGraph plotWithIdentifier:@"Blue Plot"];

    if ( thePlot ) {

        if ( self.dataForPlot.count >= NUM_POINTS ) {
            [self.dataForPlot removeObjectAtIndex:0];
            [thePlot deleteDataInIndexRange:NSMakeRange(0, 1)];
        }

        CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)theGraph.defaultPlotSpace;
        NSUInteger location       = (counter >= NUM_POINTS ? counter - NUM_POINTS + 2 : 0);

        CPTPlotRange *oldRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger( (location > 0) ? (location - 1) : 0 )
                                                              length:CPTDecimalFromUnsignedInteger(NUM_POINTS - 2)];
        CPTPlotRange *newRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(location)
                                                              length:CPTDecimalFromUnsignedInteger(NUM_POINTS - 2)];

        [CPTAnimation animate:plotSpace
                     property:@"xRange"
                fromPlotRange:oldRange
                  toPlotRange:newRange
                     duration:CPTFloat(0)];


        NSNumber *x = @(counter);
        NSNumber *y = @(accelerometers.acceleration.x);
        [self.dataForPlot addObject:@{ @"x": x,
                                       @"y": y }];

        dispatch_async(dispatch_get_main_queue(), ^{
            [thePlot insertDataAtIndex:self.dataForPlot.count - 1 numberOfRecords:1];
        });


        counter++;
    }
}

FYI。我理想情况下喜欢30 FPS。我已经将加速度计回调从1/5调整到1/30并且有一些CPU改进,但随后我失去了帧速率。

如果我注释掉insertDataAtIndex行,则CPU会以1%的速度挂起,但当然图表不会跟随新数据。 我没有看到插入方法的任何衍生物。

我还读过其他线程,重新计算轴标签是资源交互。我试过删除它们几乎没有什么改进。

我正在考虑为这项工作去OpenGL或CoreGraphics。

你有什么建议?

2 个答案:

答案 0 :(得分:0)

注意:我没有在iPhone 5s上测试过(我已经完成了iPhone 4s,5,iPad 3,iPad 4,iPad Mini 1),我们的应用程序似乎有不同的要求,所以我不肯定这会对你有所帮助。

无论如何,在我的测试中,我发现每次获得新数据点时都会通过重绘所有点来获得最佳,响应最快的结果。这对我来说是最好的,因为我必须每秒更新图形〜120次。我没有iPhone来测试我们的应用程序的CPU,但在iPad Mini上,CPU是< 50%的图表运行2个图(每个约125个点,尽管这个响应相当,每个约250个点)。该图表仅在y轴上有标签,并且不会更改。 x轴是时间,标签对我们来说是不必要的。

我们的要求可能与此实施方案有所不同,对您有所帮助,但可能值得一试。如果你愿意,它就是这样的:

-(void)UpdateGraph
{
    //foreach scatterplot
    {
        //Remove point from array
        //[linePlot deleteDataInIndexRange:NSMakeRange(0, [array count])]
    }
    //Insert new data point into array(s)

    //foreach scatterplot
    {
        //[linePlot insertDataAtIndex:0 numberOfRecords:[array count]]
    }
    //Schedule next update if necessary
    //[self performSelector:@selector(UpdateGraph) withObject:nil afterDelay:(1/(CGFloat)Your_FPS_Here)];
}

希望能帮到你,祝你好运!

答案 1 :(得分:0)

关键是要使图表简单快速地绘制。设置标签策略,以便您没有太多标签。不要使用次要刻度线或网格线(将线型设置为nil)。如果您不需要,也可以关闭主要网格线。不要在图上使用区域填充。