gpt4 book ai didi

ios - 在滚动实时 CorePlot 散点图上更新 X 轴

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:21:49 49 4
gpt4 key购买 nike

我正在尝试在装有 iOS 5.1 的 iPad 上使用 CorePlot 1.0 实现实时散点图。事情进展顺利,但有几个问题和一个主要异常 - 轴重绘。

当收集到足够的数据时,我会这样调整 plotSpace 中的范围:

CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(self.graphMinX)
length:CPTDecimalFromFloat(self.graphRangeX)];

当我执行此操作时,图表上的绘图会进行调整,就好像轴已更改一样,但轴不会调整 - 因此数据图会根据错误的轴正确显示。轴将在我停止数据源 5 秒后正确更新。

我已经查看了 RealTimePlot 中的代码(RTP) 来自 CorePlot iOS Plot Gallery,我找不到任何显着差异(尽管肯定存在)。

我的代码和 RTP 之间的一个区别:

我在后台 GCD 队列中捕获新数据,然后通过将其附加到 [NSNotificationCenter defaultCenter]

中的自定义通知来“分发”该数据

更新:架构层次结构的简化 View 是这样的:

  • Split View Controller
    • 详细 View Controller
      • TreatmentGraph 对象(管理 CPTXYGraph)
        • [Collection of] TreatmentChannel 对象(每个管理一个 CPTXYPlot)

DetailViewController 有一个数据通知的观察者,如下所示:

- (void)dataArrived:(NSNotification *)notification
{
FVMonitoredSignal *sig = [notification object];

NSValue *currValue = [sig.dataPoints lastObject];
CGPoint point = [currValue CGPointValue];

[self.treatmentGraph addPoint:point toChannelWithIdentifier:sig.signalName];
dispatch_async(dispatch_get_main_queue(), ^{
[self.graphHostingView.hostedGraph reloadData];
});

return;
}

(请注意,我使用 GCD post 将数据强制重新加载到 UI 队列 - RTP 中的示例似乎不需要这样做)这是一个危险信号,但是什么?

TreatmentGraph 中,我们检查是否需要调整 X 轴并将数据分派(dispatch)到适当的 TreatmentChannel

- (void)addPoint:(CGPoint)point toChannelWithIdentifier:(NSString *)identifier
{
// Check for a graph shift
if (point.x >= (self.graphMinX + self.graphRangeX))
{
[self shiftGraphX];
}

FVTreatmentChannel *channel = [self.channels objectForKey:identifier];
[channel addPoint:point];

return;
}

- (void)shiftGraphX
{
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(self.graphMinX) length:CPTDecimalFromFloat(self.graphRangeX)];
}

我的猜测是在主队列空闲之前轴不会更新,但由于我已经在新数据到达时强制重新加载,所以我很困惑为什么轴不会重绘。

TreatmentChannel 接受这样的新数据:

- (void)addPoint:(CGPoint)point
{
[self.plotData addObject:[NSValue valueWithCGPoint:point]]; // cache it
[self.plot insertDataAtIndex:self.plotData.count-1 numberOfRecords:1];
[self.plot reloadData];
}

请注意,我正在使用 -insertDataAtIndex:numberOfRecords: 来添加新数据并专门在 CPTXYPlot 上调用 -reloadData。这不会导致显示更新 - 直到在 DetailViewController 的数据通知处理程序中调用 -reloadData 后,我才获得显示更新。

问题:

  1. 我该怎么做才能使我的坐标轴更及时地更新?
  2. 有什么线索可以解释为什么除非我在数据到达时强制重新加载,否则我的图表上没有绘图?

第 1 项已通过确保对轴和/或绘图空间的任何更新进行包装以将它们放回 GCD 主队列来解决。

通过包装对 -insertDataAtIndex:numberOfRecords: 的调用来解决项目 2,允许删除许多困扰我的 -reloadData 调用。

故事的寓意:考虑与 CorePlot 的交互等同于 UIKit 调用 - 确保它们都发生在主队列上。

最佳答案

  1. 每当任一绘图空间范围发生变化时,轴都应重新标记和重新绘制。你什么时候根据新数据更新绘图空间?

  2. 您必须告诉情节有新数据可用。 -reloadData 是一种方法,但对于此应用程序,还有更快的方法。实时绘图示例使用 -insertDataAtIndex:numberOfRecords:-deleteDataInIndexRange: 添加新点并删除滚动出 View 的点。这比每次发生变化时都重新加载绘图的所有数据要快。如果您有多个绘图,则在图表而不是受影响的绘图上调用 -reloadData 会更慢,因为它会重新加载所有绘图的数据。

关于ios - 在滚动实时 CorePlot 散点图上更新 X 轴,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10851536/

49 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com