2014-09-23 13 views
8

Hinweis: Ich habe fast alle Diskussionen zu diesem Objekt in glänzenden googlegroups und hier in SO gelesen.glänzende App beschäftigt Indikator

Ich brauche eine Anzeige, die zeigt, dass der glänzende Server beschäftigt ist. Ich habe einen glänzenden Inkubator ausprobiert, aber das Problem ist, dass ich keinen Max für den Fortschrittsbalken einstellen kann. Ich möchte nicht so etwas: http://shiny.rstudio.com/gallery/progress-example.html Was ich brauche, ist etwas, das: 1- zeigt eine busy-Indikator Nachricht und bar (dh nur eine einfache animierte bar, muss nicht zeigen eine Füllung bar) so lange wie die Server berechnet 2- Es wird angezeigt, egal welche Registerkarte angezeigt wird. (Nicht nur in dem entsprechenden Registerkarte, aber auf das tabset)

Dank

+0

Dieser Link ist tot ... –

Antwort

8

Ich habe auch dafür gesucht. Die meisten Menschen legen nahe, eine bedingte Panel wie folgt:

conditionalPanel(
      condition="!($('html').hasClass('shiny-busy'))", 
      img(src="images/busy.gif") 
) 

Sie sich immer mehr Kontrolle geben könnte, und erstellen Sie die bedingte Handhabung (vielleicht auf mehr Material abhängig) wie dies in Ihrem ui.R:

div(class = "busy", 
    p("Calculation in progress.."), 
    img(src="images/busy.gif") 
) 

wo einige JavaScript, um das Ein- und Ausblenden der div Griff:

setInterval(function(){ 
    if ($('html').attr('class')=='shiny-busy') { 
    $('div.busy').show() 
    } else { 
    $('div.busy').hide() 
    } 
},100) 

mit einigen zusätzlichen CSS können Sie Ihre animierten beschäftigen Bild bekommt eine feste Postion stellen Sie sicher, wo Es wird immer sichtbar sein. In jedem der oben genannten Fälle habe ich festgestellt, dass der Zustand "glänzend besetzt" etwas ungenau und unzuverlässig ist: das div zeigt für einen Bruchteil einer Sekunde und verschwindet, während Berechnungen noch laufen ... Ich fand eine schmutzige Lösung um dieses Problem zumindest in meinen Apps zu beheben. Fühlen Sie sich frei, es auszuprobieren und vielleicht könnte jemand einen Einblick geben, wie und warum dies das Problem löst.

In Ihrem server.R werden Sie brauchen zwei reactiveValues ​​hinzuzufügen:

shinyServer(function(input, output, session) { 

    # Reactive Value to reset UI, see render functions for more documentation 
    uiState <- reactiveValues() 
    uiState$readyFlag <- 0 
    uiState$readyCheck <- 0 

dann in Ihrer renderPlot Funktion (oder andere Ausgabefunktion, wo Berechnungen gehen), können Sie diese reaktiven Werte verwenden, die zum Zurücksetzen Funktion:

output$plot<- renderPlot({ 

    if (is.null(input$file)){ 
     return() 
    } 
    if(input$get == 0){ 
     return() 
    } 

    uiState$readyFlag 

    # DIRTY HACK: 
    # Everytime "Get Plot" is clicked we get into this function 
    # In order for the ui to be able show the 'busy' indicator we 
    # somehow need to abort this function and then of course seamlessly 
    # call it again. 
    # We do this by using a reactive value keeping track of the ui State: 
    # renderPlot is depending on 'readyFlag': if that gets changed somehow 
    # the reactive programming model will call renderPlot 
    # If readyFlag equals readyCheck we exit the function (= ui reset) but in the 
    # meantime we change the readyFlag, so the renderHeatMap function will 
    # immediatly be called again. At the end of the function we make sure 
    # readyCheck gets the same value so we are back to the original state 

    isolate({ 
     if (uiState$readyFlag == uiState$readyCheck) { 
      uiState$readyFlag <- uiState$readyFlag+1 
      return(NULL) 
     } 
    }) 

    isolate({plot <- ...}) 

    # Here we make sure readyCheck equals readyFlag once again 
    uiState$readyCheck <- uiState$readyFlag 

    return(plot) 
}) 
+0

danke. Ich werde es versuchen und Sie das Ergebnis wissen lassen –

0

Das Besetzt div erscheint auch Bruchteile von Sekunden für die neuesten Versionen von glänzenden für, obwohl keine offensichtlichen Berechnungen gehen (es in älteren Versionen war kein Problem). Shiny scheint für kurze Zeit regelmäßig im Besetzt-Modus zu sein. Als eine Lösung (die obige Diskussion ergänzend) kann man eine zweite verzögerte Validierung der glänzend-beschäftigten HTML-Klasse für die bedingte Behandlung einschließen. Der JavaScript-Teil etwas wie das aussehen würde (Beispiel enthält auch Check für zwei verschiedene div.busy-Staaten auf dem reaktiven textit abhängig):

 if(($('html').attr('class')=='shiny-busy')){ 
       setTimeout(function() { 
       if ($('html').attr('class')=='shiny-busy') { 
        if($('#textit').html()!='Waiting...'){ 
         $('div.busy1').show() 
        } 
        if($('#textit').html()=='Waiting...'){ 
         $('div.busy2').show() 
        } 
       } 
       },1000) 
       } else { 
       $('div.busy1').hide() 
       $('div.busy2').hide() 
       } 
      },100) 
1

ich mit fadeIn gefunden() zu zeigen, im Gegensatz() hilft zu mildern Dieses blinkende Ereignis:

setInterval(function(){ 
        if ($('html').attr('class')=='shiny-busy') { 
          setTimeoutConst = setTimeout(function(){ 
           $('#loading-page').fadeIn(500); 
          }, delay); 
         } else { 
          clearTimeout(setTimeoutConst); 
          $('#loading-page').hide(); 
         } 
       },10) 
Verwandte Themen