简体   繁体   English

Shiny 中的动态列数

[英]Dynamic number of columns in Shiny

I'm writing a Shiny app with fluidRow s and I want to create a dynamic number of columns in the app.我正在编写一个带有fluidRow的 Shiny 应用程序,我想在应用程序中创建动态数量的列。 I can make columns appear and disappear correctly, but I don't know how to also make them resize accordingly.我可以使列正确显示和消失,但我不知道如何使它们相应地调整大小。 The desired outcome is that all columns have width 4 if there are 3 of them and width 6 if there are 2. The number of possible columns is 2, 3, or 4 so I don't need to account for more variability than that.期望的结果是,如果有 3 个列,则所有列的宽度为 4,如果有 2 个,则宽度为 6。可能的列数为 2、3 或 4,因此我不需要考虑更多的可变性。

I know that I can probably do it by passing the entire column set through renderUI .我知道我可以通过renderUI传递整个列集来做到这一点。 However, that would require me to define the contents of the columns in server.R and I'd rather avoid that.但是,这需要我在 server.R 中定义列的内容,我宁愿避免这种情况。

See below for a minimal code example of my app:请参阅下面的我的应用程序的最小代码示例:

library(shiny)
ui <- fluidPage(
    titlePanel("Dynamic Columns"),
    sidebarLayout(
        sidebarPanel(
            selectInput("column_count", "Number of Columns", 2:4, 2),
            submitButton("Go")
        ),
        mainPanel(
           fluidRow(
               column(3, "This is column 1"),
               column(3, "This is column 2"),
               conditionalPanel(
                   condition = "input.column_count >= 3",
                   column(3, "This is column 3")
               ),
               conditionalPanel(
                   condition = "input.column_count == 4",
                   column(3, "This is column 4")
               )
           )
        )
    )
)

server <- function(input, output) {}

shinyApp(ui = ui, server = server)

One way might be to alter the css classes using javascript.一种方法可能是使用 javascript 更改 css 类。 I wrote a short js script that calculates the width using the selected value (ie, 2, 3, 4) and the maximum bootstrap.js columns (ie, 12): 12 / value , and then updates the class with the new width: col-sm-* .我编写了一个简短的 js 脚本,它使用所选值(即 2、3、4)和最大 bootstrap.js 列(即 12)计算宽度: 12 / value ,然后使用新宽度更新 class : col-sm-* I explicitly named which columns should be resized by adding the class target-column .我通过添加 class target-column明确命名了应该调整哪些列的大小。 (You can use any name you like. Make sure it is updated in the js function.). (您可以使用任何您喜欢的名称。确保它在 js function 中更新。)。 The event is trigged by the submit button.该事件由提交按钮触发。

Here's your example with the javascript.这是您使用 javascript 的示例。 (I wrapped the app in tagList ). (我将应用程序包装在tagList中)。

library(shiny)
ui <- tagList(
    fluidPage(
    titlePanel("Dynamic Columns"),
    sidebarLayout(
        sidebarPanel(
            selectInput("column_count", "Number of Columns", 2:4, 2),
            submitButton("Go")
        ),
        mainPanel(
           fluidRow(
               column(3, "This is column 1", class = "target-column"),
               column(3, "This is column 2", class = "target-column"),
               conditionalPanel(
                   condition = "input.column_count >= 3",
                   column(3, class = "target-column", "This is column 3")
               ),
               conditionalPanel(
                   condition = "input.column_count == 4",
                   column(3, class = "target-column", "This is column 4")
               )
           )
        )
    ),
    tags$script(
        type = "text/javascript",
            "
            const btn = document.querySelector('button[type=submit]');
            const input = document.getElementById('column_count');
            btn.addEventListener('click', function(event) {
                // calculate new width
                w = 12 / input.options[input.selectedIndex].value;
                console.log('new width', w);

                // update classes
                const columns = document.querySelectorAll('.target-column');
                columns.forEach(function(column) {
                    column.className = 'col-sm-' + w + ' target-column';
                });
            })
            "
        )
    )
)

server <- function(input, output) {}

shinyApp(ui = ui, server = server) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM