plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.74k stars 1.83k forks source link

Download plot as a png with Font Awesome fails #6504

Open stumpykilo opened 1 year ago

stumpykilo commented 1 year ago

I have successfully created an annotation on a plot and the Font Awesome icon renders correctly. When I choose to Download plot as a png I get a message that states "Sorry, there was a problem downloading your snapshot!" I have reproduced this with codepen here: https://codepen.io/stumpykilo/pen/Exemaro. Please advise on how to fix or workaround this issue.

Here are the messages that I receive when attempting to download: image

Thank you.

stumpykilo commented 1 year ago

@alexcjohnson any thoughts on this?

alexcjohnson commented 1 year ago

Thanks @stumpykilo - I'm not sure what's going on, but I can confirm the problem. We should console.trace the error that led to "Sorry, there was a problem downloading your snapshot!" to make it easier to debug.

alexcjohnson commented 1 year ago

Actually doesn't give much more info when you find the error. Seems like the canvas.toDataURL call errors, I wonder if it's related to this: https://alligatr.co.uk/blog/render-an-svg-using-external-fonts-to-a-canvas/

stumpykilo commented 1 year ago

@alexcjohnson interesting find. Would this require some changes in how plotly renders or should I try another configuration when downloading the snapshot?

alexcjohnson commented 1 year ago

If that is indeed the problem, we would need to implement the procedure described there, to download, encode, and in-line the relevant font(s). No workaround AFAICT, other than not using icons from the font but instead making your own SVG shape to mimic it

stumpykilo commented 1 year ago

@alexcjohnson I think the former would be best but I'm not sure where to start on that.

alexcjohnson commented 1 year ago

Plotly.downloadImage starts here:

https://github.com/plotly/plotly.js/blob/a8631b8a242a9b14d307e71394a4e0c1ec053531/src/snapshot/download.js#L20

The conversion that I think is failing is here:

https://github.com/plotly/plotly.js/blob/a8631b8a242a9b14d307e71394a4e0c1ec053531/src/snapshot/svgtoimg.js#L63-L71

or maybe it's happening earlier, at setting the initial data url:

https://github.com/plotly/plotly.js/blob/a8631b8a242a9b14d307e71394a4e0c1ec053531/src/snapshot/svgtoimg.js#L104

Either way I think to fix it we'd need to do the font inlining described in that blog post right before we serialize the SVG element here:

https://github.com/plotly/plotly.js/blob/a8631b8a242a9b14d307e71394a4e0c1ec053531/src/snapshot/tosvg.js#L143

stumpykilo commented 1 year ago

@alexcjohnson how would one use their own SVG avoiding having to inline?

alexcjohnson commented 1 year ago

Here's an example where I draw a simple blue triangle: https://codepen.io/alexcjohnson/pen/VwGdzdB?editors=0010

You'd just need to find the path data for the icon you're interested in, and use that instead of my little path attribute in the shape.

stumpykilo commented 1 year ago

@alexcjohnson thanks. How do you find the path data for an icon? Also, I have made progress on the inline option just nowhere near done yet. Would you like to collaborate on it with me?

alexcjohnson commented 1 year ago

This looks like the one you want: https://github.com/FortAwesome/Font-Awesome/blob/6.x/svgs/regular/calendar-days.svg You will likely need to scale it to the pixel size you want, basically multiply all the numbers in the path by the same number, since plotlyjs only supports exact pixel paths right now. Kind of a pain, but there are likely programs out there that will do this (or you can write a small script to do it)

I can’t commit to collaborating, but once you have something working @archmoj or I will be happy to help finish it up.

stumpykilo commented 1 year ago

I tried starting from your SVG codepen example using the calendar-days.svg but that only seems to result in Error: <path> attribute d: Expected number. Have you been able to use something like the calendar-days.svg with Plotly shape path?

stumpykilo commented 1 year ago

@alexcjohnson @archmoj I have created a PR that will need some work done to get it over the finish line.

stumpykilo commented 1 year ago

@alexcjohnson would you have some time to take a look at my PR and let me know if that is the right direction and/or possibly complete it?