2015-01-09 2 views
1

Я пишу приложение, которое записывает некоторые данные в течение длительного периода времени (до нескольких часов) и отображает данные на графике/графике. Я сохраняю свои записанные значения с использованием основных данных и используя основной график, чтобы отображать их в диаграмме рассеяния. Мой основной объект данных выглядит следующим образом:Динамически извлекать данные для диапазона графиков в основной диаграмме iOS

MyEntity

  • TIMESTAMP: Дата
  • SomeValue: Integer 64

Мой график основной сюжет рассе сюжет, который отображает значения "SomeValue" на оси y и значениями «TimeStamp» на оси x.

На скриншоте показан основной сюжет.

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

Проблема в том, у меня есть много значений (значения добавляются в базу данных данных ядра каждую секунду в течение нескольких часов). Я не хочу получать все мои объекты Core Data и загружать их в память, чтобы они отображались в основном графике сразу. Вместо этого я предпочел бы только получать объекты, которые лежат в пределах видимого диапазона графиков, из моего основного хранилища данных, а затем отображать их с использованием основного графика. Я бы сохранил полученные результаты в NSArray или что-то подобное и использовал NSArray в моих методах CPTPlotDataSource для заполнения графика. Мой NSArray всегда будет перезаписываться, когда диапазон изменяется, так что в памяти сохраняются только видимые точки данных.

Что я думал, что я хотел бы использовать метод CPTPlotSpaceDelegate

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

, и получать соответствующие объекты из основных данных, используя TIMESTAMP в качестве предиката. Однако я не мог понять, как это сделать. Есть ли способ получить доступ к значениям timeStamp, учитывая текущий диапазон графика? Я думал о попытке получить доступ к моим методам оси x, поскольку они отображают текущее время и извлекают из моего хранилища данных, используя это, но я не мог понять, как это сделать. Это даже правильный способ сделать это? Любая помощь приветствуется.

+0

Вы должны знать, что означает 'CPTPlotRange' с точки зрения вашего времениStamp, и вы можете использовать' NSPredicate' в вашей выборке CoreData. – Larme

ответ

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

Используя этот метод, я был в состоянии принести только записи в моем основном хранилище данных, которые в настоящее время быть видны на графике. Надеюсь, это поможет любому, кто сталкивается с серьезной проблемой.

Смежные вопросы