Is there a way (in pure Shiny) to check if an element is visible on screen (display : block), in the same way JScript does with "is.visible" ?
Here is a reproductible example of my problem :
library(shiny)
library(leaflet)
library(leaflet.extras)
library(tidyverse)
library(sf)
library(shinyjs)
#Create T0New data
lat <- c(49.823, 49.823, 58.478, 57.478, 45.823)
lng <- c(-10.854,-14.854,-10.854,2.02,2.02)
date <- c(123,125,135,168,149)
cat <-c("A","A","A","B","B")
type <- c("x","x","y","z","w")
col <- c("red","red","purple","green","turquoise")
T0New <- data.frame(lat,lng,date,cat,type,col)
ui <- fluidPage(
useShinyjs(),
tags$style("
p{
display:contents
}
.show{
display: block
}
.hide{
display: none !important
}
"),
column(width = 3,
HTML('
<div class="attr-col shiny-input-radiogroup" id="conf">
<input type="radio" id="A" name="conf" value="A" checked= "checked"/>
<label for="A">A</label>
<svg height="10" width="10">
<polygon points="0 0, 10 0, 10 10, 0 10" id="AToggle" />
</svg>
<br/>
<div id = "ALegend" class style = " display: none;" >
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="red" /></svg>
<p>x </p>
</br>
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="purple" /></svg>
<p> y </p>
</div>
<div id = "ALegendBoxes" class style = " display: none;" >
<input type="checkbox" id="x" name="x" checked>
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="red" /></svg>
<label for="x">x</label>
</br>
<input type="checkbox" id="y" name="y" checked>
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="purple" /></svg>
<label for="Séculier">y</label>
</div>
<input type="radio" id="B" name="conf" value="B" />
<label for="B">B</label>
<svg height="10" width="10">
<polygon points="0 0, 10 0, 10 10, 0 10" id="BToggle" />
</svg>
<br/>
<div id = "BLegend" class style = " display: none;" >
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="green" /></svg>
<p> z </p>
</br>
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="turquoise" /></svg>
<p> w </p>
</div>
<div id = "BLegendBoxes" class style = " display: none;" >
<input type="checkbox" id="z" name="z"checked>
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="green" /></svg>
<label for="z">z</label>
</br>
<input type="checkbox" id="w" name="w"checked>
<svg height="10" width="10"><circle cx="5" cy="5" r="5" fill="turquoise" /></svg>
<label for="w">w</label>
</div>
</div>
')
),
column(width = 9,
leafletOutput("map", height = "45vh"),
plotOutput("distribPlot", height = "40vh",
brush = brushOpts(id = "distribPlot_brush", direction = "x", resetOnNew = FALSE))
)
# )
)
server <- function(input, output, session) {
filteredData <- reactive({
if (input$x == TRUE) xV <- "x" else xV <- ""
if (input$y == TRUE) yV <- "y" else yV <- ""
if (input$z == TRUE) zV <- "z" else zV <- ""
if (input$w == TRUE) wV <- "w" else wV <- ""
currentlyFiltered <- filter(T0New, type %in% c(xV,yV,zV,wV))
currentlyFiltered <- filter(currentlyFiltered, cat %in% input$conf)
if(!is.null(input$distribPlot_brush)){
thisSel <- input$distribPlot_brush
currentlyFiltered <- currentlyFiltered %>%
filter(date >= thisSel$xmin, date <= thisSel$xmax)
}
return(currentlyFiltered)
})
#Sortie map
output$map <- renderLeaflet({
leaflet()%>%
addProviderTiles(providers$OpenTopoMap)
})
observe({
mapData <- filteredData()
mapProxy <- leafletProxy("map", session = session, data = mapData)
mapProxy %>%
clearGroup('1') %>%
addCircleMarkers(
data = mapData,
lat = mapData$lat,
lng = mapData$lng,
radius = 4,
color = 'white',
opacity = 1,
fillColor = ~col,
stroke = T,
weight = 1,
fillOpacity = 1,
group='1'
)
})
#Sortie graph
output$distribPlot <- renderPlot({
distribPlot <- ggplot(T0New,aes(date)) +
geom_density(col = "#053144", fill = "#43a2ca", alpha = 0.3, adjust = 0.75)
return(distribPlot)
})
onclick(id = "AToggle", c(toggleClass(id = "ALegend", class = "show")), add = FALSE)
observe({
toggleClass(id = "ALegend", class = "hide",
condition = input$conf=="A")
toggleClass(id = "ALegendBoxes", class = "show",
condition = input$conf=="A")
})
onclick(id = "BToggle", c(toggleClass(id = "BLegend", class = "show")), add = FALSE)
observe({
toggleClass(id = "BLegend", class = "hide",
condition = input$conf=="B")
toggleClass(id = "BLegendBoxes", class = "show",
condition = input$conf=="B")
})
}
# Create Shiny app ----
shinyApp(ui = ui, server = server)
For now, interraction-based, this code does exactly what I want to do : By clicking on the square next to the radio button, if it's checkboxes are not visible yet, you can set visible it's legend without the checkboxes. If it's legend with checkboxes is already visible it won't set the legend without checkboxes visible.
But i want to enhance this functionnality by replacing the square with arrows, pointing the radiobutton if none of it's legend is visible and pointing down if any legend is visible.
For now i'm playing with "on click" (line 169 & 178), radiobutton selection (line 171 to 176 & 180 to 185) and the "!important" class "hide" (line 30) but to do what I want to do these condition aren't enough, so I was wandering if there where any "is.visible" condition in Shiny to play with