Core Plot: Jak zaprezentować popover z paska wybranego przez użytkownika
Używam Core Plot (1.1) do narysowania wykresu słupkowego i chciałbym przedstawić popover z dalszymi szczegółami poniżej paska, który został wybrany (dotknięty) przez użytkownika.
KodMój kod wygląda tak:
- (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];
}
Mój problemPozycja y kontrolera widoku popover jest niepoprawna, jest różna dla każdego pręta i dla pierwszego pręta, który ma ujemną wartość y, jest wyświetlana w górnej granicy paska zamiast dolnej granicy i ukrywa pręt . Pozycja x wydaje się być poprawna.
Proszę pomóżJakieś pomysły na to, dlaczego mój kod nie działa zgodnie z oczekiwaniami?
Dziękuję Ci!
EdytowaćNa podstawie odpowiedzi Erica zaktualizowałem swój kod w następujący sposób:
- (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];
}
Jednak wyniki, które otrzymuję, są bardziej błędne niż wcześniej. Wierzę, że coś źle zrozumiałem. Oto niektóre wyniki poleceń 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}
Wydaje się, że konwersja ze współrzędnych paska na współrzędne widoku jest całkowicie błędna w moim kodzie.
Edytuj 2Jeszcze raz dziękuję za próbkę kodu, Eric!
Zaktualizowałem mój kod i przetestowałem go za pomocą następujących opcji (wartość y = 0:plotPoint[CPTCoordinateY] = CPTDecimalFromFloat(0.0f)
, co skutkuje punktem zakotwiczenia dla popover, którego wartość y wydaje się niepoprawna (patrz poniższy zrzut ekranu). Wartość y punktu kontrolnego powinna być równoważna pozycji0
na osi y.
Następnie próbowałem ustawić wartość y punktu kontrolnego na bieżącą wartość y danych. (plotPoint[CPTCoordinateY] = plotYvalue.decimalValue
). Powoduje to punkt zakotwiczenia, który jest bliski wartości 0 osi y, a nie bliski wierzchołkowi paska. Jednak wartość y zmienia się nieco dla każdej firmy (wartość x), wskazując, że może istnieć problem z przesunięciem wartości y:
Spróbowałem również dodatkowej konwersji, którą zasugerował EricdataPoint = [self.view convertPoint:dataPoint fromView:graph.hostingView]
, ale to nie zmieniło wyników. Ponadto starałem się dodać- graph.paddingTop + graph.paddingBottom
do ostatecznych wartości y, bez powodzenia.
Byłbym wdzięczny za wszelkie pomysły na mój błąd.
Dziękuję Ci!