Hi everyone.
So I have this strange problem, where the clip-path in the SVG is wrong due to addition of the location to the clip-path url.
I have the exact same HTML offline, where when you generate the SVG from a file:// location you get something like:
<defs id="defs-fac894">
<g class="clips">
<clipPath id="clipfac894xyplot" class="plotclip"><rect width="518" height="350"/></clipPath>
...
together with:
<g class="cartesianlayer">
<g class="subplot xy">
...
<g class="plot" transform="translate(42, 50)" clip-path="url(#clipfac894xyplot)">
...
But when you do the same online you get:
<defs id="defs-6f068e">
<g class="clips">
<clipPath id="clip6f068exyplot" class="plotclip"><rect width="518" height="350"/></clipPath>
...
together with:
<g class="cartesianlayer">
<g class="subplot xy">
...
<g class="plot" transform="translate(42, 50)" clip-path="url(https://www.mydomain.com#clip6f068exyplot)">
...
If you use .downloadImage on the original state of each plot, both images are identical. If you do this with a zoomed state, where you pass the x.range and y.range to the layout for .downloadImage the resulting image isn't clipped correctly _in the online version_.
This is an image that results of the first code (used offline with file://-URL) after zooming: svg_offline.zip
This is an image that results of the latter code (used online with https://-URL) after zooming: svg_online.zip
When you change
<g class="plot" transform="translate(42, 50)" clip-path="url(https://www.mydomain.com#clip6f068exyplot)">
to
<g class="plot" transform="translate(42, 50)" clip-path="url(#clip6f068exyplot)">
(in other words: remove the location part from the url) you get the desired image.
This was tested with the current Firefox 63 as well as Firefox 52 ESR and current Microsoft Edge.
Some more notes, that I'll edit on the fly:
So, it seems that setting https://developer.mozilla.org/de/docs/Web/HTML/Element/base only to the top level domain is adding the whole URL to the clip-path url.
@etpinard @alexcjohnson Is it possible to pass an option to plotly to ignore the baseURL setting for the SVG?
where when you generate the SVG from a
file://location
Hmm, how does that work? Could you share more info here?
when you do the same online you get:
I'm not 100% sure what you mean by _online_.
Is it possible to pass an option to plotly to ignore the baseURL setting for the SVG?
It would certainly be possible.
Hmm, how does that work? Could you share more info here?
Provide plotly.min.js locally in a local .html-file and open it. This way you don't look at HTML via HTTP but rather as a static file, thus your "protocol" is not http(s):// but rather file://
when you do the same online you get:
Wrong wording, I mean over http(s)
EDIT: But the actual problem was using a base tag it seems.
It would certainly be possible.
That would be awesome, any way this could be included in a mid-term release? Anyone with a CMS running with a base setting will get screwed when using plotly currently 鈽癸笍
EDIT2: Actually, does it even make any sense honoring the base tag for plotly svg?
The relevant code is here:
I can't of a reason why window.location.href should be part of the clip-part URL in SVG exports in the first place.
Thanks for the report.
@etpinard It even says
We'd better not be exporting from a page
* with a <base> or the svg will not be portable!
馃槶
I can't of a reason why
window.location.hrefshould be part of the clip-part URL in SVG exports in the first place.
For export it shouldn't. But within the page this is necessary if there's a <base>.
One possibility: if we're asked to download the plot as SVG, we can temporarily clear drawing.baseUrl to '', generate the SVG, then put it back when we're done. Only concern with this is when drawing is async, we might draw some normal (not-for-export) plots while baseUrl is removed...
@alexcjohnson Maybe it's safe leaving it out in Plotly.downloadImage then? That's what I use 馃惐
Maybe it's safe leaving it out in
Plotly.downloadImagethen?
Yes, that's the goal (at least when downloading as SVG, I suspect we still need it to download as PNG etc). The difficulty is the way we currently stash baseUrl in the singleton drawing module (at least we do stash it https://github.com/plotly/plotly.js/commit/5887104139256934bbf554bf62685fbec62585d2 馃帀). We could instead stash it with the plot (in _context or _fullLayout or something), but that would require altering every call to setClipUrl to have gd as an argument.
@alexcjohnson actually I have the same problem when saving as PNG. I could just trace the cause by looking at the SVG.
@Braintelligence could you try exporting your graphs using
https://19420-45646037-gh.circle-artifacts.com/0/plotly.min.js
? Thank you!
Using that file doesn't help when testing locally.
You can test it yourself: Just add <base href="FILENAME.html"> for testing purposes to your local html file and open it in your browser.
I have a file://.../.../myFile.html in my clip-path url... same problems :(.
Same is true when I spin up python -m http.server 8080 to reach the contents of the same local folder via http://localhost:8080/myFile.html The clip-path looks like this then: clip-path="url(http://localhost:8080/myFile.html#clipf49e00xyplot)"
EDIT: Just to reiterate: This issue surfaces especially when you modify a given plot such that it's drawn objects can actually clip off the plot. For example if you have bars starting at y=0 you can zoom your y.range so that the lower bound is 20. The bars should now clip through the xaxis.
@etpinard @alexcjohnson
Here's a fiddle you can play around with: https://jsfiddle.net/1Lh8dm49/
See how the xaxis is not clipped at y=0 for the downloaded svg even though the range is set. You also see the base url in the clip-path and when you remove it, the xaxis is clipped as it should be.
Thanks @Braintelligence for testing this. Turns out I made a dumb mistake.
Can you confirm that https://jsfiddle.net/1Lh8dm49/1/ works for you?
Most helpful comment
Yes, that's the goal (at least when downloading as SVG, I suspect we still need it to download as PNG etc). The difficulty is the way we currently stash
baseUrlin the singletondrawingmodule (at least we do stash it https://github.com/plotly/plotly.js/commit/5887104139256934bbf554bf62685fbec62585d2 馃帀). We could instead stash it with the plot (in_contextor_fullLayoutor something), but that would require altering every call tosetClipUrlto havegdas an argument.