我正在构建一个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)