Open rbuels opened 12 years ago
An SVG export option would be great. I think it could be done completely within the browser using a data: URI to save the file. Although I guess this would require writing an SVG renderer for the feature tracks.
My current workaround for this issue is to add &tracklist=0&nav=0&overview=0 to the URI and print the page as PDF
Yes it would. Not going to happen.
The current plan is, once all of the tracks are using canvas, to try to stitch all of their contents together into another canvas, then make a data URI from that.
There is a project which simulates a canvas but builds a SVG:
http://svgkit.sourceforge.net/SVGCanvas.html
Would it be possible to write a jBrowse plugin that could export to SVG using something like this? I might look into writing one if I get some time.
That's an interesting idea. Might be worth a shot, if SVGCanvas still works.
You might be able to avoid using SVGCanvas if you write an interface to abstract the drawing operations. The drawing operations for canvas and SVG are basically equivalent, except with some different naming and parameter ordering. You're probably only using a subset of drawing commands for the CanvasFeatures glyphs. If you create two implementations, such as SVGDraw and CanvasDraw, designed with the same interface for drawing operations, with the subset of drawing commands you're using, you can then use them interchangeably in the code., e.g.use CanvasDraw to draw the glyphs in the web page, and use SVGDraw for exporting images.
Being able to export figures in a scalable, resizable format suitable for publications is a must-have for us before we can switch away from our ugly hacked-together Bio::Graphics mess to JBrowse. Actually, I've been thinking about writing a patch for this myself, but I was waiting for the CanvasFeatures code to stabilize a bit, plus I haven't had much time lately at work. If I did find some time to work on it, would you be willing to accept a patch?
Sure, always happy to have contributions of external code. You would
probably want to start on the 2.x
branch, since that's where the work
for the 2.x series of JBrowse is going on.
When you feel ready to start working on this, the best starting point would be to drop into the #gmod IRC channel on the Freenode IRC network during US East business hours, and I can help get you pointed in the right direction.
This is a tough one, I don't have a good idea for solving it yet. It's definitely possible to do with client-side code, and all the other rendering is client-side, and you want the same rendering code to be used for both.
Probably what will have to eventually be done is to write something similar to GD::SVG (which was written to solve this problem in GBrowse), but for canvas
.
The strategy with GD::SVG is that it implements a GD drawing API, but it renders to SVG. So the analogous thing would be to make a fake canvas context2d object that implements a canvas drawing API, but renders to SVG.
That might be a good intern project, now that I think about it. I seem to remember that GD::SVG was done that way. I'll see if my current OICR intern is interested.
Oh right, http://svgkit.sourceforge.net/SVGCanvas.html from earlier in this thread. Should definitely try that first.
Has there been any progress on this? Just have installed jbrowse and love it. Still got to play around with it, but I'm missing two things so far: 1) export to scalable image (such/pdf/eps) 2) an easy way to set a fixed scale (max/min score) per track from within jbrowse, without having to go through "edit track".
I'm tempted to write the second plugin myself and am thinking that the first shouldn't be too hard with SVGCanvas, but haven't used js before. Where could I find the docs for the API?
I'm afraid any docs we have on the API are not in good shape. Your best resource will be the source code itself, for now. You will find embedded JSDoc in much of the codebase, but it has fallen out of maintenance and is incompatible with the current JSDoc.
I never commented on this issue before, but I thought that I'd point out that high res canvas has been available for awhile and it kind of helps with this issue. It doesn't do full svgcanvas, but it can do higher resolution canvas, which is pretty good (previously canvasfeatures were quite blurry if used in a high res context). You can also automate the screenshot process with phantomJS
Example of a pdf rendered with phantomjs: https://www.dropbox.com/s/7pceo4o406dys8s/output.pdf?dl=0
Thanks enuggetry, I'll have a look in to it when I have time.
cmdcolin, I've tried phantoms 2.0, both the binary as well as a fresh compile through macports. Strangely it will work fine for an url such as google.com, but not jbrowse. I've also tried wkhtmltopdf only with similar results.
Can you get a screenshot of the browser on jbrowse.org ? E.g.
phantomjs rasterize.js 'http://jbrowse.org/code/latest-release/?data=sample_data/json/volvox&loc=ctgA:16409..18516&tracks=DNA,CDS,ReadingFrame,volvox-sorted_bam&tracklist=0' jbrowse.pdf "16in*8in"
Where rasterize.js https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js ?
That returns for me a pdf with phantomjs 2.0 (note: i normally use a slightly altered rasterize.js which scales the viewport so it is widescreen, e.g. https://gist.github.com/cmdcolin/7327455a269a11ac4c66)
Note: the phantomjs needs jbrowse 1.11.5+ if you are using a release mode candidate, otherwise you get a blank screen (you can use phantomjs on jbrowse below 1.11.5 with dev mode versions of jbrowse)
Huh, interesting. The phantomjs 2.0 provided rasterize.js doesn't work. Yours does though!
In either case, the imported pdf is not really vector graphics, so I'm toying with the idea of writing a little module that will just pass the location and current tracks to an R script in the background and generate a pdf from there…
On a completely different note: I've written a little dialogue window to conveniently manually set a scale and was thinking of committing it, if this is of interest. I'm clueless which branch I'd commit it to, and how I'd do so, never having worked with javascript and dojo before.
@breichholf interested to see what you come up with. There are not really formal code submitting guidelines afaik so a pull request or just a new git issue with some code pasted is probably fine.
So I've given this a go with your version of rasterize and that does give an image from our install (JB 1.11.6, phantomjs 2.0). There is a problem though which I'm guessing needs some sort of variable test to see if the requested action has completed. Basically what I see is the tracks don't complete loading. We're working with relatively large genome files and I suspect the initial download of the index file is the issue (they can easily be 10-25 MB)
I've found reference to something that theoretically could be used to determine if the page had completed load (for dojo ajax calls). It looks like dojo.request.notify should be able to set a value that can be tested to see if the page has compelted all requested actions.
Then the 'setTimeout' function at the end of rasterize.js could watch for this value being set to true before attempting to render.
@keiranmraine that would definitely be better, otherwise i would have only suggested to increase the timeout.
I think if you want to optimize it for timing, then instead of using something like that notification, the best bet might be to tell phantomjs to just "loop" until it detects something in the DOM (our phantomjs based javascript test runner does this for example https://github.com/GMOD/jbrowse/blob/master/tests/js_tests/run-jasmine.js, but it is looking for DOM elements on the test page, not the jbrowse window)
The reason i say that is because we have discussed that even if we detect when certain javascript code has been run, it does not necessarily mean that the DOM elements have been drawn to the page (see: http://gmod.827538.n3.nabble.com/Gmod-ajax-Detect-when-jBrowse-has-finished-loading-td4043750.html). I could be wrong though!
@cmdcolin , did anything get done with dojo.request.notify? Just looking at this again and although you raise a good point that things may not have rendered, I suspect a wait of 1 second after this variable being set would be sufficient.
I've found in most cases that you are generally only waiting on one the final element to complete not all of the rendering to occur once the transfers are done.
Could you point me to an appropriate place to try patching in this test?
@keiranmraine I did something similar to this and got it to work over selenium.
If anyone needs this capability, the dalliance browser can export SVG images, and it supports many of the same file formats as JBrowse. It also can use the JBrowse-formatted REST API.
... just an update as it's not linked here. The solution I ended on for scripting images generation used puppeteer. It has the ability to monitor inflight http requests so it's pretty easy to determine when a page has fully completed a data load, then pad for the last bit to render. I believe puppeteer can be used within a node module embedded in a site, pulling the relevant OS specific binary when needed.
At least one other option that gives users an easy "click button screenshot" is @bhofmei 's plugin https://github.com/bhofmei/jbplugin-screenshot
The future is of course client side JS that can perform this, but this plugin is a nice option that works with phantomjs in the current mode of things
Edit: bad grammar fix:)
not sure how without canvas...! or even if it is that useful. maybe dump the entire track (not just the part within view ) as an svg?