jqui_sortable 多个 ggplots do.call 不工作
jqui_sortable with do.call of multiple ggplots not working
为了让我的多绘图应用程序尽可能地成为 'free',到目前为止,我已经建立了一个很好的方法来构建 1:n ggplots
- 自动缩放它们
- auto ar运行ge them
- 使它们可缩放
- 让它们可以点击
- 提供巧妙定位的悬停消息
每个地块在其 div 上方也有几个按钮,以允许用户:
- 拯救他们
- 使情节 n 全屏
- 从页面中删除情节
和用户构建自己的新功能plots
以添加到自动布局页面
我尝试的下一步是合并 shinyjqui
功能,但我 运行 遇到了一些(预期的?)障碍
首先:应用程序中的 jqui_sortable
包装器成功地允许用户使用鼠标拾取子图,但当用户将其放在某处时实际上并没有改变布局。当用户放下 plot
对象时,绘图只是 return 到正常顺序。
我遵循了 jqui page
上的示例
第二个可能无法克服的问题是,在 div 中单击鼠标,在绘图内部或外部具有相同的效果,它会触发提升通过 jqui_sortable
,从而 '否决了 ggplot
对象的单击拖动缩放。
在理想情况下,我想在 plot
外部(但在 div 内部)和 ggplot2
的 brush
[= 单击时触发 jqui_sortable
25=]
require('shiny')
require('ggplot2')
require('shinyjqui')
ui <- pageWithSidebar(
headerPanel("reorganize page"),
sidebarPanel(width = 2,
sliderInput(inputId = 'NrOfPlots', label = 'Nr of Plots', min = 1, max = 20, value = 1)
),
mainPanel(
uiOutput('FP1PlotMultiplot'),
style = 'width:1250px'
)
)
server <- function(input, output, session) {
ranges <- reactiveValues()
observe({
lapply(1:input$NrOfPlots, function(i) {
output[[paste0('FP1Plot_', i)]] <- renderPlot({
p <- ggplot(mtcars, aes(wt, mpg, color = as.factor(cyl))) + geom_point() +
theme(legend.position = "none") +
ggtitle(paste('plot', i))
if(!is.null(ranges[[paste('FP1Plot', i, 'x', sep = '_')]]) & !is.null(ranges[[paste('FP1Plot', i, 'y', sep = '_')]])) {
p <- p + coord_cartesian(xlim = ranges[[paste('FP1Plot', i, 'x', sep = '_')]], ylim = ranges[[paste('FP1Plot', i, 'y', sep = '_')]] )
}
p
})
})
})
output$FP1PlotMultiplot<- renderUI({
n <- input$NrOfPlots
n_cols <- if(n == 1) {
1
} else if (n %in% c(2,4)) {
2
} else if (n %in% c(3,5,6,9)) {
3
} else {
4
}
Pwidth <- 1000/n_cols
Pheight <- 450/ceiling(n/n_cols) # calculate number of rows
Pwidth2 <- Pwidth+40
Pheight2 <- Pheight+80
plot_output_list <- list()
for(i in 1:input$NrOfPlots) {
plot_output_list <- append(plot_output_list,list(
div(id = paste0('div', 'FP1Plot_', i),
wellPanel(
plotOutput(paste0('FP1Plot_', i),
width = Pwidth,
height = Pheight,
dblclick = paste('FP1Plot' , i, 'dblclick', sep = '_'),
brush = brushOpts(
id = paste('FP1Plot', i, 'brush', sep = '_'),
resetOnNew = TRUE
)
),
style = paste('border-color:#339fff; border-width:2px; background-color: #fff; width:', Pwidth2, 'px; height:', Pheight2, 'px', sep = '')),
style = paste('display: inline-block; margin: 2px; width:', Pwidth2, 'px; height:', Pheight2, 'px', sep = ''))
))
}
jqui_sortable(do.call(tagList, plot_output_list))
})
lapply(1:20, function(i) {
observeEvent(input[[paste('FP1Plot', i, 'brush', sep = '_')]], {
brush <- input[[paste('FP1Plot', i, 'brush', sep = '_')]]
if (!is.null(brush)) {
ranges[[paste('FP1Plot', i, 'x', sep = '_')]] <- c(brush$xmin, brush$xmax)
ranges[[paste('FP1Plot', i, 'y', sep = '_')]] <- c(brush$ymin, brush$ymax)
}
})
observeEvent(input[[paste('FP1Plot', i, 'dblclick', sep = '_')]], {
ranges[[paste('FP1Plot', i, 'x', sep = '_')]] <- NULL
ranges[[paste('FP1Plot', i, 'y', sep = '_')]] <- NULL
})
})
}
shinyApp(ui, server)
可排序的元素必须在div
中。做:
jqui_sortable(do.call(function(...) div(id="allplots", ...),
plot_output_list))
为了让我的多绘图应用程序尽可能地成为 'free',到目前为止,我已经建立了一个很好的方法来构建 1:n ggplots
- 自动缩放它们
- auto ar运行ge them
- 使它们可缩放
- 让它们可以点击
- 提供巧妙定位的悬停消息
每个地块在其 div 上方也有几个按钮,以允许用户: - 拯救他们 - 使情节 n 全屏 - 从页面中删除情节
和用户构建自己的新功能plots
以添加到自动布局页面
我尝试的下一步是合并 shinyjqui
功能,但我 运行 遇到了一些(预期的?)障碍
首先:应用程序中的 jqui_sortable
包装器成功地允许用户使用鼠标拾取子图,但当用户将其放在某处时实际上并没有改变布局。当用户放下 plot
对象时,绘图只是 return 到正常顺序。
我遵循了 jqui page
第二个可能无法克服的问题是,在 div 中单击鼠标,在绘图内部或外部具有相同的效果,它会触发提升通过 jqui_sortable
,从而 '否决了 ggplot
对象的单击拖动缩放。
在理想情况下,我想在 plot
外部(但在 div 内部)和 ggplot2
的 brush
[= 单击时触发 jqui_sortable
25=]
require('shiny')
require('ggplot2')
require('shinyjqui')
ui <- pageWithSidebar(
headerPanel("reorganize page"),
sidebarPanel(width = 2,
sliderInput(inputId = 'NrOfPlots', label = 'Nr of Plots', min = 1, max = 20, value = 1)
),
mainPanel(
uiOutput('FP1PlotMultiplot'),
style = 'width:1250px'
)
)
server <- function(input, output, session) {
ranges <- reactiveValues()
observe({
lapply(1:input$NrOfPlots, function(i) {
output[[paste0('FP1Plot_', i)]] <- renderPlot({
p <- ggplot(mtcars, aes(wt, mpg, color = as.factor(cyl))) + geom_point() +
theme(legend.position = "none") +
ggtitle(paste('plot', i))
if(!is.null(ranges[[paste('FP1Plot', i, 'x', sep = '_')]]) & !is.null(ranges[[paste('FP1Plot', i, 'y', sep = '_')]])) {
p <- p + coord_cartesian(xlim = ranges[[paste('FP1Plot', i, 'x', sep = '_')]], ylim = ranges[[paste('FP1Plot', i, 'y', sep = '_')]] )
}
p
})
})
})
output$FP1PlotMultiplot<- renderUI({
n <- input$NrOfPlots
n_cols <- if(n == 1) {
1
} else if (n %in% c(2,4)) {
2
} else if (n %in% c(3,5,6,9)) {
3
} else {
4
}
Pwidth <- 1000/n_cols
Pheight <- 450/ceiling(n/n_cols) # calculate number of rows
Pwidth2 <- Pwidth+40
Pheight2 <- Pheight+80
plot_output_list <- list()
for(i in 1:input$NrOfPlots) {
plot_output_list <- append(plot_output_list,list(
div(id = paste0('div', 'FP1Plot_', i),
wellPanel(
plotOutput(paste0('FP1Plot_', i),
width = Pwidth,
height = Pheight,
dblclick = paste('FP1Plot' , i, 'dblclick', sep = '_'),
brush = brushOpts(
id = paste('FP1Plot', i, 'brush', sep = '_'),
resetOnNew = TRUE
)
),
style = paste('border-color:#339fff; border-width:2px; background-color: #fff; width:', Pwidth2, 'px; height:', Pheight2, 'px', sep = '')),
style = paste('display: inline-block; margin: 2px; width:', Pwidth2, 'px; height:', Pheight2, 'px', sep = ''))
))
}
jqui_sortable(do.call(tagList, plot_output_list))
})
lapply(1:20, function(i) {
observeEvent(input[[paste('FP1Plot', i, 'brush', sep = '_')]], {
brush <- input[[paste('FP1Plot', i, 'brush', sep = '_')]]
if (!is.null(brush)) {
ranges[[paste('FP1Plot', i, 'x', sep = '_')]] <- c(brush$xmin, brush$xmax)
ranges[[paste('FP1Plot', i, 'y', sep = '_')]] <- c(brush$ymin, brush$ymax)
}
})
observeEvent(input[[paste('FP1Plot', i, 'dblclick', sep = '_')]], {
ranges[[paste('FP1Plot', i, 'x', sep = '_')]] <- NULL
ranges[[paste('FP1Plot', i, 'y', sep = '_')]] <- NULL
})
})
}
shinyApp(ui, server)
可排序的元素必须在div
中。做:
jqui_sortable(do.call(function(...) div(id="allplots", ...),
plot_output_list))