Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use canvas instead of svg as a default or an option #161

Open
cjyetman opened this issue Jan 11, 2017 · 10 comments
Open

use canvas instead of svg as a default or an option #161

cjyetman opened this issue Jan 11, 2017 · 10 comments

Comments

@cjyetman
Copy link
Collaborator

enable, by default or as an option, plotting using canvas versus svg

I have a working prototype of forceNetwork() working that uses d3 v4 and plots using canvas instead of svg, so it's at least feasible. Apparently, it would afford significant performance gains when plotting with many nodes. Not certain if or what issues this might cause. Thoughts and ideas are appreciated. Maybe I'll get a branch on my fork working and link to it here so people can experiment with it?

(preemptive issue, anticipating/depending on the completed conversion to d3 v4 #143)

@cjyetman
Copy link
Collaborator Author

I'm willing to put some work into this, but it would be more appealing if there was an obvious need. Can anyone provide a plausible, reproducible example where the performance of the networkD3() plot is so bad that it's not very usable, probably because too many nodes or links? I'm not talking about a manufactured dataset with 1000's of nodes, but something with real data that a user might actually want to do. It would be good to use as a benchmark to see if the switch to canvas really makes a substantial difference. I already had a test version running in canvas, so I know it's possible, but the work to put it into a release version would not be trivial. Please test it in the current release version (v0.3).

@christophergandrud
Copy link
Owner

I think this makes a lot of sense. What is the case against using a manufactured data set for testing?

@cjyetman
Copy link
Collaborator Author

  1. To set a reasonable benchmark (1k or 100k nodes?)
  2. For my own personal satisfaction knowing that I'm spending time and effort on something that's actually worthwhile ;-)

@cjyetman
Copy link
Collaborator Author

(As opposed to chasing some convoluted edge case)

@christophergandrud
Copy link
Owner

I know that many people have asked if they can use networkD3 with a significant number of nodes. How much of a performance improvement do you think canvas will give? Will it allow a 1000 node network to be interacted with? (I probably wouldn't recommend this with the current implementation).

@cjyetman
Copy link
Collaborator Author

Alright, I can work with that. 1000 nodes and a few thousand links? It would still be good to be able to load it from a web accessible JSON file, rather than randomly generating it at every run with varying results. I guess I can randomly generate some data and then save it as a JSON somewhere.

@cjyetman
Copy link
Collaborator Author

Before I start in on this again, let me just say that if I sound hesitant about this, which is ironic because it was my proposal, it's only because I worry that adding a parameter to switch between canvas and svg will likely require two significantly different chunks of code in the JavaScript, and therefore increase the effort needed to maintain these scripts.

Having said that, here are a few relevant things that I've learned after a bit of research and experimentation...

  1. Apparently D3 v4+ changed the quadtree implementation for its many-body force to "greatly improve performance", so we may have achieved a significant performance boost already simply by upgrading to a recent D3 version. This old but detailed thread about force performance seems to end with blaming the previous quadtree implementation in D3 before moving on to discussions about using web workers to do the calculations (I don't think using web workers are worth the hassle here).

  2. My impression is that the switch to canvas could improve performance because there's less/no DOM manipulation versus svg which creates new DOM elements for everything it displays. I wonder if that's still relevant or significant as browsers have made significant improvements in their DOM handling in recent years. Bostock claims "slightly better" performance here.

  3. On the bright side, it seems that everything can be handled when using canvas now days... it's no longer required to mix canvas and svg to maintain some interactivity or features of svg.

  4. I've noticed that the 'viewer' in RStudio is drastically slower than viewing the output in a browser (on my machine anyway). Maybe the functions in networkD3 should have an option to display in browser instead of viewer, so users who know their plot is going to be slow can open it straight into the browser... instead of opening it in viewer, clicking the open in browser button once RStudio becomes responsive, switching back to RStudio and closing the viewer pane/windows so it doesn't keep cranking away?

I haven't given up on this yet, just haven't had the time to work on it because I was focussing on other features.

@christophergandrud
Copy link
Owner

Thanks for all of these details.

I kind of like the idea for 4, though I wonder how useful it will be. You could already just run the script from R not in RStudio to avoid the viewer issue. Any other opinions out there on this?

@areeves87
Copy link

areeves87 commented Aug 11, 2018

Hello,

In response to idea 2, I have a shiny app using networkD3 with good performance on a laptop/desktop yet terrible performance on my iphone6s and other smart phones. With just a few dozen nodes, the app is unusable on mobile.

Try for yourself here: https://areeves87.shinyapps.io/flavor-bible/

Could improved smartphone performance be a potential motivating use case for the canvas plots? I've heard mobile performance can suffer during DOM manipulations of large data: https://www.quora.com/Does-D3-js-work-efficiently-on-massive-amounts-of-data-200-million-rows-with-at-least-a-dozen-columns

Pardon any incorrect use of terminology. I am a novice. Hope my point was clear enough.

@cjyetman
Copy link
Collaborator Author

Generally speaking, the canvas approach would have better performance on all platforms, but with other consequences.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants