rshinyr-leafletrcharts

Create interactive webmap with markers in R using Shiny, Leaflet and rCharts


I am trying to create an interactive webmap in R to display storms using Shiny, Leaflet and rCharts (the structure is loosely based on the http://ramnathv.github.io/bikeshare app).

The idea is that the user selects one storm name at a time (df$Name) and the markers for that storm (lat/long) are displayed in a Leaflet map (with zoom in/out function).

I cannot get Leaflet to load a new map and markers for each separate storm name.

This is what the data (TCs.Rda) look like (sample data file uploaded here):

 Year   Name   Wind   lat    long
 2010   BONNIE 15     30.100 -91.000
 2010   FIVE   25     30.000 -88.900
 2010   FIVE   25     30.400 -88.800
 2010   FIVE   25     30.800 -88.600

server.R

library(shiny); library(rCharts); library(leaflet)    
load("TCs.Rda") 
name <- sort(unique(data$Name)) 
shinyServer(function(input, output){      
     dataset <- reactive({  df <- data[data$Name == input$name, ]  })    
     output$add <- renderText({paste("Storm name:", input$name)})  
     output$Controls <- renderUI({  
         list(selectInput("name", "Select storm", name, selected=name[1])) })  
     output$myChart <- renderMap({
         df <- dataset()
         map <- Leaflet$new()
         map$setView(c(35, -80),zoom=5) 
         map$tileLayer(provider='Stamen.TonerLite')          
         for (i in 1:nrow(df)) {
         map$marker(c(df[i, "lat"], df[i, "long"]), bindPopup=df[i, "Wind"])}  
         map$set(dom='myChart')
         map$enablePopover(TRUE)
         map$fullScreen(TRUE)
         map      
       })  
    })

ui.R

library(shiny); library(rCharts); library(leaflet)
shinyUI(pageWithSidebar( 
  headerPanel("Storm tracks"),  
  sidebarPanel(h3("My subtitle"), uiOutput("Controls")),  
  mainPanel(                     
     tabsetPanel(        
        h3(textOutput("add")),             
        tabPanel("map", tags$style(".leaflet {height: 400px;}"),  # I can only get this to work with a tabset panel, but ideally both the textOutput and map would go directly in the mainPanel 
        showOutput("myChart", "leaflet")))
      )
  ))

Solution

  • I figured it out myself eventually! Another post (Shiny renders a responsive rCharts leaflet map once, but is blank if you change the input variable) indicated that the line of code "map$set(dom='myChart')" could be preventing Leaflet from reloading a new map on each selection.

    I didn't think that could be the issue here (my example is a little different and does not use geojson), but apparently it was.

    This is my working code, in case it helps anyone else -

    server.R

    library(shiny);library(rCharts);library(leaflet)
    load("TCs.Rda")
    name <- sort(unique(data$Name)) 
    shinyServer(function(input, output){
       dataset <- reactive({df<- data[data$Name == input$name, ]})    
       output$add <- renderText({paste("Storm name:", input$name)})   
       output$Controls <- renderUI({list(selectInput("name", "Select storm", name, selected=name[1]) ) })   
    output$myChart <- renderMap({
       df <- dataset()
       map <- Leaflet$new()
       map$setView(c(35, -80),zoom=3)
       map$tileLayer(provider='Stamen.TonerLite')       
       for (i in 1:nrow(df)) {map$marker(c(df[i, "lat"], df[i, "long"]))}        
       map$fullScreen(TRUE)
       map      
      })  
    })
    

    ui.R

    library(shiny); library(rCharts); library(leaflet)
    shinyUI(pageWithSidebar( 
       headerPanel("Storm tracks"),  
       sidebarPanel(h3("My subtitle"), uiOutput("Controls")),  
       mainPanel(      
          tabsetPanel(        
            tabPanel("map", h3(textOutput("add")),
                 tags$style(".leaflet {height: 400px;}"), 
                 showOutput("myChart", "leaflet")))
      )
      ))
    

    And the result looks like this:

    enter image description here