When creating a Shiny dashboard I thought that if the heights of the boxes were equal their tops and bottoms would align. This is not the case. Here the tops are nicely aligned while the bottoms are not:
How do I ensure that the tops and bottoms are aligned?
NOTE: The same misalignment of the bottoms occurs even if the two boxes are filled with the exact same ggplot.
These instructions imply it's quite easy.
It’s possible to force the boxes to all be the same height, by setting height. In contrast to width, which is set using the 12-wide Bootstrap gride, height is specified in pixels.
Sample Code
## app.R ##
library(shiny)
library(shinydashboard)
library(ggplot2)
ui <- dashboardPage(
dashboardHeader(title = "Box alignmnent test"),
dashboardSidebar(),
dashboardBody(
# Put boxes in a row
fluidRow(
box(tableOutput("pop_num"), height = 350),
box(plotOutput("speed_distbn", height = 350))
)
)
)
server <- function(input, output) {
# Population numbers
output$pop_num <- renderTable({
df <- tibble(
x = c(1,2,3,4),
y = c(5, 6, 7, 8)
)
})
# Population distribution graph
output$speed_distbn <- renderPlot({
ggplot(data = cars, aes(x = speed, y = dist)) +
geom_point()
})
}
shinyApp(ui, server)
Note that when you set the heights, the first 350
applies to the box
function while the second 350
is passed as an argument to the plotOutput
function.
Just make sure both box
functions are passed the same height argument; also note that if the plot (including possibly some extra padding/margin) has a total height larger than the enclosing box's height, it will spill out the bottom. So to be safe, pass a height
argument to both the plotOutput
and box
functions:
box_height = "20em"
plot_height = "16em"
ui <- dashboardPage(
dashboardHeader(title = "Box alignmnent test"),
dashboardSidebar(),
dashboardBody(
# Put boxes in a row
fluidRow(
box(tableOutput("pop_num"), height = box_height),
box(plotOutput("speed_distbn",height = plot_height), height = box_height)
)
)
)
Notice that the plot's height is smaller. There's likely a more clever way to automatically do this (and certainly if you do some custom CSS there is!), but for illustration purposes this works.