核心绘图:应该向绘图空间添加CPTPlotSpaceAnnotation,以重新绘制整个图形



我正在使用核心图来显示价格的时间序列。当用户触摸图形时,我会在该点显示一条可拖动的垂直线。时间序列和可拖动线都是CPTXYGraph中的CPTScatterPlot对象。这非常有效——在时间序列图上拖动直线时的性能是可以接受的。

下一阶段是显示用户选择的价格和日期。雅虎股票应用程序有一个很好的功能,可以在一个标签中显示价格,这个标签会移动,就好像它附着在可拖动线的顶部一样。我已经尝试使用CPTPlotSpaceAnnotation中显示的文本来复制这一点。这是有效的,但会严重影响性能。经过一番挖掘,我发现CPTLayer drawInContext:被调用了多次——每次重新绘制文本标签时,整个图都会被重新绘制(事实上,我的日志暗示它被重新绘制了两次)。

这是绘制标签的代码(正在进行中)。它由plotSpace:shouldHandlePointingDeviceDraggedEvent:atPoint:调用。

- (void)displayPriceAndDateForIndex:(NSUInteger)index atPoint:(CGPoint)pointInPlotArea
{
  NSNumber * theValue = [[self.graphDataSource.timeSeries objectAtIndex:index] observationValue];
  // if the annotations already exist, remove them
  if ( self.valueTextAnnotation ) {
    [self.graph.plotAreaFrame.plotArea removeAnnotation:self.valueTextAnnotation];
    self.valueTextAnnotation = nil;
  }
  // Setup a style for the annotation
  CPTMutableTextStyle *annotationTextStyle = [CPTMutableTextStyle textStyle];
  annotationTextStyle.color = [CPTColor whiteColor];
  annotationTextStyle.fontSize = 14.0f;
  annotationTextStyle.fontName = @"Helvetica-Bold";
  // Add annotation
  // First make a string for the y value
  NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
  [formatter setMaximumFractionDigits:2];
  NSString *currentValue = [formatter stringFromNumber:theValue];
  NSNumber *x            = [NSNumber numberWithDouble:[theDate timeIntervalSince1970]];
  NSNumber *y            = [NSNumber numberWithFloat:self.graphDataSource.maxValue];
  NSArray *anchorPoint = [NSArray arrayWithObjects:x, y, nil];
  // Then add the value annotation to the plot area
  float valueLayerWidth = 50.0f;
  float valueLayerHeight = 20.0f;
  CPTTextLayer *valueLayer = [[CPTTextLayer alloc] initWithFrame:CGRectMake(0,0,valueLayerWidth,valueLayerHeight)];
  valueLayer.text = currentValue;
  valueLayer.textStyle = annotationTextStyle;
  valueLayer.backgroundColor = [UIColor blueColor].CGColor;
  self.valueTextAnnotation  = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:self.graph.defaultPlotSpace anchorPlotPoint:anchorPoint];
  self.valueTextAnnotation.contentLayer = valueLayer;
  // modify the displacement if we are close to either edge
  float xDisplacement = 0.0;
  ...
  self.valueTextAnnotation.displacement = CGPointMake(xDisplacement, 8.0f);
  [self.graph.plotAreaFrame.plotArea addAnnotation:self.valueTextAnnotation];
  // now do the date field
  ...
}

完全重新绘制是否为预期行为?有没有更好的方法来管理注释,而不必在每次调用该方法时破坏它并重新创建它?

您不需要每次都销毁和创建注释。创建后,只需更新anchorPoint。删除和添加注释可能与常量重绘有关。

最新更新