核心图:如何从用户select的栏中显示popup窗口

我想完成什么

我正在使用Core Plot(1.1)绘制条形图,并且想要在用户select(敲击)的小节下面显示更多细节的popup窗口。

我的代码如下所示:

- (void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)idx { NSNumber *yValue = self.values[idx]; NSLog(@"barWasSelectedAtRecordIndex x: %i, y: %@",idx,yValue); NSDecimal plotPoint[2]; NSNumber *plotXvalue = [self numberForPlot:plot field:CPTScatterPlotFieldX recordIndex:idx]; plotPoint[CPTCoordinateX] = CPTDecimalFromFloat(plotXvalue.floatValue); NSNumber *plotYvalue = [self numberForPlot:plot field:CPTScatterPlotFieldY recordIndex:idx]; plotPoint[CPTCoordinateY] = CPTDecimalFromFloat(plotYvalue.floatValue); CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; CGPoint dataPoint = [plotSpace plotAreaViewPointForPlotPoint:plotPoint]; NSLog(@"datapoint (CGPoint) coordinates tapped: %@", NSStringFromCGPoint(dataPoint)); GrowthChartInfoTableViewController *infoViewController = [self.storyboard instantiateViewControllerWithIdentifier: @"GrowthChartInfo"]; self.popover = [[UIPopoverController alloc] initWithContentViewController:infoViewController]; self.popover.popoverContentSize = CGSizeMake(320, 300); self.popover.delegate = self; CGRect popoverAnchor = CGRectMake(dataPoint.x + graph.paddingLeft, dataPoint.y - graph.paddingTop + graph.paddingBottom, (CGFloat)1.0f, (CGFloat)1.0f); [self.popover presentPopoverFromRect:popoverAnchor inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; } 

我的问题

弹窗视图控制器的y位置不正确,每个小节不同,第一个小节有y负值,它在小节的上限而不是下限,并隐藏小节。 x位置似乎是正确的。

在这里输入图像说明

请帮忙

任何想法为什么我的代码不能按预期工作?

谢谢!

编辑

基于Eric的回答,我更新了我的代码,如下所示:

 - (void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)idx { NSNumber *plotXvalue = [self numberForPlot:plot field:CPTScatterPlotFieldX recordIndex:idx]; NSNumber *plotYvalue = [self numberForPlot:plot field:CPTScatterPlotFieldY recordIndex:idx]; CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; CGPoint cgPlotPoint = CGPointMake(plotXvalue.floatValue, plotYvalue.floatValue); CGPoint cgPlotAreaPoint = [graph convertPoint:cgPlotPoint toLayer:graph.plotAreaFrame.plotArea]; NSDecimal plotAreaPoint[2]; plotAreaPoint[CPTCoordinateX] = CPTDecimalFromFloat(cgPlotAreaPoint.x); plotAreaPoint[CPTCoordinateY] = CPTDecimalFromFloat(cgPlotAreaPoint.y); CGPoint dataPoint = [plotSpace plotAreaViewPointForPlotPoint:plotAreaPoint]; NSLog(@"datapoint (CGPoint) coordinates tapped: %@",NSStringFromCGPoint(dataPoint)); GrowthChartInfoTableViewController *infoViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"GrowthChartInfo"]; self.popover = nil; self.popover = [[UIPopoverController alloc] initWithContentViewController:infoViewController]; self.popover.popoverContentSize = CGSizeMake(250, 200); self.popover.delegate = self; CGRect popoverAnchor = CGRectMake(dataPoint.x + graph.paddingLeft, dataPoint.y - graph.paddingTop + graph.paddingBottom, (CGFloat)1.0f, (CGFloat)1.0f); [self.popover presentPopoverFromRect:popoverAnchor inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; } 

但是,我得到的结果比以前更加错误。 我相信我一定有什么误解。 以下是NSLog命令的一些结果:

 barWasSelectedAtRecordIndex x: 0, y: -0.03920931548773198848 datapoint (CGPoint) coordinates tapped: {-6388.88, -67024.8} barWasSelectedAtRecordIndex x: 2, y: 0.174494288286651392 datapoint (CGPoint) coordinates tapped: {-6073.38, -66790} barWasSelectedAtRecordIndex x: 2, y: 0.174494288286651392 datapoint (CGPoint) coordinates tapped: {-6073.38, -66790} barWasSelectedAtRecordIndex x: 0, y: -0.03920931548773198848 datapoint (CGPoint) coordinates tapped: {-6388.88, -67024.8} 

看来从bar坐标到视图坐标的转换在我的代码中是完全错误的。

编辑2

埃里克再次感谢您的代码示例!

我更新了我的代码,并使用以下选项(y值= 0: plotPoint[CPTCoordinateY] = CPTDecimalFromFloat(0.0f) ,结果为y值似乎不正确的popup式窗口的锚点(请参阅到下面的截图),锚点的y值应该等于y轴上0的位置。

在这里输入图像说明

然后我尝试将锚点的y值设置为数据的当前y值。 ( plotPoint[CPTCoordinateY] = plotYvalue.decimalValue )。 这会导致靠近y轴0值的锚点,而不是接近条的顶部。 然而,每个公司(y值)的y值都有一点变化,表明y值的移动可能存在问题:

在这里输入图像说明

我也尝试了额外的转换,埃里克build议dataPoint = [self.view convertPoint:dataPoint fromView:graph.hostingView] ,但这并没有改变结果。 另外,我试图添加- graph.paddingTop + graph.paddingBottom到最后的y值,没有成功。

我将不胜感激我的错误可能是什么。

谢谢!

-plotAreaViewPointForPlotPoint:方法返回绘图区域坐标系中的一个点。 您需要将其转换为graphics的坐标系:

 [graph convertPoint:dataPoint fromLayer:graph.plotAreaFrame.plotArea]; 

该图表及其托pipe视图共享一个坐标系统。 如果self.view不是托pipe视图,则需要将self.view视图中的坐标转换为坐标系。


更完整的代码示例:

 NSDecimal plotPoint[2]; NSNumber *plotXvalue = [self numberForPlot:plot field:CPTScatterPlotFieldX recordIndex:idx]; plotPoint[CPTCoordinateX] = plotXvalue.decimalValue; NSNumber *plotYvalue = [self numberForPlot:plot field:CPTScatterPlotFieldY recordIndex:idx]; plotPoint[CPTCoordinateY] = plotYvalue.decimalValue; CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; // convert from data coordinates to plot area coordinates CGPoint dataPoint = [plotSpace plotAreaViewPointForPlotPoint:plotPoint]; // convert from plot area coordinates to graph (and hosting view) coordinates dataPoint = [graph convertPoint:dataPoint fromLayer:graph.plotAreaFrame.plotArea]; // convert from hosting view coordinates to self.view coordinates (if needed) dataPoint = [self.view convertPoint:dataPoint fromView:hostingView]; NSLog(@"barWasSelectedAtRecordIndex x: %@, y: %@", plotXvalue, plotYvalue); NSLog(@"datapoint coordinates tapped: %@", NSStringFromCGPoint(dataPoint));