2016-05-11 10 views
7

ich die glänzende Armaturenbrett Vorlage bin mit meinem Web-UI zu erzeugen.Direkt-Link mit R glänzend Armaturenbrett TabItem

Ich möchte eine Infobox dynamisch generieren, wenn eine Berechnung mit einem Link zu einem der TabItems in dashboardBody abgeschlossen ist.

Zum Beispiel Ich kann diese in meinem tabItem1 Ausgang,

renderInfoBox({ 
    infoBox("Completed", 
    a("Computation Completed", href="#tabItem2"), 
    icon = icon("thumbs-o-up"), color = "green" 
) 
}) 

Aber das Problem ist, dass, wenn ich auf den Link klicken, es tut nichts. Ich möchte, dass es auf tabItem2 springt. Die Verknüpfung href scheint gültig zu sein, wenn ich darauf schwebe.

Danke!


Update: Anders als Javascripts verwenden, sieht aus wie mit actionLink und updateTabItems Funktionen in shinydashboard Paket als gut funktionieren wird.

Antwort

12

Ich entschuldige mich für das lange Codebeispiel, aber ich hatte ein Beispiel mit tabItems von der shinydashboard Homepage zu kopieren.

Ihr Ansatz hat nur wenige Probleme. Erstens, wenn Sie die menuItems überprüfen würde, würden Sie sehen, dass die ID tatsächlichen Registerkarte ist nicht tabItem2, aber shiny-tab-tabItem2. Dies und das zusätzliche Attribut data-toggle="tab" innerhalb des Tags a würden ausreichen, um die gewünschte Registerkarte zu öffnen. Snippet:

a("Computation Completed", href="#shiny-tab-tabItem2", "data-toggle" = "tab") 

Aber das hat seine Grenzen. Zunächst und am offensichtlichsten ist der Status der menuItem in der Seitenleiste nicht auf active festgelegt. Das sieht sehr merkwürdig aus und man könnte nicht davon überzeugt sein, dass man auf einen anderen Tab verschoben wurde.

Zweitens, und weniger offensichtlich, wenn Sie auf die Registerkarte Änderungen (auf der Serverseite) hören, werden Sie keine Informationen zu dieser Registerkarte Schalter erhalten. Diese werden ausgelöst, indem auf menuItem geklickt wird, und die Registerkarte selbst meldet nicht, ob sie sichtbar oder ausgeblendet ist.

Also mein Ansatz wird zu simulieren, dass die entsprechende menuItem angeklickt wird, und damit alle oben genannten Probleme gelöst sind.

Code-Beispiel:

library(shiny) 
library(shinydashboard) 

ui <- shinyUI(
    dashboardPage(
    dashboardHeader(title = "Some Header"), 
    dashboardSidebar(
     sidebarMenu(
     menuItem("Computations", tabName = "tabItem1", icon = icon("dashboard")), 
     menuItem("Results", tabName = "tabItem2", icon = icon("th")) 
    ) 
    ), 

    dashboardBody(
     tabItems(
     tabItem(tabName = "tabItem1", 
      fluidRow(
      box(plotOutput("plot1", height = 250)), 

      box(
       title = "Controls", 
       sliderInput("slider", "Number of observations:", 1, 100, 50) 
      ) 
     ), 
      infoBoxOutput("out1") 
     ), 

     tabItem(tabName = "tabItem2", 
      h2("Widgets tab content") 
     ) 
    ) 
    ) 
) 
) 

server <- function(input, output){ 
    histdata <- rnorm(500) 

    output$plot1 <- renderPlot({ 
    data <- histdata[seq_len(input$slider)] 
    hist(data) 
    }) 

    output$out1 <- renderInfoBox({ 
    infoBox("Completed", 
     a("Computation Completed", onclick = "openTab('tabItem2')"), 
     tags$script(HTML(" 
     var openTab = function(tabName){ 
      $('a', $('.sidebar')).each(function() { 
      if(this.getAttribute('data-value') == tabName) { 
       this.click() 
      }; 
      }); 
     } 
     ")), 
     icon = icon("thumbs-o-up"), color = "green" 
    ) 
    }) 
} 

shinyApp(ui, server) 

Beachten Sie, dass die einzige wichtige Sache ist die onclick Eigenschaft, kein href. Dies bedeutet, dass jede div oder ein anderes Element zum Erstellen dieser Verbindung verwendet werden kann. Mit diesem Befehl onclick könnten Sie sogar nur das Bild mit dem Daumen nach oben haben.

Wenn Sie weitere Fragen haben, bitte kommentieren.

Mit freundlichen Grüßen


Edit: Whole InfoBox anklickbar.

Dies ist eine antwort auf einen kommentar von OmaymaS.Der Punkt war, die InfoBox zu einem anklickbaren Container zu machen. Um dies zu erreichen, kann man eine neue Funktion definieren, die eine etwas andere infoBox macht. Das benutzerdefinierte Feld wird wie folgt sein:

customInfoBox <- function (title, tab = NULL, value = NULL, subtitle = NULL, icon = shiny::icon("bar-chart"), color = "aqua", width = 4, href = NULL, fill = FALSE) { 
    validateColor(color) 
    tagAssert(icon, type = "i") 
    colorClass <- paste0("bg-", color) 
    boxContent <- div(class = "info-box", class = if (fill) colorClass, 
     onclick = if(!is.null(tab)) paste0("$('.sidebar a')).filter(function() { return ($(this).attr('data-value') == ", tab, ")}).click()"), 
     span(class = "info-box-icon", class = if (!fill) colorClass, icon), 
     div(class = "info-box-content", 
      span(class = "info-box-text", title), 
      if (!is.null(value)) span(class = "info-box-number", value), 
      if (!is.null(subtitle)) p(subtitle) 
     ) 
    ) 
    if (!is.null(href)) boxContent <- a(href = href, boxContent) 
    div(class = if (!is.null(width)) paste0("col-sm-", width), boxContent) 
} 

Dieser Code aus der ursprünglichen infoBox Funktionsdefinition kopiert und nur die Zeile mit onclick ist neu. Ich fügte auch die openTab Funktion (mit einigen Zuckungen) direkt innerhalb des Containers hinzu, so dass Sie sich nicht sorgen müssen, wo Sie diese Funktion innerhalb der Ansicht setzen. Könnte ein bisschen überladen sein, fühle ich mich. Diese benutzerdefinierte Infobox kann genau wie die Standard-Infobox verwendet werden. Wenn Sie das zusätzliche Argument tab übergeben, wird die Verknüpfung zur Seitenleiste hinzugefügt.

+0

Das ist sehr ordentlich! Ich schätze es sehr. – athlonshi

+0

Was ist, wenn ich es auf die gesamte Infobox anwenden möchte, d. H. Irgendeinen Teil der Infobox. Ich bin mir nicht sicher, was das Tag ist, versuchte zu Kasse, aber hat nicht funktioniert. irgendeine Ahnung? – OmaymaS

+1

@OmaymaS Ich glaube (ohne es ausprobiert zu haben), man könnte einfach die 'onclick'-Eigenschaft vom 'a'-Tag eine Zeile nach oben zum' infoBox'-Tag bewegen. Dies sollte die Funktionalität zum gesamten Infobox-Container hinzufügen. –