是否可以在砖石网格中排列闪亮的应用程序卡?

DMN*_*MNO 5 layout r shiny masonry

我目前正在尝试从一个数据框为一个爱好 Shiny 应用程序创建一个“墙”的卡片。改编自这个SO answer,这是我的代码的最小完整示例:

library(shiny)

df <- read.csv("https://github.com/intelligence-refinery/shiny_app/raw/master/flyer.csv")

card <- function(img, item, store) {
    HTML(
        paste0(
            '<div class="card">
              <div class="container">
              <h4><b>', item, '</b></h4>
              </div>
              <img src="', img, '" style="width:100%">
              <div class="container">
              <h5><i>', store, '</i></h5>
              </div>
              </div>'
        )
    )
}


ui <- fluidPage(
    tags$head(tags$style('.card {
                         width: 250px;
                       clear: both;
                       /* Add shadows to create the "card" effect */
                       box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
                       transition: 0.3s;
                       }
                       /* On mouse-over, add a deeper shadow */
                       .card:hover {
                       box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
                       }
                       /* Add some padding inside the card container */
                       .container {
                       width: 250px;
                       padding: 2px 16px;
                       }')),
    uiOutput("cards")
)

server <- function(input, output, session) {
    output$cards <- renderUI({
        # First make the cards
        args <-
            lapply(1:dim(df)[1], function(x)
                card(df[x, "clean_image_url"],
                     store = df[x, "store_name"],
                     item = df[x, "name"]))

        # Make sure to add other arguments to the list:
        args$cellArgs <- list(style = "
            width: 300px;
            height: auto;
            margin: 5px;
            ")

        # basically the same as flowLayout(cards[[1]], cards[[2]],...)
        do.call(shiny::flowLayout, args)

    })
}


# Preview the UI in the console
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)


但是,这会导致卡片之间出现难看的间隙,因为它们的大小不同:

卡片之间的空隙

一个砖石网格布局将是在这种情况下的理想:

砌体网格示例

由于我对任何类型的网络工作都很陌生,我不确定如何将纯 CSS/Javascript 解决方案应用于我的 Shiny 应用程序。我试图改编Bootstrap 文档中的示例,但是当我将 HTML 和 CSS 粘贴到 CodePen 时,我没有得到一个完整的示例......

我发现最接近在 Shiny 应用程序中创建砖石网格的示例是(相当复杂的)会议 Twitter 仪表板。我在代码中找到了相关部分。但是,由于我对任何网络工作都很陌生,因此我无法将其调整为我自己的代码。

有没有办法为以这种方式生成的卡片面板创建砖石布局?任何帮助将不胜感激!:)

teo*_*fil 5

如果您可以将图像分成一些有意义的列,那么在布置水平布局之前,您可以将多组图像包装在column. 然后用 排列列fluidRow

这是一个仅使用数据的前 20 行的示例。粘贴server唯一。另一个变化是df <- df[1:20,]在加载数据后添加:

 server <- function(input, output, session) {
    output$cards <- renderUI({
        # First make the cards
        args <-
            lapply(1:dim(df)[1], function(x)
                card(df[x, "clean_image_url"],
                     store = df[x, "store_name"],
                     item = df[x, "name"]))

        # Make sure to add other arguments to the list:
        args$cellArgs <- list(style = "
            width: 300px;
            height: auto;
            margin: 5px;
            ")

        # make five columns with four images each
        cols <-
          lapply(seq(4, dim(df)[1], 4), function(x) {
              column(width = 2, verticalLayout(args[(x - 3):x], fluid = TRUE))
          })


        # then use fluidRow to arrange the columns 
        do.call(shiny::fluidRow, cols)

    })
}

Run Code Online (Sandbox Code Playgroud)

你应该得到这样的东西:

在此处输入图片说明