2014-03-11 4 views
3

У меня возникают некоторые проблемы с CorePlot. Я пытаюсь построить несколько рассеивателей в один граф. Что работает, как ожидалось, но когда я начинаю прокручивать или масштабировать график, все приложение увеличивает его использование памяти до 900 МБ сбоев. Я думаю, что мне нужно сделать какой-то объект, но я не знаю, как это сделать. В основном я строю каждую строку с другим идентификатором участка и помещаю соответствующие данные в источник данных.CorePlot множественные диаграммы рассеяния Огромное потребление памяти

Вот что у меня получилось: (. В этом примере кода я просто уменьшить топор диапазоны статических значений для целей тестирования)

- (void)setupGraph { 
// Create graph from theme 
self.graph = [[CPTXYGraph alloc] initWithFrame:self.scatterPlotView.bounds]; 
self.graph.plotAreaFrame.masksToBorder = NO; 
self.scatterPlotView.hostedGraph = self.graph; 

CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainBlackTheme]; 
[self.graph applyTheme:theme]; 

self.graph.paddingLeft = 0.0; 
self.graph.paddingTop = 0.0; 
self.graph.paddingRight = 0.0; 
self.graph.paddingBottom = 0.0; 


// Setup plot space 
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace; 

plotSpace.allowsUserInteraction = YES; 

plotSpace.delegate = self; 

plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(30)]; 
plotSpace.globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)]; 

plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(10)]; 
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)]; 

CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet; 
CPTXYAxis *x = axisSet.xAxis; 
CPTXYAxis *y = axisSet.yAxis; 
x.labelingPolicy = CPTAxisLabelingPolicyNone; 
y.labelingPolicy = CPTAxisLabelingPolicyNone; 
} 

Этот метод загружает мои данные и рисует диаграммы рассеяния

- (void)loadSignals { 


//Data loading logic goes here nothing special just one array for each plot 

for (Signal *sig in [signals allValues]) { 
    [self constructScatterPlot:sig.name]; 
} 
}]; 

Это где рисунок происходит:

- (void)constructScatterPlot:(NSString *)identifier {  
    CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init]; 

    CPTMutableLineStyle *lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy]; 

    CPTScatterPlot *boundLinePlot = [[CPTScatterPlot alloc] init]; 
    boundLinePlot.identifier = identifier; 

    lineStyle   = [boundLinePlot.dataLineStyle mutableCopy]; 
    lineStyle.miterLimit = 1.0; 
    lineStyle.lineWidth = 1.0; 
    lineStyle.lineColor = [CPTColor redColor]; 
    boundLinePlot.dataLineStyle = lineStyle; 

    boundLinePlot.dataSource  = self; 
    boundLinePlot.cachePrecision = CPTPlotCachePrecisionDouble; 
    boundLinePlot.interpolation = CPTScatterPlotInterpolationStepped; 
    [self.graph addPlot:boundLinePlot]; 
} 

... и это где DataSource получает его значения «s:

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
NSString *plotIdent = (NSString *) plot.identifier; 

    if (![plotIdent isEqualToString:self.currentIdent]) { 
     self.countPlot++; 
     self.currentIdent = plotIdent; 
    } 

Signal *newSig = [self.signals objectForKey:plotIdent]; 
    Value * newValue = [newSig valueAtTime:index]; 
NSNumber *number = [NSNumber numberWithInteger:[newValue.value integerValue]]; 

    if (fieldEnum == CPTScatterPlotFieldY) { 

     return number; 
    } 
    if (fieldEnum == CPTScatterPlotFieldX) { 
     return [NSNumber numberWithInteger:index]; 
    } 
    return nil; 
} 

Итак, прежде всего я хотел бы знать, если это правильный способ нанесения нескольких участков (до 40 в моем случае) в одном графике? Если да, то что я могу сделать, чтобы оптимизировать мою работу?

Вывод должен выглядеть следующим образом: Expected (scrollable) output

+0

Что вы используете для countPlot? numberForPlot вызывается каждый раз, когда Core Plot нуждается в паре координат точки графика, поэтому countPlot станет больше при перемещении или масштабировании. – Dirk

+0

My countPlot var увеличивается только тогда, когда нарисован новый график (идентификатор). Этот var используется для определения y-смещения отдельных линий. – Daniel

ответ

2

Каждый участок является CALayer, который охватывает всю площадь участка графика, так и с 40 из них вы можете использовать большую часть доступной видеопамяти. Если все они используют один и тот же стиль линии, вы можете построить все линии на одном и том же участке и сохранить некоторую память таким образом. Вставьте дополнительную точку данных между сегментами линии и возвращайте nil или @(NAN) из источника данных, чтобы разбить линию.

+0

благодарит заранее. Я попробую. – Daniel

+0

Я не совсем понял сообщение Эрика. У вас есть обновление Даниэля? Мои участки могут пересекать друг друга, поэтому дополнительная точка данных не является решением, если я ее достаточно хорошо понял. – CppChase

2

Я нашел применение

"попробуйте установить collapsesLayers ДА на хостинговой зрения"

Application get stuck when drawing nearly 40 Scatter Plots using Core Plot in IPad

+0

Это на самом деле очень помогло мне. С этой настройкой и имея более 40 графиков разброса в реальном времени, использование памяти в моем приложении в среднем при отображении графического представления было более 400 МБ до 35 Мб. – alcamla

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