posit-dev / positron

Positron, a next-generation data science IDE
Other
2.31k stars 68 forks source link

R: HTML with dependencies not rendered (htmlwidgets) #1742

Closed jmcphers closed 8 months ago

jmcphers commented 10 months ago

Positron renders HTML output from R without any trouble -- so long as it's self-contained. For example, this gt example works great:

gt::gt(mtcars)

If, however, it uses external libraries, as is the case for most HTML widgets, rendering usually fails.

Example, courtesy of @DavisVaughan:

stringr::str_view(c("abc", "def", "fghi"), "e", html = TRUE)

This winds up producing an HTML document in a temporary directory that contains a lot of references to libraries that are also in that temporary directory. For example, the HTML sent to Positron from the example above includes:

<script src="lib/htmlwidgets-1.6.2/htmlwidgets.js"></script>
<link href="lib/str_view-0.1.0/str_view.css" rel="stylesheet">
<script src="lib/str_view-binding-1.5.0/str_view.js"></script>
...

There are four ways I can think of that we could fix this:

jmcphers commented 10 months ago

More context on the options after some more research:

Option (1) would be easier if we overrode print.htmlwidget (as opposed to trying to tease metadata back out of the HTML passed to the viewer). This seems like the cleanest way to do things b/c it doesn't involve trying to serialize anything.

Option (2) is the one used by IRKernel, although it has its own handrolled functions for inlining HTML dependencies (and therefore doesn't depend on pandoc). This option has the advantage of being the only one that would work if Ark were run inside Jupyter/JupyterLab. https://github.com/IRkernel/repr/blob/f6efa7622e2a0063826bf1432430d627cdf9dfe6/R/repr_htmlwidget.r#L1-L21

Option (3) is used by RStudio. In this case we'd probably create a comm representing the widget so we could handle the lifetime of the proxy server(s) correctly.

juliasilge commented 8 months ago

Initial implementation in #1822

juliasilge commented 8 months ago

When I went to do a final verification of this, I thought maybe it wasn't actually implemented all the way yet because the first several kinds of htmlwidgets I tried did not work. I do see that leaflet, for example, works but then highcharter does not:

https://github.com/posit-dev/positron/assets/12505835/dcba0c63-7859-4043-b1c2-ec985b88a740

Is this as expected? Do we have a list of htmlwidgets that we do/do not expect to work after this initial implementation? I just happened to try threejs and highcharter, since those are htmlwidgets I have used in my "previous life".

jmcphers commented 8 months ago

I would expect all HTML widgets to work. And in fact highcharter does work for me... sometimes.

image

But, maddeningly, not always. When it doesn't work, there are a bunch of cryptic errors being thrown by highcharter itself, from its minified scripts:

image

I could try to chase those down with a debug copy of highcharter but I'm not sure it's worth spending a day on given that (AFAIK) highcharter isn't really a top 10 library. Did you notice widgets besides highcharter that don't work? I think we could probably close this issue and reopen one to track any remaining widgets that are known to struggle in the Plots pane.

juliasilge commented 8 months ago

Sounds good! I will open a new issue to track remaining troublesome widgets. 👍