
在开发交互式shiny应用时,我们经常需要展示用户可以拖拽排序的列表。sortable包提供了一个强大的解决方案,通过rank_list函数创建这样的拖拽列表。然而,当列表中的项目数量过多时,列表容器可能会变得非常长,超出屏幕范围,导致用户体验下降。为了解决这个问题,我们需要为列表容器设置一个固定的最大高度,并在内容超出该高度时自动显示滚动条,使用户能够方便地浏览和操作所有列表项。
实现rank_list的滚动功能,主要依赖于CSS的两个关键属性:
通过将这两个属性应用于rank_list所生成的HTML元素,即可实现列表的滚动功能。
我们将基于一个典型的Shiny sortable应用示例,演示如何为rank_list_1(即“Drag from here”列表)添加滚动功能。
sortable包中的rank_list函数在HTML中会生成一个div元素,其id属性与input_id参数的值一致。例如,对于input_id = "rank_list_1",生成的div将具有id="rank_list_1"。因此,我们可以直接通过CSS ID选择器#rank_list_1来定位并样式化这个特定的列表容器。
在Shiny应用的UI部分,使用tags$head和tags$style来嵌入自定义CSS样式。我们将为#rank_list_1设置max-height和overflow-y: auto。
以下是修改后的Shiny应用代码,其中包含了实现rank_list_1可滚动功能的CSS样式。
library(shiny)
library(sortable)
ui <- fluidPage(
tags$head(
tags$style(HTML("
/* 整体桶列表容器的最小高度 */
.bucket-list-container {
min-height: 350px;
}
/* 为 rank_list_1 添加滚动条样式 */
#rank_list_1 {
max-height: 300px; /* 设置最大高度,可根据需要调整 */
overflow-y: auto; /* 垂直方向内容溢出时显示滚动条 */
border: 1px solid #e0e0e0; /* 可选:为列表添加边框以便更好地区分 */
padding: 5px; /* 可选:内部填充 */
background-color: #f8f8f8; /* 可选:背景色 */
/* 确保在flex布局中,该元素的高度能被正确限制 */
flex-basis: 200px; /* 维持原有flex布局中的宽度基准 */
flex-grow: 1; /* 允许其增长 */
flex-shrink: 1; /* 允许其收缩 */
}
/* 调整其他 rank_list 的样式,使其与滚动列表对齐 */
#rank_list_2, #rank_list_3 {
border: 1px solid #e0e0e0; /* 添加边框 */
padding: 5px;
background-color: #f8f8f8;
min-height: 100px; /* 确保有最小高度 */
flex-basis: 200px; /* 维持原有flex布局中的宽度基准 */
flex-grow: 1;
flex-shrink: 1;
}
/* 确保横向桶列表的子元素(即各个rank_list)能够填充高度 */
.bucket-list.bucket-list-horizontal > * {
align-self: stretch; /* 让子元素拉伸以填充父容器的高度 */
}
"))
),
fluidRow(
column(
width = 12,
# 选择变量列表
radioButtons(inputId="variableList",
label="选择您的变量列表",
choices = c("names(mtcars)"="names(mtcars)","state.name"="state.name")),
# 输入文本以筛选变量名
textInput(
inputId = "subsetChooseListText",
label = "输入文本以筛选列表",
value = "c"
),
div(
class = "bucket-list-container default-sortable",
"将项目拖拽到任意桶中",
div(
class = "default-sortable bucket-list bucket-list-horizontal",
# uiOutput将生成可拖拽的源列表 (rank_list_1)
uiOutput("selection_list"), # 移除 inline style,通过CSS文件控制
rank_list(
text = "到这里",
labels = list(),
input_id = "rank_list_2",
options = sortable_options(group = "mygroup")
),
rank_list(
text = "以及这里",
labels = list(),
input_id = "rank_list_3",
options = sortable_options(group = "mygroup")
)
)
)
)
),
fluidRow(
column(
width = 12,
tags$b("结果"),
column(
width = 12,
tags$p("input$rank_list_1"),
verbatimTextOutput("results_1"),
tags$p("input$rank_list_2"),
verbatimTextOutput("results_2"),
tags$p("input$rank_list_3"),
verbatimTextOutput("results_3")
)
)
)
)
server <- function(input,output) {
# 初始化响应式变量
varList <- reactive({
req(input$variableList)
if (input$variableList == "state.name") {
state.name
} else {
# 生成一个长列表以演示滚动条
paste0(rep(names(mtcars), 20),"_", 1:220)
}
})
subsetChooseList <- reactive({
items <- varList()
pattern <- input$subsetChooseListText
if (nchar(pattern) < 1) {
return(items)
}
items[
grepl(
x = items,
pattern = input$subsetChooseListText,
ignore.case = TRUE
)
]
})
output$selection_list <- renderUI({
labels <- subsetChooseList()
# 移除已被选择的项目
labels <- labels[!(
labels %in% input$rank_list_2 |
labels %in% input$rank_list_3
)]
# 生成可拖拽的源列表
rank_list(
text = "从这里拖拽",
labels = labels,
input_id = "rank_list_1",
options = sortable_options(group = "mygroup")
)
})
# 调试用的可视化输出
output$results_1 <- renderPrint(input$rank_list_1)
output$results_2 <- renderPrint(input$rank_list_2)
output$results_3 <- renderPrint(input$rank_list_3)
}
shinyApp(ui, server)CSS样式定义 (tags$head 和 tags$style):
uiOutput("selection_list"):
server 函数中的 output$selection_list:
通过简单地应用CSS的max-height和overflow-y: auto属性,我们可以有效地为Shiny sortable包中的rank_list添加滚动功能。这种方法不仅易于实现,而且提供了良好的用户体验,特别是在处理大量列表项时。结合Flexbox布局的考虑,您可以构建出既功能强大又美观的交互式Shiny应用。
以上就是Shiny Sortable列表滚动实现教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号