英文:
Interactive plots from Quarto docs not rendering inside R Shiny using iframe, How to render Quarto ".qmd" files within R Shiny app?
问题
目标
我想在现有的R Shiny应用程序中呈现多个Quarto文件(.qmd)。
当前解决方案
我的当前解决方案是将Quarto文件渲染为HTML,并在R Shiny应用程序中显示HTML文件,但这对于交互式绘图不起作用。我知道我可以在Quarto文档中使用Shiny,但我想在R Shiny内呈现具有其功能的Quarto。
可重现的示例代码
app.R
library(shiny)
library(quarto)
ui <- fluidPage(titlePanel("可重现的示例"),
sidebarLayout(
sidebarPanel(
textInput(inputId = "user_argument", label = "参数"),
br(),
actionButton("render_button", "渲染Quarto")
),
mainPanel(uiOutput("quarto_output"))
))
server <- function(input, output) {
observeEvent(input$render_button, {
quarto::quarto_render("example.qmd",
execute_params = list(user_arg = input$user_argument))
html <- readLines("qmd_output.html")
# 在输出中显示HTML
output$quarto_output <- renderUI({
tags$iframe(srcdoc = html,
height = "500px",
width = "100%")
})
})
}
# 运行应用程序
shinyApp(ui = ui, server = server)
example.qmd
---
title: "Quarto HTML Basics"
format:
html:
code-tools: true
self-contained: true
output-file: "qmd_output.html"
theme: cosmo
execute:
warning: false
params:
user_arg: NA
---
```{r}
#| label: fig-temperatures
#| fig-cap: "New Haven Temperatures"
library(dygraphs)
dygraph(nhtemp) %>%
dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01"))
```
## 参数
我的名字是`r params$user_arg`。
观察
- 当Quarto渲染HTML时,交互式图正常工作,但当相同的HTML在R Shiny内呈现时,它不起作用。
- 我使用iframe,因为直接将HTML插入R Shiny中还会覆盖插入的HTML的CSS。
帮助
- 是否有其他方法可以在R Shiny应用程序内呈现Quarto文件?
- 如果没有,是否有任何选项可以从HTML中在Shiny中呈现交互式图?
英文:
Goal
I want to render multiple Quarto files (.qmd) inside existing one R Shiny App
Current Solution
My current solution is to render Quarto files into html and disply html files inside R Shiny App, however this does not work for interactive plots. I am aware that I can use shiny inside Quarto documents but I want to render quarto with its functionalities inside R Shiny.
Reproducible Example Code
app.R
library(shiny)
library(quarto)
ui <- fluidPage(titlePanel("Reproducable Example"),
sidebarLayout(
sidebarPanel(
textInput(inputId = "user_argument", label = "Argument"),
br(),
actionButton("render_button", "Render Quarto ")
),
mainPanel(uiOutput("quarto_output"))
))
server <- function(input, output) {
observeEvent(input$render_button, {
quarto::quarto_render("example.qmd",
execute_params = list(user_arg = input$user_argument))
html <- readLines("qmd_output.html")
# Display html in output
output$quarto_output <- renderUI({
tags$iframe(srcdoc = html,
height = "500px",
width = "100%")
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
example.qmd
---
title: "Quarto HTML Basics"
format:
html:
code-tools: true
self-contained: true
output-file: "qmd_output.html"
theme: cosmo
execute:
warning: false
params:
user_arg: NA
---
```{r}
#| label: fig-temperatures
#| fig-cap: "New Haven Temperatures"
library(dygraphs)
dygraph(nhtemp) %>%
dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01"))
```
## Argument
My name is `r params$user_arg`.
Observations
- The interactive plot is working when quarto renders the html and not working when same html is rendered inside R Shiny
- I am using iframe because directly inserting the html inside the R Shiny also overrides the css from inserted html.
Help
- Is there any other way to render Quarto files inside R Shiny App?
- If no, any option to render interactive plots in Shiny from html?
答案1
得分: 1
新回答
经过一点小调整,我成功让iframe工作了,而且CSS没有溢出。这是我做的:
首先,在你的app.R所在的目录中创建一个www
文件夹。如果将Web资源放置在这个目录中,它们就可以轻松使用。
接下来,将example.qmd
移动到www文件夹中。最后,将observeEvent更改为以下内容:
observeEvent(input$render_button, {
quarto::quarto_render("www/example.qmd", #注意www/
execute_params = list(user_arg = input$user_argument)
)
html <- "qmd_output.html" #没有www!因为在src调用中,www/是隐含的
# 在输出中显示html
output$quarto_output <- renderUI({
tags$iframe(src = html,
height = "500px",
width = "100%")
})
})
英文:
New answer
After juuust a bit of tinkering, I got the iframe to work, and the CSS doesn't spill over. Here's what I did:
First, create a www
folder in your directory where app.R lives. Web resources can be easily used if they are placed in this directory.
Next, move example.qmd
inside the www folder. Finally, change the observeEvent to this:
observeEvent(input$render_button, {
quarto::quarto_render("www/example.qmd", #note the www/
execute_params = list(user_arg = input$user_argument)
)
html <- "qmd_output.html" # WITHOUT www! Because www/ is implicit in src calls
# Display html in output
output$quarto_output <- renderUI({
tags$iframe(src = html,
height = "500px",
width = "100%")
})
})
Original reply
Not a perfect answer, but this will get your Quarto document showing up:
change the observeEvent to this:
observeEvent(input$render_button, {
quarto::quarto_render("example.qmd",
execute_params = list(user_arg = input$user_argument))
html <- "qmd_output.html" #CHANGED you defined this name in example.qmd
# Display html in output
output$quarto_output <- renderUI({
# I didn't get iframe to work, but using the next line will load the generated HTML
includeHTML(html)
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论