动态获取核心图中绘图范围的数据 iOS

Dynamically fetch data for plot range in core plot iOS

我正在编写一个应用程序,可以长时间(最多几个小时)记录一些数据并在 graph/plot 中显示数据。我正在使用核心数据存储我记录的值,并使用核心图将它们显示在散点图中。我的核心数据实体如下所示:

我的实体

我的核心图是一个散点图,它在 y 轴上显示 "someValue" 值,在 x 轴上显示 "timeStamp" 值。

截图显示了核心情节的样子。

问题是我有很多值(在几个小时内每秒都会将值添加到核心数据库中)。我不想获取我所有的核心数据实体并将它们加载到内存中以立即显示在核心图中。相反,我宁愿只从我的核心数据存储中获取位于可见绘图范围内的实体,然后使用核心绘图显示它们。我会将获取的结果存储在 NSArray 或类似的东西中,并在我的 CPTPlotDataSource 方法中使用 NSArray 来填充绘图。当范围发生变化时,我的 NSArray 总是会被覆盖,因此只有可见的数据点保留在内存中。

我以为我会使用

- (CPTPlotRange *)plotSpace:(CPTPlotSpace *)space
  willChangePlotRangeTo:(CPTPlotRange *)newRange
          forCoordinate:(CPTCoordinate)coordinate

CPTPlotSpaceDelegate 的方法,并使用时间戳作为谓词从核心数据中获取相关实体。但是,我不知道该怎么做。有没有办法在给定绘图的当前范围的情况下访问时间戳值?我想尝试访问我的 x-axis 标签,因为它们显示当前时间并使用它从我的数据存储中获取,但我不知道如何访问。这甚至是正确的方法吗?感谢任何帮助。

好的,我设法弄明白了:)。这是我的解决方案,以防其他人遇到这个问题:

我意识到获取可见日期范围的唯一方法是从轴标签中提取日期值。然后我使用这些日期值对我的核心数据模型执行查询。我使用 CPTAxisDelegate 方法 shouldUpdateAxisLabelsAtLocations 执行此操作。每当范围以任何方式发生变化(通过 panning/zooming)时,都会调用该委托方法。这是我所做的:

-(BOOL)axis:(CPTAxis *)axis shouldUpdateAxisLabelsAtLocations:(NSSet *)locations{
    //Extract the NSDate values from the axis labels
    NSFormatter *formatter = axis.labelFormatter;
    NSMutableArray *rangeDates = [[NSMutableArray alloc]init];
    for ( NSDecimalNumber *tickLocation in locations ) {
        NSString *labelString       = [formatter stringForObjectValue:tickLocation];

       //Generate an NSDate object from the label
       NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
       [dateFormatter setDateFormat:@"HH:mm:ss"];
       NSDate *date = [dateFormatter dateFromString:labelString];
       [rangeDates addObject:date];
    }

    //Sort dates in ascending order (old to new) since they aren't sorted in the tickLocation array
    [rangeDates sortUsingSelector:@selector(compare:)];
    NSDate *startDate = rangeDates[0];
    NSDate *endDate = rangeDates[rangeDates.count-1]; 

    //Modify dates as needed and perform core data query using start and end dates
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"timestamp >= %@ AND timestamp <= %@", startDate, endDate];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:[NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:self.managedObjectContext]];
    [request setPredicate:predicate];
    NSError *error = nil;
    NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&error];
}

使用这种方法,我只能获取我的核心数据存储中当前在绘图中可见的记录。我希望这可以帮助遇到严重问题的任何人。