How to arrange HTML Widgets inside of a RMarkdown Document (PDF, HTML)

只愿长相守 提交于 2019-11-30 04:58:27

问题


I'm working in a R notebook and would like use it to create two ouptuts: an HTML document and PDF document.

My analysis includes leaflet maps (html widgets), which is causing problems when I knit the notebook to a PDF document. Thanks to the webshot function now included in the knitr package, "knitr will try to generate static screenshots for HTML widgets automatically using the webshot package" (https://github.com/yihui/knitr/blob/master/NEWS.md).

This works fine when my output is a series of leaflet maps stacked on top of each other, but I would like to group the maps together in a more concise row arrangement (see image below).

Here's a reproducible example of my R notebook: gist

Unfortunately, when I try to knit this to a PDF document I get the following error message:

Error: Functions that produce HTML output found in document targeting latex output.
Please change the output type of this document to HTML. Alternatively, you can allow
HTML output in non-HTML formats by adding this option to the YAML front-matter of
your rmarkdown file:

  always_allow_html: yes

Note however that the HTML output will not be visible in non-HTML formats.

How can I get this single-row arrangement in a PDF document?


回答1:


If I understand you correctly, then all you have to do is to add some chunk options. The key here is the option fig.show='hold' which determines that all plots in the chunk will be collected and displayed together at the very end of the chunk.

---
title: "R Notebook"
output:
  pdf_document: 
    keep_tex: yes
  html_notebook: default
---

###Default Arrangement
```{r, echo=FALSE,message=FALSE, fig.height=4, fig.width=2, fig.show='hold'}
#devtools::install_github("wch/webshot")

library(leaflet)
library(htmltools)
library(RColorBrewer)

m1 <- leaflet(quakes) %>% 
        addTiles() %>% 
        addMarkers(lng=174.768, lat=-36.852)

m2 <- leaflet(quakes) %>% 
        addProviderTiles("Esri.WorldGrayCanvas") %>% 
        addMarkers(lng=174.768, lat=-36.852)

m3 <- leaflet(quakes) %>%
        addProviderTiles("Stamen.Toner") %>%
        addMarkers(lng=174.768, lat=-36.852)
m1
m2
m3
```

If you want to have this format for both pdf and html output you could add this script to the body ofyour Rmd document (not inside a chunk):

<script>
  $(document).ready(function() {
    $('.leaflet').css('float','left');
  });
</script>

Trying to add this CSS snippet via the chunk option out.extra does not work, since LaTeX does not know how to deal with CSS. Though the JS code is ignored when compiled to pdf.




回答2:


While the selected answer did resolve my problem, I have decided to take a slightly different approach.

I still adjust the CSS styling, but instead of using a JS script that targets all .leaflet elements, I passed each leaflet htmlwidget to a helper function called styleWidget that adjusts the CSS individually. This function is explained here, but I'll add its definition below anyway:

styleWidget <- function(hw=NULL, style="", addl_selector="") {
        stopifnot(!is.null(hw), inherits(hw, "htmlwidget"))

        # use current id of htmlwidget if already specified
        elementId <- hw$elementId
        if(is.null(elementId)) {
                # borrow htmlwidgets unique id creator
                elementId <- sprintf(
                        'htmlwidget-%s',
                        htmlwidgets:::createWidgetId()
                )
                hw$elementId <- elementId
        }

        htmlwidgets::prependContent(
                hw,
                htmltools::tags$style(
                        sprintf(
                                "#%s %s {%s}",
                                elementId,
                                addl_selector,
                                style
                        )
                )
        )
}

This improves on Martin's solution because it gives more control – for instance, I can now change the third map's stye to float: none; so that the following elements aren't displayed beside the maps. The styleWidget function can be used to modify the CSS of any htmlwidget (although not Shiny widgets), making it a good general-purpose tool to have in the toolbox.



来源:https://stackoverflow.com/questions/39562947/how-to-arrange-html-widgets-inside-of-a-rmarkdown-document-pdf-html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!