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)