是否可以初始化Shiny输入值而不将它们包含在ui中?

时间:2019-04-30 04:30:05

标签: javascript r shiny shinyjs

我正在构建一个Shiny应用程序,可在其中单击输出元素以设置输入变量。为此,我加入了一些调用Shiny.setInputValue方法的Javascript。

我想初始化这些值,但不希望用户意识到它们,因为它们仅在后台使用。我目前的技巧是在用户界面中的某些按钮周围使用hidden库中的shinyjs函数,但这并不是很令人满意。这是我的方法的一个示例:

library(shiny)
library(shinyjs)
library(tidyverse)

ui <- fluidPage(
  useShinyjs(),
  hidden(
    numericInput(label = NULL, inputId = 'INPUT', value = 0)
  ),
  DT::dataTableOutput("one_row")
)

server <- function(input, output) {
  script <- 'Shiny.setInputValue("INPUT", Math.random());'
  btn <- as.character(actionButton(inputId = 'button', 
                                   label = "Click me!", 
                                   onclick = script))
  one_row <- iris[1, ] %>% mutate(button = btn)
  output$one_row <- DT::renderDataTable({
    print(input$INPUT)
    one_row}, escape = FALSE)
}

shinyApp(ui = ui, server = server)

所以我的主要问题是:是否有更好的方法来设置这些“不可见”输入的默认值?我应该只在应用程序中的某个地方使用runjs函数吗?

一个相关的问题是:是否可以使用javascript访问这些输入值?我希望有类似Shiny.getInputValue的东西,但似乎没有。

编辑:

这是一个更彻底的示例,准确地显示了我正在尝试做的事情。我正在使用visNetwork,但我想覆盖一些默认行为。通常,当您单击一个节点时,它会显示所有连接的边(传入或传出的边)。

我希望节点选择仅显示一个方向上的边缘,然后再次单击(显示,输出,输入,输出...)显示另一个方向。为此,我需要跟踪点击(click),选择哪个节点(selected_node)以及当前显示的方向(out)。

要实现此目的,我目前正在使用visEvents重新定义一次单击所发生的情况,并使用visNetworkProxy选择基于该单击的节点和边。

library(shiny)
library(shinyjs)
library(tidyverse)
library(visNetwork)

ui <- fluidPage(
  useShinyjs(),
  hidden(
    numericInput(label = NULL, inputId = 'click', value = 0),
    numericInput(label = NULL, inputId = 'selected_node', value = 0)
  ),
  visNetworkOutput("network")
)

server <- function(input, output) {

  network <- reactive({
    nodes <- data.frame(id = 1:3)
    edges <- data.frame(expand.grid(to = 1:3, from = 1:3)) %>%
      mutate(id = row_number())
    list(nodes = nodes, edges = edges)
    })

  output$network <- renderVisNetwork({

    network <- network()

    visNetwork(network$nodes, network$edges) %>% 
      visPhysics(enabled = FALSE) %>%
      visLayout(randomSeed = 123) %>%
      visEdges(smooth = list(type = 'curvedCW'),
               arrows =list(to = list(enabled = TRUE, scaleFactor = 0.5))) %>% 
      visEvents(type = "on", 
                click = "function (properties) {
                          var nodeID = properties.nodes[0]
                          var edgeID = properties.edges[0];
                          if (nodeID) { Shiny.onInputChange('click', 1, {priority: \"event\"});
                                        Shiny.onInputChange('selected_node', nodeID)} 
                          else if (edgeID){ Shiny.onInputChange('click', 2);}
                          else { Shiny.onInputChange('click', 3);}}")
  })

  out <- FALSE

  observe({
    out <<- !out
    nodeID <- input$selected_node
    network <- network()

    # only fire if node was selected
    if(input$click == 1){
      edgeIDs <- network$edges %>% filter(to == nodeID) %>%
        pull(id)

      if(out){edgeIDs <- network$edges %>% filter(from == input$selected_node) %>% pull(id)}

      visNetworkProxy("network") %>%
        visSetSelection(nodesId = nodeID, edgesId = edgeIDs, highlightEdges = FALSE)
    }
  })
  }

shinyApp(ui = ui, server = server)

0 个答案:

没有答案