Another difference is the foreground and background variables refer to canvas rendering contexts rather than a group of SVG paths.
Canvas has some built-in inerpolators too. Check out the paths section:
http://simon.html5.org/dump/html5-canvas-cheat-sheet.html
The interaction can bog down based on how many rows are selected. The
foreground is completely redrawn every brush event. Rendering paths is
still a bottleneck. This depends on the size of the canvas too. A
canvas with half the height will be 30-50% faster, it seems.
Firefox throws long-running script alerts. Perhaps
requestAnimationFrame can be used to chunk together the drawing of
paths, so that only 50-100 lines are drawn at a time. This way the
user might get more immediate feedback, even if it takes a moment for
the chart to fill in.
I hope this will be able to deal well with 30k+ lines, possibly up to 100k.
Unfortunately with this technique, the interface is prone to
"flashing", since it will show the canvas state after it's been
cleared but before most lines have been drawn. It's annoying to see
lines re-render after small changes to the filter.
I have been working on a new time-series visualization library (part
of Cube 0.2.0) that combines SVG and Canvas to render real-time
metrics. The nice thing about Canvas is that when new data comes in, I
can simply blit the old data to the left by one pixel, expending very
little effort drawing new data. This approach lets the library scale
to hundreds of metrics by thousands of samples (~300,000 data
points!), updating every ten seconds.
Many assume (speaking in the abstract here) that Canvas is magically
faster than SVG in the general case. This is not true, of course; the
real benefit of Canvas is being able to control what gets drawn on
update. In some cases, you can achieve a similar effect with SVG by
applying CSS3 transforms, which cause the SVG to be rendered as a
texture, much like Canvas. For example, try clicking and dragging in
the middle to rotate:
http://mbostock.github.com/d3/talk/20111116/bundle.html
My hope is that browser vendors continue to make SVG renderers smarter
and faster. There has been some promising work at NVidia to push the
entire SVG down to the GPU, for example:
http://developer.nvidia.com/nv-path-rendering
Unrelated: I seem have to problems using the brush component in your
demos, Kai. For example, if I brush an axis, I can't click on the
background of the axis to clear the brush. Is it just me?
Mike
OK, this was a bug in release 2.9.0, and has now been fixed in 2.9.1 Oops!
Mike
I tried caching the pixel data, but I couldn't figure out how to
squeeze more performance out of it. The cache is contained in the
"foreground_cache" variable, and the "staging" canvas is used to
rerender lines and draw them to the foreground:
Paths are rendered only once, and image data is cached for redrawing.
Redrawing a single path requires one clearRect, putImageData and
drawImage call. The net effect seems much slower than simply
rerendering paths with moveTo/lineTo.
Transparency doesn't work with putImageData, which is why the staging
canvas is required.
I also tried avoiding putImageData by storing Image elements instead
of pixel arrays, but that was even slower:
http://stackoverflow.com/questions/3952856/why-is-putimagedata-so-slow/4282335#4282335
Any ideas on improving this caching/redrawing?
Some D3 demos that definitely run slowly on the iPad 3. If we could
characterize the specific kinds of D3 features that run slowly, we
could (a) send in useful bug reports and (b) know which features to
avoid. Seems like something worth tracking and investigating...
-r
--
http://www.cfcl.com/rdm Rich Morin
http://www.cfcl.com/rdm/resume r...@cfcl.com
http://www.cfcl.com/rdm/weblog +1 650-873-7841
Software system design, development, and documentation
And here's the bug-free fix for IE9:
https://github.com/mbostock/d3/pull/618
--
Jason Davies, http://www.jasondavies.com/
A further improvement might be to base the rendering order on the
user's last interaction. For instance, if brushed from 30 -> 50 g of
fat, the selection sorts by fat (increasing) and renders in that
order. Removing a filter doesn't require clearing the canvas and
existing lines don't need to be re-rendered. For now the shuffled
render order is a simpler solution though.
Added tick hiding, dynamic opacity, bezier curves, a dark theme:
Compare to sequential rendering order here: