Ошибка с highchartr, insertUI и removeUI в Shiny R. Ошибка в shinyapp.js
Привет всем, я работаю с блестящим приложением с navbarPage
несколько tabsetPanel
, Я пытаюсь заставить приложение загружать только пользовательский интерфейс, в котором находится пользователь. Это чтобы избежать генерации длинного кода. Для этого я генерирую ui
из отдельных файлов R для каждого tabsetPanel
загрузите их в приложение по мере необходимости с помощью функции source("ui_temp_idpanel.R")
, Я удалил пользовательский интерфейс из предыдущей вкладки, в которой пользователь использовал removeUI
функции и вставьте новый пользовательский интерфейс во вкладку, где пользователь в настоящее время с insertUI
функция. Проблема была при использовании highchater
библиотека, чтобы включить карту (важно отметить, что когда графика генерируется с библиотекой, эта проблема не возникает.). Когда есть только одна карта, проблем не возникает, однако, когда их несколько (в другой tabPanel), проблема возникает. Я также заметил, что проблема возникает из-за использования removeUI
а также insertUI
функции, так как я попробовал случай, когда пользовательский интерфейс карт фиксирован, и проблема не задается. Одна из вещей, которые я пытался удалить, была ouput$id_map
из предыдущей вкладки, когда пользователь меняет вкладку, я думаю, что я могу сделать это с ouput$id_map <-renderHighChart ({})
, но я не решаю проблему.
Когда я проверяю приложение в браузере, это код ошибки, который выдает меня:
GET http://127.0.0.1:5642/undefined 404 (Not Found)
VM114:69 Uncaught TypeError: Cannot read property 'map' of null
Вы можете подумать, что при отправке карты на hchart ()
функция. Странно то, что сначала приложение работает без проблем, до тех пор, пока не будет сгенерирована карта в tab1
карта генерируется в tab2
а затем вы вернетесь к tab1
когда ошибка проходит. После ошибки приложение перестает генерировать карты и зависит от места, где вы запускаете removeUI
а также insertUI
что приложение может представлять другие ошибки. Если вы настаиваете на смене вкладок после ошибки, появляются новые ошибки:
shinyapp.js:360 Uncaught Duplicate binding for ID mapa2
shinyapp.js:360 Uncaught Duplicate binding for ID mapa1
Это все, что я знаю о проблеме. Я воссоздал ошибку в более простом приложении, которое я оставляю следующим:
Пример приложения, которое представляет ошибку.
library(shiny)
library(highcharter)
library(colourpicker)
#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
#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)