2016-05-30 64 views
0

enter image description hereCoreplot註釋不是在正確的位置 - plotAreaFrame.plotArea.touchedPoint是顯示NAN

我使用coreplot顯示曲線圖。註釋不在位置點上方顯示。 當我調試graph.plotAreaFrame.plotArea touchedPoints顯示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;} 

這是coreplot註解顯示方法。

-(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是「南」,而不是正確的點。任何想法有什麼不對? – Cintu

+0

你是否正在計算數據源中'CPTScatterPlotFieldX'的某種運行總數?如果是這樣,您在定位註釋時需要執行相同的數學運算。 –

+0

是的,x軸的數學計算是錯誤的 – Cintu

相關問題