I have hundreds of thousands of points of time series data that I want to represent to the user. My current solution is to render said data to a PNG with a 3rd party library and then load that PNG into a NSImage
and display it in a scroll view. This works great, except that:
My current attempt is to directly draw NSBezierPath
s to a NSView
. The view renders beautifully, but very, very slowly, even if I only draw a limited subset of points at a time. And every time I scroll I have to re-draw which is also slow.
I'm certain, as a relative Cocoa newbie, that I'm missing some better ways to do this. What's the "right" way to do it?
My current attempt is to directly draw NSBezierPaths to a NSView. The view renders beautifully, but very, very slowly, even if I only draw a limited subset of points at a time. And every time I scroll I have to re-draw which is also slow.
Before you undertake any drastic solutions, try these simpler steps:
NSRectClip
, passing the rectangle that you take as the argument to drawRect:
. This is a one-liner.NSIntersectsRect
to test whether it's inside the rectangle.delta = -[path lineWidth]
— and yes, you must include that minus sign), then pass the result as both arguments to NSInsetRect
. Make sure you keep the original rectangle around, since different paths may have different linewidths.The idea is, quite simply, to draw less. Setting the clipping path (using NSRectClip
) will reduce the amount of blitting that results from drawing operations. Excluding paths that fall completely outside the draw rectangle will save you the probably-more-expensive clipping for those paths.
And, of course, you should profile at each step to make sure you haven't made things slower. You may want to set up some sort of frame-rate counter.
One more thing: Getting the bounds for each path may be expensive. (Again, profile.) If so, you may want to cache the bounds for each path, perhaps using a parallel NSArray
of NSValue
s or by wrapping the path and bounds together in an object of your own devising. Then you only compute the bounds once and merely retrieve it on future drawing runs.
The docs have a section on NSBezierPath performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With