Reputation: 11
This is my first ever stack overflow question so please let me know if you think I haven't done this properly.
I'm using flexdashboard and shiny modules to create an interactive document and I want to include an rPivotTable and a download button which downloads the pivot table as a csv. This csv should contain the data table created when the user changes the input of the rPivotTable.
I have used other stack overflow answers (such as the one in here: download rpivotTable ouput in shiny) to write the code and I feel like I'm close. However, when I run the code below, open the interactive document in my Chrome browser, and click the Download button an error occurs. The little download bar that pops up at the bottom of the page on Chrome doesn't show the csv file but instead shows the message "Failed - Server problem". To see whether aSummaryTable
gets produced at all I included the output in the UI (DT::dataTableOutput(ns("aSummaryTable"))
) but when I run the Rmd the resulting document only displays the rPivotTable and the Download button.
I'm quite new to shiny and have never used java script so I don't really understand the onRefresh
part of my code:
onRefresh = htmlwidgets::JS("function(config) {
Shiny.onInputChange('myData', document.getElementById('pivot').innerHTML);
}")
Here is my complete (and hopefully reproducible) Rmarkdown code. (if you have any ideas why I might be getting this error and how I could solve this problem, I would be extremely grateful)
---
title: "Report"
output:
flexdashboard::flex_dashboard:
theme: simplex
orientation: rows
social: menu
source_code: embed
runtime: shiny
---
```{r setup, include=FALSE}
## Installing packages if not already installed & require(package)
usePackage <- function(p) {
if (!is.element(p, installed.packages()[,1]))
install.packages(p, dep = TRUE)
require(p, character.only = TRUE)
}
usePackage('flexdashboard')
usePackage('plotly')
usePackage('data.table')
usePackage('rpivotTable')
usePackage('knitr')
usePackage('Rcpp')
usePackage('stringi')
usePackage('tidyr')
usePackage('chron')
usePackage('DT')
usePackage('caroline')
usePackage('rvest')
usePackage('htmlwidgets')
```
Demo
=========================
### Demo
```{r, include=FALSE}
# UI function
demoUI <- function(id) {
ns <- NS(id)
fillCol(height = 600, flex = c(NA, 1),
DT::dataTableOutput(ns("aSummaryTable")),
rpivotTableOutput(ns("pivot"))
,
inputPanel(
downloadButton(ns('downloadData'), 'Download ')
)
)
}
# Server function
demoServer <- function(input, output, session) {
output$pivot <- renderRpivotTable({
library(htmlwidgets)
library(rpivotTable)
rpivotTable(data = datasets::mtcars, aggregatorName = "Count", rendererName = "Bar Chart",
onRefresh = htmlwidgets::JS("function(config) {
Shiny.onInputChange('myData', document.getElementById('pivot').innerHTML);
}"))
})
# Clean the html and store as reactive
summarydf <- eventReactive(input$myData,{
library(htmlwidgets)
input$myData %>%
read_html %>%
html_table(fill = TRUE) %>%
.[[2]]
})
# show df as DT::datatable
output$aSummaryTable <- DT::renderDataTable({
DT::datatable(summarydf(), rownames = FALSE)
})
output$downloadData <- downloadHandler(
filename <- "rpivottable_mtcars.csv",
# This function should write data to a file given to it by
# the argument 'file'.
content = function(file) {
# Write to a file specified by the 'file' argument
write.csv(summarydf(), file,
row.names = FALSE)
}
)
}
```
```{r}
demoUI("demo")
callModule(demoServer, "demo")
```
EDIT: I've just managed to fix this myself. It seems like one can't send the data as sliced by the rPivotTable from the client back to the server when using Shiny Modules. It does work, however, when instead using an Inline Application or an External Application. Here's a reproducible and finally working code for this (just in case anyone ever comes across this problem):
---
title: "Report"
output:
flexdashboard::flex_dashboard:
theme: simplex
orientation: rows
social: menu
source_code: embed
runtime: shiny
---
```{r setup, include=FALSE}
## Installing packages if not already installed & require(package)
usePackage <- function(p) {
if (!is.element(p, installed.packages()[,1]))
install.packages(p, dep = TRUE)
require(p, character.only = TRUE)
}
usePackage('flexdashboard')
usePackage('plotly')
usePackage('data.table')
usePackage('rpivotTable')
usePackage('knitr')
usePackage('Rcpp')
usePackage('stringi')
usePackage('tidyr')
usePackage('chron')
usePackage('DT')
usePackage('caroline')
usePackage('rvest')
usePackage('htmlwidgets')
```
Demo
=========================
### Demo
```{r}
shinyApp(
ui = fillPage(
fillCol(flex = c(NA, 1),
DT::dataTableOutput("aSummaryTable"),
rpivotTableOutput("pivotTab")
,
inputPanel(
downloadButton('downloadData', 'Download ')
)
)),
server = function(input, output, session) {
output$pivotTab <- renderRpivotTable({
rpivotTable(data = datasets::mtcars, aggregatorName = "Count", rendererName = "Table",
onRefresh = htmlwidgets::JS("function(config) {Shiny.onInputChange('myData', document.getElementById('pivotTab').innerHTML);}")
)
})
# Clean the html and store as reactive
summarydf <- eventReactive(input$myData,{
input$myData %>%
read_html %>%
html_table(fill = TRUE) %>%
.[[2]]
})
# show df as DT::datatable
output$aSummaryTable <- DT::renderDataTable({
DT::datatable(summarydf(), rownames = FALSE)
})
output$downloadData <- downloadHandler(
filename <- "rpivottable_mtcars.csv",
content = function(file) {
write.csv(summarydf(), file,
row.names = FALSE)
}
)
}
)
```
Upvotes: 1
Views: 788