Shiny Plotly Plot застрял при быстром переключении вкладок - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь найти способ избежать проблем с изменением размера без перезагрузки всего графика при переключении вкладок в Shiny перед загрузкой графика.Минимальный пример для воссоздания проблемы приведен ниже путем рисования выборок из значений амплитуды нормального распределения и последующего построения гистограммы в качестве заполнителя для графика с интенсивными вычислениями.

time_waste<- function(magnitude) {
  y<-0
  for(i in 1:magnitude) {
    y<- y + rnorm(1,0,1)
  }
  return(abs(y))
}

ui <- fluidPage(sidebarLayout(
    sidebarPanel(width = 3,
                              fluidRow(
                                column(
                                  4,
                                  numericInput(
                                    inputId = "magnitude",
                                    label = "magnitude",
                                    value = 1000000
                                      )))),
    mainPanel(width = 8,
              tabsetPanel(id = "tabset",
                          tabPanel("Plot1", plotlyOutput("p1", height = "700px")),
                          tabPanel("Plot2", plotlyOutput("p2", height = "700px"))))
  )
  )

server<- function(input, output, session) {

  y<- reactive({
    rep(time_waste(time_waste(input$magnitude)),3)
  })

  output$p1 <- renderPlotly({

  p<- plot_ly(
    x = c("giraffes", "orangutans", "monkeys"),
    y = y(),
    name = "SF Zoo",
    type = "bar"
  )
  })

  output$p2<-  renderPlotly({

    p<- plot_ly(
      x = c("giraffes", "orangutans", "monkeys"),
      y = y(),
      name = "SF Zoo",
      type = "bar"
    )

  return(p)
  })

}

app <- shinyApp(ui, server)
runApp(app)

При этом застрявший график выглядит каксвязанное изображение: Застрявший график

График отображается правильно, если его размер каким-либо образом изменяется (например, путем изменения размера окна, в котором он находится), и проблема не возникает с фиксированной шириной участка.

С уважением и заранее спасибо.

1 Ответ

0 голосов
/ 25 октября 2018

Это похоже на ошибку со стороны Plotly для меня.Если вы не назначите начальную ширину, график будет иметь ширину 100 пикселей.Изменение ширины div на 100% на самом деле мало что дает.

Вы можете включить Javascript для изменения размера графика каждый раз, когда нажимается вкладка, или вы можете отключить все кнопки вкладки, пока блестящий занят.

При использовании метода resize графики будут перерисовываться каждый раз, когда вы нажимаете клавишу Tab, и после изменения размера окна они снова изменяют свой размер.Я также безуспешно пытался использовать методы Plotly redraw, relayout.

Итак, я бы предпочел второй вариант, чтобы отключить вкладки, когда приложение занято, но это на самом деле не отвечает вашимвопрос, поэтому я закомментировал JavaScript.

time_waste<- function(magnitude) {
  y<-0
  for(i in 1:magnitude) {
    y<- y + rnorm(1,0,1)
  }
  return(abs(y))
}


## Resize plot p1 at every Tab click. 
js <- HTML("
$(document).on('shiny:value', function() { 
$('#tabset li a').on('click',function() {
  Plotly.Plots.resize('p1');
});
});
"
)


## Deactivate all Buttons as long as shiny is busy
# js <- HTML('
# $(document).on("shiny:busy", function() {
#  var inputs = document.getElementsByTagName("a");
#  console.log(inputs);
#  for (var i = 0; i < inputs.length; i++) {
#  inputs[i].disabled = true;
#  }
# });
# 
# $(document).on("shiny:idle", function() {
#  var inputs = document.getElementsByTagName("a");
#  console.log(inputs);
#  for (var i = 0; i < inputs.length; i++) {
#  inputs[i].disabled = false;
#  }
# });'
# )


ui <- fluidPage(
  ## Include JavaScript to the HTML
  tags$head(tags$script(js)),
  sidebarLayout(
  sidebarPanel(width = 3,
               fluidRow(
                 column(4,
                   numericInput(
                     inputId = "magnitude",
                     label = "magnitude",
                     value = 1000000
                   )))),
  mainPanel(width = 8,
            tabsetPanel(id = "tabset",
                        tabPanel("Plot1", plotlyOutput("p1", height = "700px")),
                        tabPanel("Plot2", plotlyOutput("p2", height = "700px"))))
  )
)

server<- function(input, output, session) {
  y <- reactive({
    rep(time_waste(time_waste(input$magnitude)),3)
  })

  output$p1 <- renderPlotly({
    plot_ly(x = c("giraffes", "orangutans", "monkeys"),
      y = y(),name = "SF Zoo",type = "bar")
  })

  output$p2<-  renderPlotly({
    plot_ly(x = c("giraffes", "orangutans", "monkeys"),
      y = y(), name = "SF Zoo",type = "bar")
  })
}

shinyApp(ui, server)
...