Problem with highchartr, insertUI and removeUI in Shiny R. Error in shinyapp.js

2

Hi, I'm all working with an application shiny with a navbarPage several tabsetPanel . I would like the ui of each tab panel to be temporary, with this I mean that I hope to get the application to only load the ui in which the user is. This to avoid generating a code too long. For this gender ui from files R individual% for each tabsetPanel , I charge them to the application as needed with the function source("ui_temp_idpanel.R") . I remove the ui of the tab previous in which the user was with the help of the function removeUI and insert the new ui in the tab in which the user is currently with the function insertUI . The problem was when I used the highchater library to include a map (it is important to mention that when graphics generated with a library are included this problem does not occur.) . When there is only one map there is no problem, however when there is more than one (in different tabPanel ) the problem appears. I also noticed that the problem arises due to the use of the functions removeUI e insertUI , since I tried the case in which the ui of the maps are fixed and the problem does not occur. Some of the things I tried was to erase the ouput$id_mapa of the tab previous when the user changes tab , I think I can do it with ouput$id_mapa<-renderHighChart({}) , but I do not solve the problem.

When inspecting the application in a browser this is the error code that it throws at me:

  GET http://127.0.0.1:5642/undefined 404 (Not Found)    
  VM114:69 Uncaught TypeError: Cannot read property 'map' of null

You might think there is an error sending the map to the hchart() function. The strange thing is that at first the application works without problem, it is until after having generated a map in tab1 , a map is generated in tab2 and then you return to tab1 when the error passes. After the error the application stops generating the maps and depends on the place where you run removeUI e insertUI that the app can present other errors. If you insist on changing tabs after the error, new errors appear:

shinyapp.js:360 Uncaught Duplicate binding for ID mapa2
shinyapp.js:360 Uncaught Duplicate binding for ID mapa1

This is all I know about the problem. I have recreated the error in a simpler application that I leave below:

Example App that presents the error.

#Ejemplo Mapa
nac<-list(type="FeatureCollection",
          features=list(list(type="Feature",
          properties=list(state_code=list(0),state_name=list("Nacional")),
          geometry=list(type="Polygon",
                        coordinates=list(list(list(-95,26),
                                              list(-91,26),
                                              list(-91,22),
                                              list(-95,22),
                                              list(-95,26)))))))
#Variable para insertar ui al inico de la app
inicio<-1


library(shiny)
library(highcharter)

#Crear uis para cambiar decuardo al tab
ui_mapa1<-tagList(div(
  highchartOutput("mapa1")
))

ui_mapa2<-tagList(div(
  highchartOutput("mapa2")
))


#ui
ui <- fluidPage(

   # Application title
   titlePanel("Problema con highchartr and removeUI"),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
        colourInput("colormap",h3("Color"),value = "#2c3e50"),
        actionButton("mapa","Mapear",icon('globe'))
      ),

      # Main ppanel
      mainPanel(
        #En el tabsetpanel se comentaron los tabpanel con los ui fijos
        #y se incluyeron dos tabpanel para insertar ahi los tab donde ve el 
        #usuario.
         tabsetPanel(id="tabpanel",
           # tabPanel("Mapa1",div(highchartOutput("mapa1"),id="Mapa1")),
           # tabPanel("Mapa2",div(highchartOutput("mapa2"),id="Mapa2"))
           tabPanel("Mapa1",div(id="Mapa1")),
           tabPanel("Mapa2",div(id="Mapa2"))
         )
      )
   )
)

# server
server <- function(input, output,session) {

  #Se carga el ui en el tab2 al inicio
  if(inicio==1){
    insertUI(selector = "#Mapa2",
             ui=ui_mapa2)
    inicio<-2
  }


  #Se crean valores reactivos para guardar los tags, unos datos para el mapay
  #y dos valores para controlar la reactividad de los mapas
  rv<-reactiveValues(
    ulttag=NULL,
    acttag="Mapa2",
    data_mapa=data.frame(),
    mapa1=0,
    mapa2=0
  )


  #Cuando se cambie de tab corre este codigo
   observeEvent(input$tabpanel,{
     #Guarda en que tag estuvo anteriormente, y en cual esta actaulmente
     rv$ulttag<-rv$acttag; rv$acttag<-input$tabpanel

     #Encuentra el ui que debe insertar
     if(rv$acttag=="Mapa1"){
       uires<-ui_mapa1
     }else{
       uires<-ui_mapa2
     }

     #Remueve el ui del ultimo tag y inserta el ui del tag actual
     removeUI(selector = paste("#",rv$ulttag," > *",sep=""))
     insertUI(selector = paste("#",rv$acttag,sep=""),
              ui=uires)
   })


   #Cuando demos clic en el boton mapear carga los datos de cada tab
   #y cambia el valore reactivo
   observeEvent(input$mapa,{

     if(rv$acttag=="Mapa1"){
       data<-as.data.frame(cbind(c(0),c(4)))
       names(data)<-c("id.edo","value")
       rv$mapa1<-rv$mapa1+1
       rv$data_mapa<-data }else{#Mapa 2
         data<-as.data.frame(cbind(c(0),c(8)))
         names(data)<-c("id.edo","value")
         rv$data_mapa<-data
         rv$mapa2<-rv$mapa2+1
       }

   })



   ##Genara el mapa 1

   output$mapa1<-renderHighchart({
     rv$mapa1

     isolate(highchart(type = "map") %>%
               hc_chart(backgroundColor = "#FFFFFF") %>%
               hc_add_series(mapData = nac, showInLegend = FALSE, nullColor = "#424242",
                             borderWidth = 0,data = rv$data_mapa, value = "value",
                             joinBy = c("state_code", "id.edo"), name = "IVP" ,
                             dataLabels = list(enabled = TRUE, format = '{point.properties.state_name}'),
                             borderColor = "#FAFAFA", borderWidth = 0.1,
                             tooltip = list(pointFormat='{point.properties.state_name}: {point.value}<br/>',
                                            valueDecimals = 2),
                             states=list(
                               hover=list(
                                 color= "#a4edba"
                               )
                             ))%>%
               hc_colorAxis(tickPixelInterval= 100,
                            minColor= '#E6E7E8',
                            maxColor=input$colormap)%>%
               hc_title(text ="Indice de Valoracón Predial")%>%
               hc_mapNavigation(enabled= T,
                                buttonOptions=list(verticalAlign= 'bottom')
               ) %>%
               hc_credits(enabled = TRUE,
                          text = "Fuente: Elaboración propia",
                          href = "") %>% 
               hc_exporting(
                 enabled = TRUE
               ))

   })



   ##Genera el mapa2
   output$mapa2<-renderHighchart({
     rv$mapa2

     isolate(highchart(type = "map") %>%
               hc_chart(backgroundColor = "#FFFFFF") %>%
               hc_add_series(mapData = nac, showInLegend = FALSE, nullColor = "#424242",
                             borderWidth = 0,data = rv$data_mapa, value = "value",
                             joinBy = c("state_code", "id.edo"), name = "IVP" ,
                             dataLabels = list(enabled = TRUE, format = '{point.properties.state_name}'),
                             borderColor = "#FAFAFA", borderWidth = 0.1,
                             tooltip = list(pointFormat='{point.properties.state_name}: {point.value}<br/>',
                                            valueDecimals = 2),
                             states=list(
                               hover=list(
                                 color= "#a4edba"
                               )
                             ))%>%
               hc_colorAxis(tickPixelInterval= 100,
                            minColor= '#E6E7E8',
                            maxColor=input$colormap)%>%
               hc_title(text ="Indice de Valoracón Predial")%>%
               hc_mapNavigation(enabled= T,
                                buttonOptions=list(verticalAlign= 'bottom')
               ) %>%
               hc_credits(enabled = TRUE,
                          text = "Fuente: Elaboración propia",
                          href = "") %>% 
               hc_exporting(
                 enabled = TRUE
               ))

   })



}

# Correr aplicación
shinyApp(ui = ui, server = server)
    
asked by Rolando Tamayo 04.10.2017 в 03:50
source

1 answer

1

Apparently it is a topic related to the use of tabPanel . I send you your corrected example.

library(shiny)
library(highcharter)
library(colourpicker)
#Crear uis para cambiar decuardo al tab
ui_mapa1<-tagList(div(
  highchartOutput("mapa1")
))

ui_mapa2<-tagList(div(
  highchartOutput("mapa2")
))


#ui
ui <- fluidPage(

  # Application title
  titlePanel("Problema con highchartr and removeUI"),

  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      colourInput("colormap",h3("Color"),value = "#2c3e50"),
      actionButton("mapa","Mapear",icon('globe'))
    ),

    # Main ppanel
    mainPanel(
      #En el tabsetpanel se comentaron los tabpanel con los ui fijos
      #y se incluyeron dos tabpanel para insertar ahi los tab donde ve el 
      #usuario.
      tabsetPanel(id="tabpanel",
                  # tabPanel("Mapa1",div(highchartOutput("mapa1"),id="Mapa1")),
                  # tabPanel("Mapa2",div(highchartOutput("mapa2"),id="Mapa2"))
                  tabPanel("Mapa1",highchartOutput("mapa1")),
                  tabPanel("Mapa2",highchartOutput("mapa2"))
      )
    )
  )
)

# server
server <- function(input, output,session) {

  #Se carga el ui en el tab2 al inicio
  if(inicio==1){
    insertUI(selector = "#Mapa2",
             ui=ui_mapa2)
    inicio<-2
  }


  #Se crean valores reactivos para guardar los tags, unos datos para el mapay
  #y dos valores para controlar la reactividad de los mapas
  rv<-reactiveValues(
    ulttag=NULL,
    acttag="Mapa2",
    data_mapa=data.frame(),
    mapa1=0,
    mapa2=0
  )


  #Cuando se cambie de tab corre este codigo
  observeEvent(input$tabpanel,{
    #Guarda en que tag estuvo anteriormente, y en cual esta actaulmente
    rv$ulttag<-rv$acttag; rv$acttag<-input$tabpanel

    #Encuentra el ui que debe insertar
    if(rv$acttag=="Mapa1"){
      uires<-ui_mapa1
    }else{
      uires<-ui_mapa2
    }

    #Remueve el ui del ultimo tag y inserta el ui del tag actual
    removeUI(selector = paste("#",rv$ulttag," > *",sep=""))
    insertUI(selector = paste("#",rv$acttag,sep=""),
             ui=uires)
  })


  #Cuando demos clic en el boton mapear carga los datos de cada tab
  #y cambia el valore reactivo
  observeEvent(input$mapa,{

    if(rv$acttag=="Mapa1"){
      data<-as.data.frame(cbind(c(0),c(4)))
      names(data)<-c("id.edo","value")
      rv$mapa1<-rv$mapa1+1
      rv$data_mapa<-data }else{#Mapa 2
        data<-as.data.frame(cbind(c(0),c(8)))
        names(data)<-c("id.edo","value")
        rv$data_mapa<-data
        rv$mapa2<-rv$mapa2+1
      }

  })



  ##Genara el mapa 1

  output$mapa1<-renderHighchart({
    rv$mapa1

    isolate(highchart(type = "map") %>%
              hc_chart(backgroundColor = "#FFFFFF") %>%
              hc_add_series(mapData = nac, showInLegend = FALSE, nullColor = "#424242",
                            borderWidth = 0,data = rv$data_mapa, value = "value",
                            joinBy = c("state_code", "id.edo"), name = "IVP" ,
                            dataLabels = list(enabled = TRUE, format = '{point.properties.state_name}'),
                            borderColor = "#FAFAFA", borderWidth = 0.1,
                            tooltip = list(pointFormat='{point.properties.state_name}: {point.value}<br/>',
                                           valueDecimals = 2),
                            states=list(
                              hover=list(
                                color= "#a4edba"
                              )
                            ))%>%
              hc_colorAxis(tickPixelInterval= 100,
                           minColor= '#E6E7E8',
                           maxColor=input$colormap)%>%
              hc_title(text ="Indice de Valoracón Predial")%>%
              hc_mapNavigation(enabled= T,
                               buttonOptions=list(verticalAlign= 'bottom')
              ) %>%
              hc_credits(enabled = TRUE,
                         text = "Fuente: Elaboración propia",
                         href = "") %>% 
              hc_exporting(
                enabled = TRUE
              ))

  })



  ##Genera el mapa2
  output$mapa2<-renderHighchart({
    rv$mapa2

    isolate(highchart(type = "map") %>%
              hc_chart(backgroundColor = "#FFFFFF") %>%
              hc_add_series(mapData = nac, showInLegend = FALSE, nullColor = "#424242",
                            borderWidth = 0,data = rv$data_mapa, value = "value",
                            joinBy = c("state_code", "id.edo"), name = "IVP" ,
                            dataLabels = list(enabled = TRUE, format = '{point.properties.state_name}'),
                            borderColor = "#FAFAFA", borderWidth = 0.1,
                            tooltip = list(pointFormat='{point.properties.state_name}: {point.value}<br/>',
                                           valueDecimals = 2),
                            states=list(
                              hover=list(
                                color= "#a4edba"
                              )
                            ))%>%
              hc_colorAxis(tickPixelInterval= 100,
                           minColor= '#E6E7E8',
                           maxColor=input$colormap)%>%
              hc_title(text ="Indice de Valoracón Predial")%>%
              hc_mapNavigation(enabled= T,
                               buttonOptions=list(verticalAlign= 'bottom')
              ) %>%
              hc_credits(enabled = TRUE,
                         text = "Fuente: Elaboración propia",
                         href = "") %>% 
              hc_exporting(
                enabled = TRUE
              ))

  })



}

# Correr aplicación
shinyApp(ui = ui, server = server)

You let me know if I made a mistake in solving this problem.

UPDATE

According to your requirements ...

#ui
ui <- fluidPage(

  # Application title
  titlePanel("Problema con highchartr and removeUI"),

  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      colourInput("colormap",h3("Color"),value = "#2c3e50"),
      actionButton("mapa","Mapear",icon('globe'))
    ),

    # Main ppanel
    mainPanel(
      #En el tabsetpanel se comentaron los tabpanel con los ui fijos
      #y se incluyeron dos tabpanel para insertar ahi los tab donde ve el 
      #usuario.
      tabsetPanel(id="tabpanel",
                  # tabPanel("Mapa1",div(highchartOutput("mapa1"),id="Mapa1")),
                  # tabPanel("Mapa2",div(highchartOutput("mapa2"),id="Mapa2"))
                  tabPanel("Mapa1",div(id="Mapa1")),
                  tabPanel("Mapa2",div(id="Mapa2")),
                  selected="Mapa2"
      )
    )
  )
)

# server
server <- function(input, output,session) {
  library(shiny)
  library(highcharter)
  library(colourpicker)

  nac<-list(type="FeatureCollection",
            features=list(list(type="Feature",
                               properties=list(state_code=list(0),state_name=list("Nacional")),
                               geometry=list(type="Polygon",
                                             coordinates=list(list(list(-95,26),
                                                                   list(-91,26),
                                                                   list(-91,22),
                                                                   list(-95,22),
                                                                   list(-95,26)))))))

  ui_mapa1<-reactive({tagList(div(

        renderHighchart({
        print(paste("1",rv$mapa1))

        highchart(type = "map") %>%
          hc_chart(backgroundColor = "#FFFFFF") %>%
          hc_add_series(mapData = nac, showInLegend = FALSE, nullColor = "#424242",
                        borderWidth = 0,data = rv$data_mapa, value = "value",
                        joinBy = c("state_code", "id.edo"), name = "IVP" ,
                        dataLabels = list(enabled = TRUE, format = '{point.properties.state_name}'),
                        borderColor = "#FAFAFA", borderWidth = 0.1,
                        tooltip = list(pointFormat='{point.properties.state_name}: {point.value}<br/>',
                                       valueDecimals = 2),
                        states=list(
                          hover=list(
                            color= "#a4edba"
                          )
                        ))%>%
          hc_colorAxis(tickPixelInterval= 100,
                       minColor= '#E6E7E8',
                       maxColor=isolate(input$colormap))%>%
          hc_title(text ="Indice de Valoracón Predial")%>%
          hc_mapNavigation(enabled= T,
                           buttonOptions=list(verticalAlign= 'bottom')
          ) %>%
          hc_credits(enabled = TRUE,
                     text = "Fuente: Elaboración propia",
                     href = "") %>% 
          hc_exporting(
            enabled = TRUE
          )

      })      

  ))})

  ui_mapa2<-reactive({tagList(div(

      ##Genera el mapa2
      renderHighchart({
        print(paste("2",rv$mapa2))

        highchart(type = "map") %>%
          hc_chart(backgroundColor = "#FFFFFF") %>%
          hc_add_series(mapData = nac, 
                        showInLegend = FALSE, 
                        nullColor = "#424242",
                        borderWidth = 0,
                        data = rv$data_mapa,
                        value = "value",
                        joinBy = c("state_code", "id.edo"), 
                        name = "IVP" ,
                        dataLabels = list(enabled = TRUE, format = '{point.properties.state_name}'),
                        borderColor = "#FAFAFA", 
                        borderWidth = 0.1,
                        tooltip = list(pointFormat='{point.properties.state_name}: {point.value}<br/>',
                                       valueDecimals = 2),
                        states=list(
                          hover=list(
                            color= "#a4edba"
                          )
                        ))%>%
          hc_colorAxis(tickPixelInterval= 100,
                       minColor= '#E6E7E8',
                       maxColor=isolate(input$colormap))%>%
          hc_title(text ="Indice de ValoracIón Predial")%>%
          hc_mapNavigation(enabled= T,
                           buttonOptions=list(verticalAlign= 'bottom')
          ) %>%
          hc_credits(enabled = TRUE,
                     text = "Fuente: Elaboración propia",
                     href = "") %>% 
          hc_exporting(
            enabled = TRUE
          )

      })

  ))})

  #Se crean valores reactivos para guardar los tags, unos datos para el mapay
  #y dos valores para controlar la reactividad de los mapas
  rv<-reactiveValues(
    ulttag=NULL,
    acttag="Mapa2",
    data_mapa=data.frame(),
    mapa1=0,
    mapa2=0
  )

  #Cuando se cambie de tab corre este codigo
  observeEvent(input$tabpanel,{
    #Guarda en que tag estuvo anteriormente, y en cual esta actaulmente
    rv$ulttag<-rv$acttag; rv$acttag<-input$tabpanel

    #Encuentra el ui que debe insertar
    if(rv$acttag=="Mapa1"){
      uires<-ui_mapa1()
      print(rv$acttag)
    }else{
      uires<-ui_mapa2()
      print(rv$acttag)
    }

    #Remueve el ui del ultimo tag y inserta el ui del tag actual
    if(!(rv$acttag==rv$ulttag)){
    removeUI(selector = paste("#",rv$ulttag," div",sep=""))}

    insertUI(selector = paste("#",rv$acttag,sep=""),ui=uires)
    print("nac")
  })

  #Cuando demos clic en el boton mapear carga los datos de cada tab
  #y cambia el valore reactivo
  observeEvent(input$mapa,{

    if(rv$acttag=="Mapa1"){
      data<-as.data.frame(cbind(c(0),c(4)))
      names(data)<-c("id.edo","value")
      rv$mapa1<-rv$mapa1+1
      rv$data_mapa<-data }else{#Mapa 2
        data<-as.data.frame(cbind(c(0),c(8)))
        names(data)<-c("id.edo","value")
        rv$data_mapa<-data
        rv$mapa2<-rv$mapa2+1
      }
  })

}

# Correr aplicación
shinyApp(ui = ui, server = server)
    
answered by 04.10.2017 / 15:56
source