rstudio / shinydashboard

Shiny Dashboarding framework
https://rstudio.github.io/shinydashboard/
Other
887 stars 299 forks source link

Wordcloud2 blocks plot from initially rendering #281

Open raduromaniuc opened 6 years ago

raduromaniuc commented 6 years ago

Hi,

There is an issue when trying to render both a barplot and a wordcloud. The barplot does not initially render. However, it does render when resizing the window. When the wordcloud is removed, the barplot successfully renders immediately.

I managed to reproduce the issue with the following code:

library(shiny)
library(shinydashboard)
library(wordcloud2)

data <- data.frame(term = c("A", "B", "C", "D", "E"), count = c(10, 15, 3, 5, 7))

body <- dashboardBody(
    fluidRow(
      box(
        plotOutput("barplot"),
        wordcloud2Output("wordcloud")
      )
    )
)

server <- function(input, output) {
  output$wordcloud <- renderWordcloud2({ wordcloud2(data) })
  output$barplot <- renderPlot({ barplot(data$count, names.arg = data$term) })
}

shinyApp(dashboardPage(dashboardHeader(), dashboardSidebar(), body), server)
raduromaniuc commented 6 years ago

It seems to be from wordcloud2 package, version 0.2.1 I downgraded to wordcloud2 version 0.2.0 as ohjakobsen suggested in this post: https://github.com/Lchiffon/wordcloud2/issues/37

Now everything works as expected

harelhan commented 5 years ago

Hi @romaniucradu

Could you please let me know how to install 0.2.0 version of wordcloud2. I am facing the same issue with Shiny and it is really frustrating.

Thanks Hitesh

gunawebs commented 5 years ago

EXACT SAME ISSUE HERE. Cannot thanks @romaniucradu here. Any idea when wordcloud2 would be fixed to handle this? Or is it recommended that we revert to using wordcloud. Thanks again

araupontones commented 5 years ago

I am having the same issue. It seems that wordcloud2 is stopping a table to render. Do you know of a solution? thanks!

stragu commented 5 years ago

I think I have the same issue with the latest wordcloud2 version from GitHub (0.2.2). I am not sure this has been reported at all there – isn't it a wordcloud2 issue? @Lchiffon

Edit: hm not sure what happened exactly, but I updated all my packages and now I can render a wordcloud2 viz at the same time as a ggplot2 + plotly bar chart.

da11an commented 4 years ago

I'm having issues with renderWordcloud2 in a Shiny App. It is causing some of my other uiOutputs to not appear, and it's blocking some of my ggplots, but not always consistently. Downgrading to 0.2.0 from 0.2.1 did not help.

stevecondylios commented 4 years ago

(hacky) Solution

After generating a chart, wordcloud2() uses htmlwidgets::onRender() to render it, but also runs some custom javascript that conditionally reloads the page. Simply by removing this custom javascript, I was able to fix the issues I was experiencing

That is, I simply defined the the following function - wordcloud2a() - and use it in place of the regular wordcloud2()

wordcloud2a <- function (data, size = 1, minSize = 0, gridSize = 0, fontFamily = "Segoe UI", 
          fontWeight = "bold", color = "random-dark", backgroundColor = "white", 
          minRotation = -pi/4, maxRotation = pi/4, shuffle = TRUE, 
          rotateRatio = 0.4, shape = "circle", ellipticity = 0.65, 
          widgetsize = NULL, figPath = NULL, hoverFunction = NULL) 
{
  if ("table" %in% class(data)) {
    dataOut = data.frame(name = names(data), freq = as.vector(data))
  }
  else {
    data = as.data.frame(data)
    dataOut = data[, 1:2]
    names(dataOut) = c("name", "freq")
  }
  if (!is.null(figPath)) {
    if (!file.exists(figPath)) {
      stop("cannot find fig in the figPath")
    }
    spPath = strsplit(figPath, "\\.")[[1]]
    len = length(spPath)
    figClass = spPath[len]
    if (!figClass %in% c("jpeg", "jpg", "png", "bmp", "gif")) {
      stop("file should be a jpeg, jpg, png, bmp or gif file!")
    }
    base64 = base64enc::base64encode(figPath)
    base64 = paste0("data:image/", figClass, ";base64,", 
                    base64)
  }
  else {
    base64 = NULL
  }
  weightFactor = size * 180/max(dataOut$freq)
  settings <- list(word = dataOut$name, freq = dataOut$freq, 
                   fontFamily = fontFamily, fontWeight = fontWeight, color = color, 
                   minSize = minSize, weightFactor = weightFactor, backgroundColor = backgroundColor, 
                   gridSize = gridSize, minRotation = minRotation, maxRotation = maxRotation, 
                   shuffle = shuffle, rotateRatio = rotateRatio, shape = shape, 
                   ellipticity = ellipticity, figBase64 = base64, hover = htmlwidgets::JS(hoverFunction))
  chart = htmlwidgets::createWidget("wordcloud2", settings, 
                                    width = widgetsize[1], height = widgetsize[2], sizingPolicy = htmlwidgets::sizingPolicy(viewer.padding = 0, 
                                                                                                                            browser.padding = 0, browser.fill = TRUE))
  chart
}

And that fixed the issue for me.

Reproducible example of the problem

I had an Rmd with leaflet maps failing to render after a wordcloud2(), despite everything working normally in RStudio.

The following knits the leaflet map perfectly

---
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)
```

```{r}
library(tidyverse)
library(wordcloud2)
library(tidytext)

```

```{r}
# wordcloud2(demoFreq)
```

```{r}
library(maps) # Get coords of Australian cities
aus_cities <- world.cities %>% 
  filter(country.etc == "Australia")
library(leaflet)
pal <- colorNumeric(palette = "YlOrRd", domain = aus_cities$pop) # Set colours
aus_cities %>% 
  leaflet() %>%
  addTiles() %>%
  addCircleMarkers(lat = ~lat, lng = ~long, popup = ~name, 
                   color = ~pal(pop), stroke = FALSE, fillOpacity = 0.6) %>%
  addLegend(position = "bottomleft", pal = pal, values = ~pop)
```

But when # wordcloud2(demoFreq) is uncommented it's knitted again, the wordcloud appears as expected but the leaflet map fails to render.

i.e. on the left is with wordcloud2() commented out, and on the right is after simply uncommenting wordcloud2(demoFreq)

image

And after knitting with the wordcloud2a() hack above, it works as I required:

image

sessionInfo()

R version 3.6.2 (2019-12-12)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] en_AU.UTF-8/en_AU.UTF-8/en_AU.UTF-8/C/en_AU.UTF-8/en_AU.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] tidytext_0.2.2     wordcloud2_0.2.1   forcats_0.4.0      stringr_1.4.0      dplyr_0.8.99.9002  purrr_0.3.3        readr_1.3.1        tidyr_1.0.0        tibble_3.0.0      
[10] ggplot2_3.3.0.9000 tidyverse_1.2.1   

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6            lubridate_1.7.4         lattice_0.20-38         leaflet.providers_1.9.0 assertthat_0.2.1        digest_0.6.25           mime_0.9               
 [8] R6_2.4.1                cellranger_1.1.0        backports_1.1.6         evaluate_0.14           httr_1.4.1              pillar_1.4.3            rlang_0.4.5.9000       
[15] readxl_1.3.1            rstudioapi_0.11         Matrix_1.2-18           rmarkdown_1.12          htmlwidgets_1.3         munsell_0.5.0           shiny_1.3.2            
[22] broom_0.5.2             janeaustenr_0.1.5       compiler_3.6.2          httpuv_1.5.1            modelr_0.1.4            xfun_0.13               base64enc_0.1-3        
[29] pkgconfig_2.0.3         htmltools_0.3.6         tidyselect_1.0.0        fansi_0.4.1             crayon_1.3.4            withr_2.1.2             later_0.8.0            
[36] SnowballC_0.6.0         grid_3.6.2              nlme_3.1-142            jsonlite_1.6.1          xtable_1.8-4            gtable_0.3.0            lifecycle_0.2.0        
[43] magrittr_1.5            tokenizers_0.2.1        scales_1.1.0            cli_2.0.2               stringi_1.4.6           promises_1.0.1          leaflet_2.0.3          
[50] xml2_1.3.1              ellipsis_0.3.0          generics_0.0.2          vctrs_0.2.99.9011       tools_3.6.2             glue_1.4.0              hms_0.4.2              
[57] crosstalk_1.0.0         rsconnect_0.8.16        yaml_2.2.1              colorspace_1.4-1        rvest_0.3.4             knitr_1.27.2            haven_2.1.1 
apsteinmetz commented 4 years ago

wordcloud2a fixed the issue for me. Steve's timing was incredible since it was just yesterday that I narrowed the culprit down to wordcloud2. I, too, was having arbitrary elements not rendering upon startup or, sometimes, even on a refresh. The problem was driving me nuts because the elements that would not render would vary by how they were ordered in the dashboard. Thanks for this fix! I hope it can be incorporated into the package.

WahiduzzamanKhan commented 3 years ago

@stevecondylios Thanks, man!! You are a lifesaver. I was having a similar issue where if I render a wordcloud and a datatable on the same page the datatable doesn't render. But if instead of using renderDT() I put the datatable inside a div() and use renderUI() the table was rendering. But that way I was losing a lot of functionalities. I have spent an unhealthy amount of time trying to figure out what I was doing wrong. wordcloud2a just fixed everything for me.