核心情节:如何从用户选择的栏呈现弹出框
Posted
技术标签:
【中文标题】核心情节:如何从用户选择的栏呈现弹出框【英文标题】:Core Plot: How to present popover from a bar selected by the user 【发布时间】:2012-12-01 09:41:53 【问题描述】:我想完成什么
我正在使用 Core Plot (1.1) 绘制条形图,我想在用户选择(点击)的条形下方显示一个带有更多详细信息的弹出框。
代码
我的代码如下所示:
- (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];
我的问题
popover view controller 的 y 位置不正确,每个 bar 和第一个 bar 都有不同的 y 值,它显示在 bar 的上限而不是下限和隐藏栏。 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
在我的代码中,从条形坐标到视图坐标的转换似乎是完全错误的。
编辑 2
再次感谢您的代码示例,Eric!
我已经更新了我的代码并使用以下选项对其进行了测试(y 值 = 0:plotPoint[CPTCoordinateY] = CPTDecimalFromFloat(0.0f)
,这会导致弹出框的锚点,其 y 值似乎不正确(请参阅以下屏幕截图). 锚点的y值应该等于0
在y轴上的位置。
然后我尝试将锚点的 y 值设置为数据的当前 y 值。 (plotPoint[CPTCoordinateY] = plotYvalue.decimalValue
)。这会导致锚点靠近 y 轴的 0 值,而不是靠近条形的顶部。但是,每家公司的 y 值(x 值)都有一点变化,这表明 y 值的偏移可能存在问题:
我还尝试了 Eric 建议 dataPoint = [self.view convertPoint:dataPoint fromView:graph.hostingView]
的额外转换,但这并没有改变结果。此外,我尝试将- graph.paddingTop + graph.paddingBottom
添加到最终的y 值,但没有成功。
对于我的错误可能是什么,我将不胜感激。
谢谢!
【问题讨论】:
Bar 不是 UIComponent 。它只是一张图。因此,当您为每个条绘制条并存储在数组中时,您需要创建一个 CGRect 点,并且您需要在 touchesBegan: 方法中检查数组中任何矩形中的用户触摸。我也可能错了。但这只是一个想法。 我正在使用- barPlot:barWasSelectedAtRecordIndex:
来获取所选柱的索引及其y值。
【参考方案1】:
-plotAreaViewPointForPlotPoint:
方法返回绘图区域坐标系中的一个点。您需要将其转换为图形的坐标系:
[graph convertPoint:dataPoint fromLayer:graph.plotAreaFrame.plotArea];
图表和它的宿主视图共享一个坐标系。如果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));
【讨论】:
我必须先使用-plotAreaViewPointForPlotPoint:
转换点,然后再使用[graph convertPoint:dataPoint fromLayer:graph.plotAreaFrame.plotArea]
再转换吗?当我链接这两种方法时,我得到了错误的 x 值结果。但是,当我不使用 [graph convertPoint:dataPoint fromLayer:graph.plotAreaFrame.plotArea]
时,我会得到正确的 x 值。这怎么可能?
需要-plotAreaViewPointForPlotPoint:
转换。它采用数据坐标中的值(条形位置和提示)并将它们转换为绘图区域中的视图坐标。
Eric,感谢您提供的代码示例,我已经对其进行了广泛的测试。但是,我仍然对 y 坐标有疑问:似乎 y 值的偏移存在问题。当我将 y 值设置为 0 时,锚点会粘在条形的顶部。对于改变 y 值(例如 0.15 和 0.17),锚点也会改变,但仍然接近 y 轴的 0 值。关于我的代码可能有什么问题的任何想法?谢谢!
Core Plot 将翻转变换应用于 ios 上的托管视图。弹出框锚点的 y 坐标位于翻转坐标系中。您在某处缺少另一个坐标空间转换。
是的,似乎是翻转坐标系导致了这个问题。但是,我完全不知道我应该在哪里需要额外的空间转换(以及我应该如何添加它)。不幸的是,这个坐标空间转换主题对我来说是全新的。您对我如何解决此问题或我应该在哪里查找错误有任何提示吗?非常感谢!以上是关于核心情节:如何从用户选择的栏呈现弹出框的主要内容,如果未能解决你的问题,请参考以下文章
如何使用情节提要从自定义 uitableviewcell 正确启动弹出框转场
Web自动化测试10:Selenium下拉选择框弹出框滚动条操作
updatepanel 里面放ASPxGridView,使用RegisterClientScriptBlock方法,弹出框弹不出