Core Plot: cómo presentar popover desde una barra seleccionada por el usuario
Estoy utilizando Core Plot (1.1) para dibujar un gráfico de barras y me gustaría presentar una ventana emergente con más detalles debajo de la barra que ha sido seleccionada (pulsada) por el usuario.
CódigoMi código se ve así:
- (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];
}
Mi problemaLa posición y del controlador de vista emergente es incorrecta, es diferente para cada barra y para la primera barra, que tiene un valor negativo, se presenta en el límite superior de la barra en lugar del límite inferior y oculta la barra . La posición x parece ser correcta.
¿Alguna idea sobre por qué mi código no funciona como se esperaba?
¡Gracias!
EditarBasándome en la respuesta de Eric, actualicé mi código de la siguiente manera:
- (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];
}
Sin embargo, los resultados que estoy obteniendo son más erróneos que antes. Creo que debo haber entendido mal algo. Estos son algunos de los resultados de los comandos 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}
Parece que la conversión de las coordenadas de la barra a las coordenadas de la vista es completamente incorrecta en mi código.
Editar 2¡Gracias de nuevo por tu ejemplo de código, Eric!
He actualizado mi código y lo he probado con las siguientes opciones (valor-y = 0:plotPoint[CPTCoordinateY] = CPTDecimalFromFloat(0.0f)
, lo que da como resultado un punto de anclaje para la ventana emergente cuyo valor de y parece ser incorrecto (consulte la siguiente captura de pantalla). El valor de y del punto de anclaje debe ser equivalente a la posición de0
en el eje y.
Luego traté de establecer el valor y del punto de anclaje en el valor actual de los datos. (plotPoint[CPTCoordinateY] = plotYvalue.decimalValue
). Esto da como resultado un punto de anclaje que está cerca del valor 0 del eje y en lugar de estar cerca de la parte superior de la barra. Sin embargo, el valor de y cambia un poco para cada compañía (valor de x), lo que indica que puede haber un problema con el cambio de los valores de y:
También probé la conversión adicional que Eric sugirió.dataPoint = [self.view convertPoint:dataPoint fromView:graph.hostingView]
, pero esto no cambió los resultados. Además, he intentado añadir- graph.paddingTop + graph.paddingBottom
a los valores finales de y, sin éxito.
Agradecería cualquier idea sobre cuál podría ser mi error.
¡Gracias!