2012-06-01 70 views
2

我試圖在iOS 5.1的iPad上使用CorePlot 1.0實現實時散點圖。事情很好地解決了一些問題和一個主要的例外 - 軸重繪。在滾動實時CorePlot Scatterplot上更新X軸

當收集到足夠的數據,我調整在plotSpace範圍從而:

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

當我做到這一點,在圖上的曲線調整爲如果軸發生了變化,但軸沒有按」 t調整 - 所以數據的圖表正確地針對不正確的軸顯示。停止數據源後,軸將正確更新5秒鐘。

我從CorePlot iOS的情節畫廊審查RealTimePlot(RTP)的代碼,我找不到任何顯著差異(儘管確實存在)。我的代碼和RTP之間

一個區別:

我在[NSNotificationCenter defaultCenter]

更新其連接到一個自定義通知捕獲背景GCD隊列,然後將其「分佈式」新的數據: 架構層級的簡化視圖是這樣的:

  • SplitViewController
    • DetailViewController
      • TreatmentGraph對象(管理CPTXYGraph
        • [收集] 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帖子的數據到UI隊列 - t他在RTP中的例子似乎並不需要)這是一面紅旗,但是是什麼?

TreatmentGraph之內,我們檢查是否需要X軸調整,並將數據分派到合適的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:只需添加新的數據,並呼籲-reloadData專門對CPTXYPlot。這不會導致顯示更新 - 直到-reloadDataDetailViewController的數據通知處理程序中被調用纔會顯示更新。

問題:

  1. 我能做些什麼,因爲我的軸線以更及時地更新?
  2. 任何線索爲什麼我不能在我的圖上得到陰謀,除非我在數據到達時強制重新加載?

通過確保對軸和/或圖空間的任何更新進行封裝以將它們放回到GCD主隊列中來解決項目1。

通過將呼叫打包爲-insertDataAtIndex:numberOfRecords:來解決項目2,允許刪除困擾我的很多-reloadData呼叫。

故事的道德:考慮與CorePlot相當於UIKit調用的交互 - 確保它們都發生在主隊列中。

回答

2
  1. 無論何時繪圖空間範圍發生變化,座標軸都應重新標記並重繪。你什麼時候根據新數據更新繪圖空間?

  2. 您必須告訴情節新數據可用。 -reloadData是這樣做的一種方式,雖然對於這個應用程序,有更快的方法來做到這一點。實時繪圖示例使用-insertDataAtIndex:numberOfRecords:-deleteDataInIndexRange:添加新點並刪除滾動出視圖的點。這比每次改變時重新加載圖的所有數據要快。在圖表上調用-reloadData而不是受影響的繪圖會更慢,因爲它會重新加載所有繪圖的數據。

+0

您好埃裏克, 我會更新更多的細節問題,但很快: 新數據通過TreatmentGraph對象調度 - 其中,如果需要一個調整的軸和plotSpace做 - 並傳遞給來自它們集合的正確的TreatmentChannel對象。 TreatmentChannel中的-addPoint:方法高速緩存特定於指定的數據,使用-insertDataAtIndex:numberOfRecords:更新圖並在該圖上調用-reloadData。 (這不會導致更新) 感謝您的幫助。 – Thompsonian

+0

你不需要'-insertDataAtIndex:numberOfRecords:'和'-reloadData'。我認爲這個問題與不同的線索有關。嘗試在主線程上調用'-insertDataAtIndex:numberOfRecords:'。 –

+0

在主隊列中調用'-insertDataAtIndex:numberOfRecords:'確實減輕了對'-reloadData'的需求。非常好的電話。我仍然在試圖追蹤我的軸將不**更新的主要問題,除非我停止數據饋送。 – Thompsonian