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

时间:2015-01-09 10:21:17

标签: ios objective-c core-data core-plot

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

myEntity所

  • timeStamp:日期
  • someValue:Integer 64

我的核心绘图是一个散点图,它显示y轴上的“someValue”值和x轴上的“timeStamp”值。

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

My core plot graph with "someValue" on the y-axis and "timeStamp" on the x-axis.

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

我的想法是我会使用

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

CPTPlotSpaceDelegate的方法,并使用timeStamp作为谓词从核心数据中获取相关实体。但是,我无法弄清楚如何做到这一点。在给定图的当前范围的情况下,有没有办法访问timeStamp值?我想过尝试访问我的x轴标签,因为它们显示当前时间并使用它从我的数据存储中取出但我无法弄清楚如何。这甚至是正确的方法吗?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

好的,我设法弄明白:)。这是我的解决方案,万一其他人偶然发现了这个问题:

我意识到获取可见日期范围的唯一方法是从轴标签中提取日期值。然后我使用这些日期值在我的核心数据模型上执行查询。我是使用CPTAxisDelegate方法shouldUpdateAxisLabelsAtLocations完成的。每当范围以任何方式改变时(通过平移/缩放),都会调用该委托方法。这是我做的:

-(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];
}

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