Plot Label Redraw upon Symbol Selection

69 views
Skip to first unread message

Mike Rossetti

unread,
May 23, 2013, 10:53:12 PM5/23/13
to coreplot...@googlegroups.com
In an earlier manifestation of my little iOS plot project I had things set up so that when one tapped on a plot symbol a label would be shown by that symbol and any old label would be removed. It worked fine. Now, not so fine.

My CPTScatterPlotDelegate handles the tap:

- (void)scatterPlot:(CPTScatterPlot*)the_plot
    plotSymbolWasSelectedAtRecordIndex
:(NSUInteger) index {
 
if (self.indexShowingLabel == 999999 || self.indexShowingLabel == index) {
   
[self.plot relabelIndexRange:NSMakeRange(index, 1)];
 
} else {
   
if (self.indexShowingLabel < index)
     
[self.plot relabelIndexRange:NSMakeRange(self.indexShowingLabel,
                                               index
- self.indexShowingLabel + 1)];
   
else
     
[self.plot relabelIndexRange:NSMakeRange(index,
                                               
self.indexShowingLabel - index + 1)];
 
}
 
self.indexShowingLabel = index;
}

This function gets called on a tap and the proper range is invalidated. But the labels are not redrawn.

The CPTPlotDataSource provides the data labels with a -[dataLabelForPlot:recordIndex:] function. It gets called on initial plot draw but not in response to the relabelIndexRange: calls shown above. It's been a while since I was fiddling with this code but I seem to recall that the dataLabelForPlot: was being called in response to a relabelIndexRange:. (I do not have a -[dataLabelsForPlot:recordIndexRange:] function!)

What am I missing?

Thanks in advance!
Mike


Eric

unread,
May 24, 2013, 10:36:21 AM5/24/13
to coreplot...@googlegroups.com
This sounds like a bug. Please report it on the Core Plot issue tracker. I'll try to fix it soon.

Eric

Mike Rossetti

unread,
May 24, 2013, 10:52:01 AM5/24/13
to coreplot...@googlegroups.com
I'll do a bit more research (this evening) first and then 'bug' you if necessary. A quick check shows that the_plot is not the same as self.plot, which is quite unexpected as there is (supposedly) only one plot in existence at the moment. Changing instances of self.plot to the_plot makes no difference though. Intriguing.

Mike

Mike Rossetti

unread,
May 27, 2013, 6:04:51 PM5/27/13
to coreplot...@googlegroups.com
I'll file a bug on this. But I'd be happy to help fix this, with a little insight on the expected invalidation process.

Looking at CPTPlot.m here is what I see:
  1. [-CPTPlot relabelIndexRange: ] sets SPTPlot.needsRelabel via -[CPTPlot setNeedsRelable: ].
  2. -[CPTPlot setNeedsRelable: ] calls -[CPTLayer setNeedsLayout].
  3. -[CPTLayer setNeedsLayout] sends a CPTGraphNeedsRedrawNotification.
  4. The CPTGraphHostingView never receives the notification because…
  5. …the graph hosting view does not collapse layers; my code doesn't setCollapsesLayers: .
Is there a particular reason why a redraw notification is only recognized when the layers are collapsed? Or should there be an alternative path that will cause the plot layer to register for this notification when layers are not collapsed?

Mike

On Friday, May 24, 2013 8:52:01 AM UTC-6, Mike Rossetti wrote:
I'll do a bit more research (this evening) first and then 'bug' you if necessary. A quick check shows that the_plot is not the same as self.plot, which is quite unexpected as there is (supposedly) only one plot in existence at the moment. Changing instances of self.plot to the_plot makes no difference though. Intriguing.

Mike

Eric

unread,
May 28, 2013, 9:40:13 PM5/28/13
to coreplot...@googlegroups.com
The CPTGraphNeedsRedrawNotification notification informs the iOS hosting view that the appearance and/or layout of some part of the graph has changed. This is only important when the hosting view collapses the graph layers and draws everything in one graphics context rather than maintaining the full CALayer tree and letting Core Animation render and composite each layer individually. I don't think this has anything to do with the issue you're seeing.

The call to -setNeedsLayout triggers the -layoutSublayers method the next time Core Animation lays out the layer tree. Inside the -relabel method, accessing the cachedDataCount property loads new plot data and labels if needed. We need to make sure that the relabelIndexRange method sets the flags required for -reloadDataInIndexRange: to be called.

Eric
Reply all
Reply to author
Forward
0 new messages