Anotasi coreplot tidak berada di lokasi yang tepat - plotAreaFrame.plotArea.touchedPoint menampilkan NAN

masukkan deskripsi gambar di sini

Saya menggunakan coreplot untuk menampilkan grafik. Anotasi tidak ditampilkan di atas titik lokasi. Saat saya men-debug graph.plotAreaFrame.plotArea touchPoints menampilkan NAN alih-alih titik yang benar.

-(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;}

Ini adalah metode tampilan anotasi 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];
}
}

Silakan periksa tangkapan layar bahwa titik-titiknya tidak sejajar dengan titik-titik pada grafik.

Metode Sumber Data

-(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];}

masukkan deskripsi gambar di sini

Ketika saya menyentuh intinya, plotAreaFrame.plotArea.touchedPoint adalah NAN. Silakan lihat tangkapan layar ini


person Cintu    schedule 30.05.2016    source sumber
comment
Mengapa saya mendapatkan plotArea TouchedPoint sebagai NAN?   -  person Cintu    schedule 31.05.2016


Jawaban (1)


Pertanyaannya tidak menampilkan metode sumber data, tetapi berdasarkan cara pengaturan label sumbu x, sepertinya nilai x diplot sebagai indeks data. Coba gunakan penghitungan titik jangkar berikut saat memposisikan anotasi:

NSNumber *y = [[self.arrayOfValues objectAtIndex:index] objectForKey:@"Speed"];
CPTNumberArray *anchorPoint = @[@(index), y];
person Eric Skroch    schedule 30.05.2016
comment
Maaf itu tidak berfungsi. Saya telah menambahkan metode sumber data ke pertanyaan, silakan periksa. Ketika saya melakukan debug, saya melihat plotAreaFrame.plotArea.touchedPoint adalah NAN, bukan titik yang benar. Apakah ada yang salah? - person Cintu; 31.05.2016
comment
Apakah Anda menghitung total berjalan untuk CPTScatterPlotFieldX di sumber data? Jika ya, Anda perlu melakukan perhitungan yang sama saat memposisikan anotasi. - person Eric Skroch; 31.05.2016