Reputation: 2319
I'm developing a R Shiny app that is composed of two fluidRow
s holding some content. One of them contains a Leaflet map spanning some columns. So far, so good. Now, the idea was to extend the map in the background to the other columns and also to the upper fluidRow
. In the end, the map could be seen across the whole website: without opacity in its column
s and semitransparently in the other column
s and the upper fluidRow
.
This is how the app looks so far:
And this is how I ideally want it to look:
And here is the code for the app:
library(leaflet)
library(shiny)
library(shinythemes)
ui <- navbarPage(
title = "The app",
tabPanel("Reproducible examples are great :)",
fluidPage(
fluidRow(
column(2,
selectInput("city", "Select city:",
c("Beirut", "Cairo", "Bagdad"),
selected = "Beirut"
),
actionButton("start", "Start",
style = "color: black;
background-color: #ffcc00;")
),
column(5,
"Content is here ...",
br(),
sliderInput("slider1", "",
min = 1,
max = 100,
value = 30,
ticks = TRUE)
),
column(5,
"... and there and ...",
br(),
sliderInput("slider2", "",
min = 1,
max = 100,
value = 30,
ticks = TRUE)
),
),
fluidRow(
column(7,
leafletOutput("map",
height = "67vh"
)
),
column(5,
"... also here ...",
br(),
sliderInput("slider3", "",
min = 1,
max = 500,
value = 30,
ticks = TRUE),
"... and even down there",
br(),
sliderInput("slider4", "",
min = 1,
max = 500,
value = 30,
ticks = TRUE)
)
)
)
),
theme = shinytheme("cosmo")
)
server <- function(input, output) {
output$map <- renderLeaflet({
leaflet(data = NULL,
options = leafletOptions(zoomControl = FALSE,
dragging = TRUE)) |>
addTiles(
options = providerTileOptions(noWrap = TRUE)) |>
setView(lng = 35.5051, lat = 33.889, zoom = 14) |>
addScaleBar(position = "bottomleft")
})
}
shinyApp(ui, server)
I tried to look for a solution online, but failed badly without even finding a real inspiration. So, I am even more curious if any of you knows a solution or hint!
Upvotes: 0
Views: 562
Reputation: 7350
tada :)
library(leaflet)
library(shiny)
library(shinythemes)
ui <- navbarPage(
title = "The app",
tabPanel("Reproducible examples are great :)",
div(
absolutePanel(
top = "50px", left = 0, right = 0, height = "125px",
style = "opacity: 0.6; background-color: white; z-index: 1",
column(2,
selectInput("city", "Select city:",
c("Beirut", "Cairo", "Bagdad"),
selected = "Beirut"
),
actionButton("start", "Start",
style = "color: black;
background-color: #ffcc00;")
),
column(5,
"Content is here ...",
br(),
sliderInput("slider1", "",
min = 1,
max = 100,
value = 30,
ticks = TRUE)
),
column(5,
"... and there and ...",
br(),
sliderInput("slider2", "",
min = 1,
max = 100,
value = 30,
ticks = TRUE)
)
),
absolutePanel(
top = "50px", left = 0, right = 0, bottom = 0,
fixed = TRUE, cursor = "default",
style = "z-index: 0",
leafletOutput("map", height = "calc(100vh - 50px)")
),
absolutePanel(
right = 0, top = "175px", width = "40vw",
"... also here ...",
style = "opacity: 0.6; background-color: white; height: calc(100vh - 175px);",
br(),
sliderInput("slider3", "",
min = 1,
max = 500,
value = 30,
ticks = TRUE),
"... and even down there",
br(),
sliderInput("slider4", "",
min = 1,
max = 500,
value = 30,
ticks = TRUE)
)
)
),
theme = shinytheme("cosmo")
)
server <- function(input, output) {
output$map <- renderLeaflet({
leaflet(data = NULL,
options = leafletOptions(zoomControl = FALSE,
dragging = TRUE)) |>
addTiles(
options = providerTileOptions(noWrap = TRUE)) |>
setView(lng = 35.5051, lat = 33.889, zoom = 14) |>
addScaleBar(position = "bottomleft")
})
}
shinyApp(ui, server)
To be responsive on smaller screens:
library(leaflet)
library(shiny)
library(shinythemes)
ui <- navbarPage(
title = "The app",
tabPanel("Reproducible examples are great :)",
div(
style = "margin-top: -70px;",
tags$style(
'
.top-panel {
position: relative;
width: 50%;
display: inline-block;
margin-top: 52px;
}
.right-panel {
position: relative;
width: 50%;
display: inline-block;
margin-top: 52px;
margin-left: -3px;
vertical-align: top;
}
.panels {
opacity: 0.6;
background-color: white;
z-index: 1;
}
.panel-map {
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
@media (min-width: 750px) {
.top-panel {
position: absolute;
top: 0px;
left: 0;
right: 0;
height: 125px;
width: 100%
}
.right-panel {
position: absolute;
top: 125px;
right: 0;
width: 40vw;
height: calc(100vh - 175px);
z-index: 1
}
}
'
),
div(
class = "top-panel panels",
column(2,
selectInput("city", "Select city:",
c("Beirut", "Cairo", "Bagdad"),
selected = "Beirut"
),
actionButton("start", "Start",
style = "color: black;
background-color: #ffcc00;")
),
column(5,
"Content is here ...",
br(),
sliderInput("slider1", "",
min = 1,
max = 100,
value = 30,
ticks = TRUE)
),
column(5,
"... and there and ...",
br(),
sliderInput("slider2", "",
min = 1,
max = 100,
value = 30,
ticks = TRUE)
)
),
div(
class = "panel-map",
top = "50px", left = 0, right = 0, bottom = 0,
fixed = TRUE, cursor = "default",
style = "z-index: 0",
leafletOutput("map", height = "calc(100vh - 50px)")
),
div(
"... also here ...",
class = "right-panel panels",
br(),
sliderInput("slider3", "",
min = 1,
max = 500,
value = 30,
ticks = TRUE),
"... and even down there",
br(),
sliderInput("slider4", "",
min = 1,
max = 500,
value = 30,
ticks = TRUE)
)
)
),
theme = shinytheme("cosmo")
)
server <- function(input, output) {
output$map <- renderLeaflet({
leaflet(data = NULL,
options = leafletOptions(zoomControl = FALSE,
dragging = TRUE)) |>
addTiles(
options = providerTileOptions(noWrap = TRUE)) |>
setView(lng = 35.5051, lat = 33.889, zoom = 14) |>
addScaleBar(position = "bottomleft")
})
}
shinyApp(ui, server)
Too many details, you need to learn some CSS. I'm not gonna explain all of them. The key here is the @media
query, which makes it use a different set of CSS inside once the screen size is reached/below certain values.
When it is on small screen:
Upvotes: 3