Is it possible to change the data of a googlevis chart (any of them!) without forcing a full reload of the page/chart?
Current code that gives a very undesirable flicker when the map is being reloaded:
shinyServer(function(input, output, session) {
observe({
print("Reloading..")
invalidateLater(update_freq*1000, session)
data <- loadDataFiles()
output$gvis <- renderGvis(mapPlot(data)) //mapPlot returns a new gvisGeoChart
})
Ideally I'd just reload my markers, not the chart itself.
The googleVis Shiny bindings need to be rewritten to fix this problem. In the meantime I have prototyped some ideas here that you might want to check out; you can install it using devtools::install_github("jcheng5/googleCharts") and see the example here. It is pretty rough but you won't get the flickering and instability that currently occurs with googleVis + shiny.
Related
I have multiple renderPlot({}) in my shiny app. I want the plots to start appearing as soon as they are ready to be rendered instead of waiting for all the renderPlots to finish execution. Is there a way to be able to do this?
renderPlotly({
datatablevariable <- ReactiveFn1()
plot_ly()
})
renderPlotly({
datatablevariable <- ReactiveFn2()
plot_ly()
})
In the code above, I want shiny to show the first plot as soon as ReactiveFn1() is done instead of waiting for ReactiveFn2() to be done as well. Hope this example helps!
I have been using R for about a year but am only a few weeks into Shiny. I have some code which calls an API and spits out a nice tables of results which I would like to use in a Shiny App - with the API being called when an action button is clicked.
I've been trouble shooting this for a few days but can't figure it out, below are a few of the things I have tried.
If I remove the action button, the API calls and displays as soon as the app is opened.
Replacing the API with simple text shows the text when the button is clicked.
Rendering the table inside the action results in the UI wondering where the table is (as button as not been pressed) and giving an error.
The API contains sensitive info so I have removed some details added a typical return (it returns Json to the browser when URL is visited).
Any ideas on what i might be missing?
API return
{"meta":{"request":{"granularity":"Monthly","main_domain_only":false,"format":null,"domain":"cnn.com","start_date":"2017-02-01","end_date":"2017-02-28","limit":null,"country":"world"},"status":"Success","last_updated":"2017-04-30"},"visits":[{"date":"2017-02-01","visits":100000`}]}
UI.r
library(shiny)
shinyUI(fluidPage(
headerPanel(actionButton("do", "Click Me")),
mainPanel(dataTableOutput("mytable"))
))
Server.r
library(shiny)
function(input, output) {
#Call API, flatten Json return
Visits_Final<- eventReactive(input$do, {
Results<- paste0("https://api.com/",
"site.com",
"apikey=***") %>%
map(fromJSON, flatten = FALSE)
#Transform into DF
visits_temp= data.frame(date=NA,visits=NA,ID=NA)
for(i in 1:1){
DF_L<- as.data.frame(Results[[i]]$visits)
ID <- (rep(i, nrow(DF_L)))
DF_L<- cbind(DF_L, ID)
Visits_Final<-rbind(visits_temp, DF_L)}})
#Output to UI
output$mytable <- renderDataTable({Visits_Final()})
}
Thanks in advance!
Edits
for(i in 1:i){
As per BigDataScientist comment, changed to
for(i in 1:1){
Code comments added
System info added:
R 3.3.2
R Studio Version 1.0.143
OS Sierra 10_12_3
Solved - In the Server file I changed eventReactive to observeEvent
Honestly, not 100% understanding this documentation but it did help
Shiny: what is the difference between observeEvent and eventReactive?
Feel free to comment with similar problems.
I’m trying to have two spatial plots side-by-side in shiny, and I was suggested a powerful function, sync of mapview. sync allows to have multiple maps for comparison, a great feature, but unable to figure out integrating or calling its output in shiny. I have gone through ‘mapview for shiny’ and other related links mapview/shiny. The former suggested using renderMapview and mapviewOutput, however it did not work, i.e., no map being displayed. Please see the reproducible code. Also, I tried using #map slot of mapview object in renderLeaflet and calling it via leafletOutput - did not work. In both cases, a shiny window pops up and does not display anything. However, do see the following message in the command window: Warning in spCheckObject(x) : Columns CCN_1 in attribute table contain only NA values and are dropped. - it is related to the data base and confirms that mapview command is being executed but does not provide any leads on absence of plots. Greatly appreciate suggestions or clues on displaying mapview geneated plots in shiny.
library(shiny)
library(mapview)
ui <- fluidPage(
mapviewOutput("samplemap"),
p()
)
server <- function(input, output, session) {
output$samplemap <- renderMapview({
mapview(gadmCHE)
})
}
shinyApp(ui, server)
I am using leaflet and shinydashboard to create shiny app which have multiple menus which have a problem of leaftletProxy.
Here I created minimum example to show my question (https://gist.github.com/byzheng/074c3c1ff75ea9f951f5).
In the app, there are two sidebar menus 1) the first menu has a link click me; 2) the second menu has a leaflet map. After clicking click me in the first page, the second page is enabled and then setView of leaflet map to a random place.
The problem is the js console has an error message Couldn't find map with id map when the click me is clicked in the first time and leafletProxy is called.
I think this problem is related with leaflet map isn't initialized when shiny app is loading. After clicking more than one time, everything is working as expected.
So my question is how to force shiny to draw leaflet map when shiny app is loading.
Thanks for any suggestions.
The issue here is that the code creating the leaflet map is suspended while the output$map is hidden.
One way to fix this could be to use:
outputOptions(output,"map",suspendWhenHidden=FALSE)
Unfortunately this seems to be buggy right now but could be fixed soon, it currently throws a js error (see here).
Since output$summary seems to be run after the renderLeaflet, you could use setView in that block as a temporary solution.
output$summary <- renderPrint({
leafletProxy('map') %>% setView(runif(1) * 30 +2, runif(1) * 30 + 2, 7)
print(input$mydata)
print(leafletProxy('map')$id)
})
You should put a need in your reactive. For example:
need(input$button, "Click the button")
Documentation here: http://shiny.rstudio.com/reference/shiny/latest/validate.html
Or you could just return when the proxy is NULL:
if (is.null(proxy)) {
return(NULL)
}
To simplify this example I've only included the necessary code to describe the issue I'm having. Should it be required, I will include a fully reproducible example, but I have a hunch that this issue can be solved through theory alone by someone with more experience using Shiny. Basically, I've programmed a Shiny app in R which looks something like this:
ui.R
plotOutput(outputId = 'heatmap1', height = "800px")
uiOutput('selectStrains')
uiOutput('selectRegions')
server.R
output$selectStrains = renderUI({
checkboxGroupInput(inputId='strains',
choices=sort(colnames(mousedata)),
selected=colnames(mousedata))
})
output$selectRegions = renderUI({
checkboxGroupInput(inputId='regions',
choices=sort(rownames(mousedata)),
selected=rownames(mousedata))
})
# more code
output$heatmap1 = renderPlot({
input$recalculate
mousedatamat = as.matrix(mousedata[isolate(input$strains), isolate(input$regions)])
heatmap.2(mousedatamat)
})
problem:
My problem is that in server.R, when the app is first loaded, input$strains and input$regions are both NULL. Therefore, mousedatamat in server.R will be a 0x0 matrix, and the heatmap will be empty on the front page of the app, which makes for a pretty poor user experience. I don't know how the ui.R and server.R files interact when an app is launched, so I'm finding it difficult to debug. To make the plot show up I either need to click a recalculate button (input$recalculate), or resize the window (but only in the horizontal dimension for some reason).
To add more mystery to the mix, I have the same heatmap figure on page 2 (I'm using a navbarPage layout), which shows up on the app load when I navigate to that tab! It is the very same code, only instead it is assigned to output$heatmap2. When I navigate back to page 1, output$heatmap1 still does not display.
I've tried placing the calls to uiOutput above plotOutput in ui.R, but the main reason I don't know how to solve this I think is because I don't know much about execution flow when an app is started. Any ideas or information on this topic?