2016-05-30 2 views
0

enter image description hereCoreplot аннотаций не в нужном месте - plotAreaFrame.plotArea.touchedPoint показывает NAN

Я использую coreplot для отображения графика. Аннотации не отображаются над точками местоположения. Когда я отлаживаю graph.plotAreaFrame.plotArea, touchpointPoints показывает NAN вместо правильных точек.

-(void)configureGraph { 
// 1 - Create the graph 
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:CGRectMake(0.0, 0.0, 320, 260)]; 
[graph applyTheme:[CPTTheme themeNamed:kCPTStocksTheme]]; 

graph.fill = [CPTFill fillWithColor:[CPTColor clearColor]]; 
graph.plotAreaFrame.fill = [CPTFill fillWithColor:[CPTColor clearColor]]; 


// 2 - Set graph title 
NSString *title = @"Speed"; 
//graph.title = title; 
// 3 - Create and set text style 
CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle]; 
titleStyle.color = [CPTColor whiteColor]; 
titleStyle.fontName = @"Helvetica-Bold"; 
titleStyle.fontSize = 16.0f; 
graph.titleTextStyle = titleStyle; 
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop; 
graph.titleDisplacement = CGPointMake(0.0f, 10.0f); 
// 4 - Set padding for plot area 
[graph.plotAreaFrame setPaddingLeft:35.0f]; 
[graph.plotAreaFrame setPaddingBottom:25.0f]; 
[graph.plotAreaFrame setPaddingTop:5.0f]; 
[graph.plotAreaFrame setPaddingRight:0.0f]; 

graph.plotAreaFrame.masksToBorder = YES; 
//graph.plotAreaFrame.plotArea.delegate = self; 


// 5 - Enable user interactions for plot space 
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace; 
plotSpace.allowsUserInteraction = YES; 
plotSpace.delegate = self; 



// 2 - Create the three plots 
CPTScatterPlot *aaplPlot = [[CPTScatterPlot alloc] init]; 
aaplPlot.dataSource = self; 
aaplPlot.delegate = self; 
aaplPlot.plotSymbolMarginForHitDetection = 5.0; 

aaplPlot.interpolation = CPTScatterPlotInterpolationCurved; 
aaplPlot.identifier = @"A"; 
CPTColor *aaplColor = [CPTColor colorWithComponentRed:127.0f/255.0f green:255.0f/255.0f blue:255.0f/255.0f alpha:1.0f]; 
[graph addPlot:aaplPlot toPlotSpace:plotSpace]; 

// 3 - Set up plot space 
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:aaplPlot, nil]]; 
[plotSpace setYRange: [CPTPlotRange plotRangeWithLocation:[NSNumber numberWithInt:0] length:[NSNumber numberWithInt:maxY+10]]]; 
[plotSpace setXRange: [CPTPlotRange plotRangeWithLocation:[NSNumber numberWithInt:0] length:[NSNumber numberWithInt:maxX]]]; 

    // 4 - Create styles and symbols 
CPTMutableLineStyle *aaplLineStyle = [aaplPlot.dataLineStyle mutableCopy]; 
aaplLineStyle.lineWidth = 2.5; 
aaplLineStyle.lineColor = aaplColor; 
aaplPlot.dataLineStyle = aaplLineStyle; 
CPTMutableLineStyle *aaplSymbolLineStyle = [CPTMutableLineStyle lineStyle]; 
aaplSymbolLineStyle.lineColor = aaplColor; 
CPTPlotSymbol *aaplSymbol = [CPTPlotSymbol ellipsePlotSymbol]; 
aaplSymbol.fill = [CPTFill fillWithColor:aaplColor]; 
aaplSymbol.lineStyle = aaplSymbolLineStyle; 
aaplSymbol.size = CGSizeMake(6.0f, 6.0f); 
aaplPlot.plotSymbol = aaplSymbol; 


CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle]; 
axisTitleStyle.color = [CPTColor whiteColor]; 
axisTitleStyle.fontName = @"Helvetica-Bold"; 
axisTitleStyle.fontSize = 12.0f; 
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle]; 
axisLineStyle.lineWidth = 2.0f; 
axisLineStyle.lineColor = [CPTColor whiteColor]; 
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init]; 
axisTextStyle.color = [CPTColor whiteColor]; 
axisTextStyle.fontName = @"Helvetica-Bold"; 
axisTextStyle.fontSize = 11.0f; 
CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle]; 
tickLineStyle.lineColor = [CPTColor whiteColor]; 
tickLineStyle.lineWidth = 2.0f; 
CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle]; 
tickLineStyle.lineColor = [CPTColor blackColor]; 
tickLineStyle.lineWidth = 1.0f; 
// 2 - Get axis set 
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) graph.axisSet; 
// 3 - Configure x-axis 
CPTAxis *x = axisSet.xAxis; 
x.title = @"Distance --> (Points are 200 meter apart)"; 
x.titleTextStyle = axisTitleStyle; 
x.titleOffset = 8.0f; 
x.labelOffset = 0.0f; 


x.axisLineStyle = axisLineStyle; 
x.labelingPolicy = CPTAxisLabelingPolicyNone; 
x.preferredNumberOfMajorTicks = 4; 
x.labelTextStyle = axisTextStyle; 
x.majorTickLineStyle = axisLineStyle; 
x.majorTickLength = 0.0f; 
x.minorTickLength = 0.0f; 

x.tickDirection = CPTSignNegative; 
CGFloat dateCount = [self.arrayOfDates count]; 
NSMutableSet *xLabels = [NSMutableSet setWithCapacity:dateCount]; 
NSMutableSet *xLocations = [NSMutableSet setWithCapacity:dateCount]; 
float i = 0.0; 
for (int index = 0 ; index < [self.arrayOfDates count]; index++) { 

    float distanceX = (float)([[[self.arrayOfDates objectAtIndex:index] objectForKey:@"Distance"] floatValue]); 
    NSString *labelDist = [NSString stringWithFormat:@"%.2f", distanceX]; 
    CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:labelDist textStyle:x.labelTextStyle]; 
    CGFloat location = i++; 
    label.tickLocation = [NSNumber numberWithFloat:i]; 
    label.offset = x.majorTickLength; 
    if (label) { 
     [xLabels addObject:label]; 
     [xLocations addObject:[NSNumber numberWithFloat:location]]; 
    } 

} 
//x.axisLabels = xLabels; 
//x.majorTickLocations = xLocations; 
// 4 - Configure y-axis 
CPTAxis *y = axisSet.yAxis; 
y.title = @"Traffic Density"; 
y.titleTextStyle = axisTitleStyle; 
y.titleOffset = 18.0f; 
y.axisLineStyle = axisLineStyle; 
//y.majorGridLineStyle = gridLineStyle; 
y.labelingPolicy = CPTAxisLabelingPolicyNone; 
y.preferredNumberOfMajorTicks = 4; 

y.labelTextStyle = axisTextStyle; 
y.labelOffset = 0.0f; 
y.majorTickLineStyle = axisLineStyle; 
y.majorTickLength = 0.0f; 
y.minorTickLength = 0.0f; 
y.tickDirection = CPTSignNegative; 
int majorIncrement = ceil(maxY/4); 
NSInteger minorIncrement = maxY/8; 
CGFloat yMax = maxY; // should determine dynamically based on max price 
NSMutableSet *yLabels = [NSMutableSet set]; 
NSMutableSet *yMajorLocations = [NSMutableSet set]; 
NSMutableSet *yMinorLocations = [NSMutableSet set]; 


for (NSInteger j = 0; j <= yMax + majorIncrement; j++) { 
    NSUInteger mod = j % majorIncrement; 
    if (mod == 0) { 
     CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:@"%i", j] textStyle:y.labelTextStyle]; 
     NSDecimal location = CPTDecimalFromInteger(j); 
     label.tickLocation = [NSNumber numberWithInt:j]; 
     label.offset = -y.majorTickLength - y.labelOffset; 
     if (label) { 
      [yLabels addObject:label]; 
     } 
     [yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]]; 
    } 
} 


    y.axisLabels = yLabels; 
y.majorTickLocations = yMajorLocations; 

// Create a plot that uses the data source method 

axisSet.xAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0]; 
axisSet.xAxis.orthogonalPosition = [NSNumber numberWithInt:0]; 

axisSet.yAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:0.0]; 

self.hostView.collapsesLayers = NO; 
self.hostView.hostedGraph = graph;} 

Это метод отображения аннотаций ядра.

-(void)scatterPlot:(nonnull CPTScatterPlot *)plot  plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index 
{ 
CPTGraph *graph = self.hostView.hostedGraph; 

CPTPlotSpaceAnnotation *annotation = self.symbolTextAnnotation; 

if (annotation) { 
    [graph.plotAreaFrame.plotArea removeAnnotation:annotation]; 
    self.symbolTextAnnotation = nil; 
} 

// Setup a style for the annotation 
CPTMutableTextStyle *hitAnnotationTextStyle = [CPTMutableTextStyle textStyle]; 
hitAnnotationTextStyle.color = [CPTColor whiteColor]; 
hitAnnotationTextStyle.fontName = @"Helvetica-Bold"; 
hitAnnotationTextStyle.fontSize = 16.0; 

// Determine point of symbol in plot coordinates 

NSNumber *x = [NSNumber numberWithFloat:[[[self.arrayOfDates objectAtIndex:index] objectForKey:@"Distance"] floatValue]] ; 
NSNumber *y = [NSNumber numberWithFloat:[[[self.arrayOfValues objectAtIndex:index] objectForKey:@"Speed"] floatValue]]; 
CPTNumberArray *anchorPoint = @[x, y]; 

// Add annotation 
// First make a string for the y value 
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 
formatter.maximumFractionDigits = 2; 
NSString *yString = [formatter stringFromNumber:y]; 



CPTPlotSpace *defaultSpace = graph.defaultPlotSpace; 
if (defaultSpace) { 
    CPTTextLayer *textLayer = [[CPTTextLayer alloc] initWithText:yString style:hitAnnotationTextStyle]; 
    annotation     = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:defaultSpace anchorPlotPoint:anchorPoint]; 
    annotation.contentLayer  = textLayer; 
    annotation.displacement  = CGPointMake(0.0, 10.0); 

    [graph.plotAreaFrame.plotArea addAnnotation:annotation]; 
} 
} 

Проверьте скриншот, что точки не выровнены с точками графика.

методы источника данных

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index { 
NSInteger valueCount = [self.arrayOfDates count]; 
switch (fieldEnum) { 
    case CPTScatterPlotFieldX: 
     if (index < valueCount) { 
      distanceX += [[[self.arrayOfDates objectAtIndex:index] objectForKey:@"Distance"] floatValue]; 
      NSLog(@"Distance = %f",distanceX); 
      return [NSNumber numberWithFloat:distanceX]; 
     } 
     break; 

    case CPTScatterPlotFieldY:{ 
     float distance = [[[self.arrayOfValues objectAtIndex:index] objectForKey:@"Speed"] floatValue]; 
     return [NSNumber numberWithFloat:distance]; 

     break; 
    } 
} 
return [NSDecimalNumber zero];} 

enter image description here

Когда я коснулся точки, plotAreaFrame.plotArea.touchedPoint является NAN. Пожалуйста, просмотрите этот снимок экрана

+0

Почему я получаю plotArea TouchedPoint как NAN? – Cintu

ответ

0

Вопрос не показывает методы источника данных, но на основе того, как настроены метки оси X, похоже, что значения x отображаются как индекс данных. Попытайтесь использовать следующий расчет якорной точки при размещении аннотации:

NSNumber *y = [[self.arrayOfValues objectAtIndex:index] objectForKey:@"Speed"]; 
CPTNumberArray *anchorPoint = @[@(index), y]; 
+0

Жаль, что он не работает. Я добавил методы источника данных к вопросу, пожалуйста, проверьте. Когда я отлаживаю, я видел plotAreaFrame.plotArea.touchedPoint - это «NAN» вместо правильных точек. Любая идея, что не так? – Cintu

+0

Вы вычисляете какое-то общее количество для «CPTScatterPlotFieldX» в источнике данных? Если это так, вам нужно сделать одну и ту же математику при размещении аннотации. –

+0

Да, математический расчет оси x был неправильным – Cintu