Dynami c количество столбцов в Shiny - PullRequest
0 голосов
/ 01 мая 2020

Я пишу блестящее приложение с fluidRow s и хочу создать динамическое c количество столбцов в приложении. Я могу сделать так, чтобы столбцы отображались и исчезали правильно, но я не знаю, как их соответственно изменить. Желаемый результат состоит в том, что все столбцы имеют ширину 4, если их 3, и ширину 6, если их 2. Число возможных столбцов равно 2, 3 или 4, поэтому мне не нужно учитывать большую изменчивость, чем эта.

Я знаю, что, вероятно, смогу сделать это, пропустив весь набор столбцов через renderUI. Однако это потребовало бы от меня определения содержимого столбцов в server.R, и я бы предпочел этого избежать.

Ниже приведен пример минимального кода моего приложения:

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)

1 Ответ

1 голос
/ 01 мая 2020

Одним из способов может быть изменение классов css с использованием javascript. Я написал короткий js скрипт, который вычисляет ширину, используя выбранное значение (то есть, 2, 3, 4) и максимальные столбцы bootstrap. js (то есть, 12): 12 / value, а затем обновляет класс с новой шириной: col-sm-*. Я явно назвал, какие столбцы должны быть изменены, добавив класс target-column. (Вы можете использовать любое имя, которое вам нравится. Убедитесь, что оно обновлено в функции js.). Событие инициируется кнопкой отправки.

Вот ваш пример с javascript. (Я завернул приложение в 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) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...