In an attempt to make my multiplot app as 'free' as possible, I have so far build a nice way to build 1:n ggplots
- auto scale them
 - auto arrange them
 - make them zoomable
 - make them clickable
 - give smartly positioned hover messages
 
Each plot also gets a few buttons above it in it's div to allow the user to: - save them - make plot n full screen - remove plot from the page
and functionality for the user to build their own new plots to add to the auto layout page
The next step I was trying out, was to incorporate shinyjqui functionality but there I ran into some (expected?) obstacles
To start with: the jqui_sortable wrapper in the app successfully allows the user to pick up sub plots with the mouse, but does not actually change the layout when the user drops it somewhere. The plots simply return to the normal order when the user drops the plot object. 
I followed the examples on the jqui page
The second problem, which may not be possible to overcome, is that click-hold of the mouse in the div, inside the plot OR outside of it has the same effect, it triggers the lifting up by jqui_sortable , thereby 'overruling the click-drag to zoom of the ggplot object. 
In an ideal scenario I would like to trigger the jqui_sortable when clicking outside the plot (but inside the div), and ggplot2's brush
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)
