Search code examples
iosobjective-ccocoa-touchannotationscore-plot

Changing the position of a CorePlot annotation after zooming(iOS)


I am using a CorePlot ScatterPlot to display data readings from an external bluetooth sensor. Ive gone through the following tutorial: http://www.raywenderlich.com/13271/how-to-draw-graphs-with-core-plot-part-2 and Ive got everything working the way that I would like with one exception. When the user taps on one of the data points, an annotation is placed on top of the data point.

Here is how I create and add the annotations:

NSNumber *value = [self numberForPlot:plot field:CPTScatterPlotFieldY recordIndex:idx];
if (!valueAnnotation) {
    NSNumber *x = [NSNumber numberWithInt:0];
    NSNumber *y = [NSNumber numberWithInt:0];
    NSArray *anchorPoint = [NSArray arrayWithObjects:x, y, nil];
    valueAnnotation = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:plot.plotSpace anchorPlotPoint:anchorPoint];
}

// 5 - Create text layer for annotation
NSString *stringValue = [NSString stringWithFormat:@"%@", value];

CPTTextLayer *textLayer = [[CPTTextLayer alloc] initWithText:stringValue style:style];
valueAnnotation.contentLayer = textLayer;

// 7 - Get the anchor point for annotation
CGFloat x = (CGFloat)idx;
NSNumber *anchorX = [NSNumber numberWithFloat:x];
CGFloat y = [value floatValue]; //edit this line?
NSNumber *anchorY = [NSNumber numberWithFloat:y];
valueAnnotation.anchorPlotPoint = [NSArray arrayWithObjects:anchorX, anchorY, nil];

// 8 - Add the annotation
[plot.graph.plotAreaFrame.plotArea addAnnotation:valueAnnotation];

Ive tried adding a small value to anchorY to move the annotation above the plot point:

CGFloat y = [value floatValue] + 5;

Although this works great at first, when the user zooms in the graph the annotation moves further and further away from the plot point. How can I keep the annotation above or below the plot point while zooming?

I thought I might have to implement the CPTPlotSpaceDelegate method plotSpace: shouldScaleBy: aboutPoint: method, and this is where Im stuck. This is what I have:

-(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint {
     CPTGraph *graph = self.hostView.hostedGraph;
     NSArray *annotations = graph.plotAreaFrame.plotArea.annotations;

     if (annotations.count > 0) {
         CPTPlotSpaceAnnotation *annotation = [annotations objectAtIndex:0];

         NSNumber *anchorX = /* ? */;
         NSNumber *anchorY = /* ? */;

         annotation.anchorPlotPoint = [NSArray arrayWithObjects:anchorX, anchorY, nil];
     }
     return YES;
 }

Im not really sure where to go from here. Any help or direction you could provide would be greatly appreciated.


Solution

  • Use the displacement property to offset the annotation away from the anchor point. The displacement is measured in pixels so it won't change with the plot space.