Rshiny 布局框

jl1*_*121 5 r shiny

无法为我遇到的这个特定问题找到正确的词语。

我希望盒子围绕汽车的图像,但考虑到图像的高度,这意味着它将下一个流体行移得更低。有没有办法让盒子看起来像我画红色盒子的地方?但更重要的是第 3 行汽车图像旁边的框(我不希望有人对第四个流体行进行编码!)。

我尝试合并垂直布局,但它只是使所有内容都垂直。

布局

代码:并使用任何图像替换下面

library(shinydashboard)
library(shiny)
library(shinyjs)

ui <- dashboardPage(
  dashboardHeader(disable = TRUE),
  dashboardSidebar(disable = TRUE),
  dashboardBody(
    useShinyjs(),
    dashboardBody(
      # the first row
      fluidRow(
        box( id = "box1",
             h4(strong(textOutput("box1"))),
             p(textOutput("box1_sub")),
             width = 2,
             solidHeader = TRUE
        ),
        box( id = "box2",
             h4(strong(textOutput("box2"))),
             p(textOutput("box2_sub")),
             width = 2,
             solidHeader = TRUE,
             background = "blue"
        ),
        box( id = "box3",
             h4(strong(textOutput("box3"))),
             p(textOutput("box3_sub")),
             width = 2,
             solidHeader = TRUE
        ),
        box( id = "box4",
             h4(strong(textOutput("box4"))),
             p(textOutput("box4_sub")),
             width = 2,
             solidHeader = TRUE,
             background = "yellow"
        ),
        box( id = "box5",
             h4(strong(textOutput("box5"))),
             p(textOutput("box5_sub")),
             width = 2,
             solidHeader = TRUE,
             background = "purple"
        ),
        box( id = "box6",
             h4(strong(textOutput("box6"))),
             p(textOutput("box6_sub")),
             width = 2,
             solidHeader = TRUE
        )
        
      ),
      br(),
      # second row with car image
      fluidRow(
        box( id = "box7",
             h4(strong(textOutput("box7"))),
             p(textOutput("box7_sub")),
             width = 2,
             solidHeader = TRUE,
             background = "green"
        ),
        box( id = "box8",
             h4(strong(textOutput("box8"))),
             p(textOutput("box8_sub")),
             width = 2,
             solidHeader = TRUE,
             background = "green"
        ),
        box( uiOutput("car_image"),
             width = 4
        ),
        box( id = "box13",
             h4(strong(textOutput("box13"))),
             p(textOutput("box13_sub")),
             width = 2,
             solidHeader = TRUE,
             background = "green"
        ),
        box( id = "box14",
             h4(strong(textOutput("box14"))),
             p(textOutput("box14_sub")),
             width = 2,
             solidHeader = TRUE,
             background = "green"
        )
      ),
      br(),
      # third row
      fluidRow(
        box( id = "box10",
             h4(strong(textOutput("box10"))),
             p(textOutput("box10_sub")),
             width = 2,
             solidHeader = TRUE
        )
      ),
      br(),
      # fourth row
      fluidRow(
        box( id = "box11",
             h4(strong(textOutput("box11"))),
             p(textOutput("box11_sub")),
             width = 2,
             solidHeader = TRUE
        ),
        box( id = "box12",
             h4(strong(textOutput("box12"))),
             p(textOutput("box12_sub")),
             width = 2,
             solidHeader = TRUE
        )))))

server <- function(input, output) {
  
    output$car_image <- renderUI({
        img(src='/image.png', width = '100%')})

    
    output$box1 <- renderText({"box1"})
    
    output$box1_sub<- renderText({"box1_sub"})
    
    output$box2 <- renderText({"box2"})
    
    output$box2_sub <- renderText({"box2_sub"})
    
    output$box3 <- renderText({"box3"})
    
    output$box3_sub <-renderText({"box3_sub"})
    
    output$box4<- renderText({"box4"})
    
    output$box4_sub <- renderText({"box4_sub"})
    
    output$box5 <- renderText({"box5"})
    
    output$box5_sub <- renderText({"box5_sub"})

    output$box6 <- renderText({"box6_sub"})
    
    output$box6_sub <- renderText({"box6_sub"})
    
    output$box7<- renderText({"box7"})

    output$box7_sub <- renderText({"box7_sub"})

    output$box8 <- renderText({"box8"})

    output$box8_sub <- renderText({"box8_sub"})

    output$box9<- renderText({"box9"})

    output$box9_sub <- renderText({"box9_sub"})

    output$box10<- renderText({"box10"})

    output$box10_sub <- renderText({"box10_sub"})

    output$box11<- renderText({"box11"})

    output$box11_sub <- renderText({"box11_sub"})

    output$box12<- renderText({"box12"})

    output$box12_sub <- renderText({"box12_sub"})

    output$box13<- renderText({"box13"})

    output$box13_sub <- renderText({"box13_sub"})

    output$box14<- renderText({"box14"})

    output$box14_sub <- renderText({"box14_sub"})
}

shinyApp(ui = ui, server = server)

Run Code Online (Sandbox Code Playgroud)

Joh*_*osa 3

鉴于您的代码,我也会尽力帮助您解决应用程序的其他方面。

设置

建议1:使用函数式编程

Hadley Wickham 在他的《掌握闪亮》一书中的第 18 章介绍了使用函数来减少应用程序中的代码重复的想法。考虑到这一点,让我们构建一个函数,以 id 作为参数,返回一个盒子。

通过此功能,您可以控制盒子的任何元素。并且,通过参数,imagenbox您可以判断盒子是否包含汽车图像。

create_box <- \(
  id, imagenbox = FALSE,  width = 12, 
  background = 'green',solid_header = TRUE
  ){
  
  boxId <- paste0('box', id)
  subtilteId <- paste0('box', id, "_sub")
  
  if(imagenbox) {
    return(
      box(
        id = boxId, class = 'imagen_box',
        uiOutput('car_image'),
        width = width
        )
    )
  }
  
  box(id = boxId,
      h4(strong(textOutput(boxId))),
      p(textOutput(subtilteId)),
      width = width,
      solidHeader = solid_header
      )
}
Run Code Online (Sandbox Code Playgroud)

现在您已经有了这个函数,让我们准备参数列表以循环该函数并在您的应用程序 UI 中生成框。

通过这两个向量,我们将创建 13 个盒子,其中 6 号盒子将是带有汽车图像的盒子。

boxes <- 1:13
car_imagen_index <- c(rep(FALSE, 5), TRUE, rep(FALSE, 7))
Run Code Online (Sandbox Code Playgroud)

应用程序用户界面

对于像这样复杂的应用程序,您必须跳出框框思考,并且不仅使用闪亮的代码来排列和设计视觉元素的样式。我将添加一个 css 文件来包含/制作您需要的网格布局。

css文件内容是这样的

/* Display grid for the box container with 4 columns   */
body > div.wrapper > div > section > div > section {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

/* Element 6 (the one with the image, remember)  to span across
   two rows and columns
*/
body > div > div > section > div > section > div:nth-child(6) {
  grid-row: span 2;
  grid-column: span 2;
}
Run Code Online (Sandbox Code Playgroud)

注意:.css文件只是具有该扩展名的文本文件。这篇文章很好的介绍

ui <-  dashboardPage(
  dashboardHeader(disable = TRUE),
  dashboardSidebar(disable = TRUE),
  dashboardBody(
  # Here I include the css file
    includeCSS('grid-style.css'),
    useShinyjs(),
    dashboardBody(
      # Function programming to generate the boxes
      map2(boxes, car_imagen_index, ~create_box(.x, .y))
    )
    )
  )
Run Code Online (Sandbox Code Playgroud)

在您的服务器中,您也可以使用函数式编程。例如,框的标题和副标题将通过迭代过程生成。

server <- function(input, output) {
  # render the car image
  output$car_image <- renderUI({
    img(src='https://www.elcarrocolombiano.com/wp-content/uploads/2021/04/20210420-WORLD-CAR-OF-THE-YEAR-VOLKSWAGEN-ID-4-01.jpg', width = '100%')})
  
  # render the boxes title and subtitle
  lapply(boxes, \(id) {
    boxId = paste0('box', id)
    subtitleId = paste0('box', id, '_sub')
    
    output[[boxId]] <- renderText(boxId)
    output[[subtitleId]] <- renderText(subtitleId)
  })
}

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述