tutorial sistema que operativo guide development developer dev desarrollo desarrollador con app aplicaciones objective-c ios uiview core-plot uipopovercontroller

objective c - sistema - Core Plot: Cómo presentar popover desde una barra seleccionada por el usuario



sistema operativo ios pdf (1)

El método -plotAreaViewPointForPlotPoint: devuelve un punto en el sistema de coordenadas del área de trazado. Necesita convertir eso al sistema de coordenadas del gráfico:

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

El gráfico y su vista de alojamiento comparten un sistema de coordenadas. Si self.view no es la vista de alojamiento, deberá convertir las coordenadas a su sistema de coordenadas desde la vista de alojamiento.

Una muestra de código más completa:

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));

Lo que me gustaría lograr

Estoy usando Core Plot (1.1) para dibujar un gráfico de barras y me gustaría presentar un popover con más detalles debajo de la barra que el usuario ha seleccionado (tocado).

Código

Mi 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 problema

La posición y del controlador de vista popover es incorrecta, es diferente para cada barra y para la primera barra, que tiene un valor y 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.

Por favor ayuda

¿Alguna idea sobre por qué mi código no funciona como se esperaba?

¡Gracias!

Editar

Basado en la respuesta de Eric, he actualizado 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 recibo son más erróneos que antes. Creo que debo haber malinterpretado 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 barras a las coordenadas de vista es completamente incorrecta en mi código.

Editar 2

¡Gracias de nuevo por su muestra de código, Eric!

He actualizado mi código y lo he probado con las siguientes opciones (y-value = 0: plotPoint[CPTCoordinateY] = CPTDecimalFromFloat(0.0f) , que da como resultado un punto de anclaje para el popover cuyo valor de y parece ser incorrecto (consulte a la siguiente captura de pantalla). El valor y del punto de anclaje debe ser equivalente a la posición de 0 en el eje y.

Luego traté de establecer el valor y del punto de anclaje al valor y 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 y cambia un poco para cada compañía (valor x) lo que indica que puede haber un problema con el cambio de los valores y:

También probé la conversión adicional que Eric sugirió dataPoint = [self.view convertPoint:dataPoint fromView:graph.hostingView] , pero esto no modificó los resultados. Además, traté de agregar - graph.paddingTop + graph.paddingBottom a los valores y finales, sin éxito.

Agradecería cualquier idea sobre cuál podría ser mi error.

¡Gracias!