我正在构建一个绘制网络的闪亮应用程序。用户可以选择一个节点,单击一个切换按钮以显示该节点的自我网络,然后单击相同的按钮返回主网络。我试图让一个工具提示将鼠标悬停在按钮上,其文本会根据按钮本身的状态以及是否选择节点而发生变化。问题是工具提示仅在条件更改时才显示。
可重现的代码:
用户界面:
# libraries
library(shiny)
library(shinyBS)
library(igraph)
library(visNetwork)
# UI
shinyUI(
fluidPage(
visNetworkOutput("NetPlot",width="auto",height=600),
bsButton("Ego",label=textOutput("EgoText"),type="toggle",disabled=TRUE)
)
)
服务器:(抱歉,代码冗长 - 不太确定我哪里出错了,我想提供足够的上下文)
# libraries
library(shiny)
library(shinyBS)
library(igraph)
library(visNetwork)
# create data
nodes <- data.frame(id=c("10","11","12","13","14"))
edges <- data.frame(rbind(c("10","12"),c("10","14"),c("11","12"),c("13","14"),c("14","12")))
colnames(edges) <- c("from","to")
shinyServer(function(input,output,session) {
# Activate Ego Network button when a node is selected
observeEvent(input$NetPlot_selected, {
if (input$NetPlot_selected=="") disabled = TRUE
else disabled = FALSE
updateButton(session,"Ego", disabled=disabled)
}, priority=1)
# Set Ego Button text
# "Full Network" when TRUE, "Ego Network" when FALSE
output$EgoText <- renderText({
ifelse ((input$Ego), as.character("Full Network"), as.character("Ego Network"))
})
# Set tooltip text
# Works intermittently
observeEvent({
input$Ego
input$NetPlot_selected},
{
# No node is selected yet
if (is.null(input$NetPlot_selected) || input$NetPlot_selected=="")
{hovtx <- as.character("Select a node to extract ego network")}
# Node is selected
else if (!input$Ego && input$NetPlot_selected!="")
{hovtx <- as.character("Click to go to ego network")}
# Ego network is displayed
else if (!(is.null(input$Ego)) && input$Ego)
{hovtx <- as.character("Click to return to full network")}
addTooltip(session,"Ego",hovtx,"right",trigger="hover", options=list(container="body"))
},priority=2)
# Create ego network dataframe when toggle button is on
EgoNet <- reactive({
req(input$Ego)
# Convert main network to igraph
ego1 <- graph_from_data_frame(edges, directed=FALSE, nodes)
# Get ego network of the selected node
ego2 <- make_ego_graph(ego1, nodes=input$NetPlot_selected)[[1]]
# Convert back to visNetwork
ego3 <- toVisNetworkData(ego2)
ego3
})
# Plot the network
output$NetPlot <- renderVisNetwork({
if (input$Ego){ # Ego network is requested
visNetwork(EgoNet()$nodes, EgoNet()$edges) %>%
visIgraphLayout(physics=FALSE, type="full", layout="layout_with_kk")
} else
{ # Ego network not requested
visNetwork(nodes,edges) %>%
visOptions(nodesIdSelection=TRUE,
highlightNearest=list(
enabled=TRUE, labelOnly=FALSE)
) %>%
visIgraphLayout(physics=FALSE, type="full", layout="layout_with_kk")
}
})
})
当应用程序首次加载时,如果我在执行任何其他操作之前将鼠标悬停在按钮上,工具提示就会起作用。单击一个节点,工具提示不再起作用。单击该按钮,工具提示将再次起作用。再次单击按钮,工具提示有效。如果在重新开始时,我没有将鼠标悬停在按钮上,而是先单击一个节点,则工具提示适用于该条件,但在单击按钮后无效。设置这两个部分的优先级observeEvent
有助于在返回完整网络时保持工具提示的功能,所以我想知道第一个是否会干扰第二个,但我不确定还能做什么。
我确实尝试了renderText
与按钮标签一起使用的方法,但bsTooltip
在 UI 中没有响应响应式文本,这就是我addTooltip
在服务器端使用的原因。
编辑
大约一个月后,我回到了这个尝试另一种方法。
如果我更新 ui 以uiOutput("EgoTip")
在最后添加,然后转到服务器并将第二个替换observeEvent
为以下内容:
output$EgoTip <- renderUI({
if (is.null(input$NetPlot_selected) || input$NetPlot_selected=="")
{bsTooltip("Ego", "Select a node to extract ego network", "right",
options=list(container="body"))}
else if (!input$Ego && input$NetPlot_selected!="")
{bsTooltip("Ego", "Click to go to ego network", "right",
options=list(container="body"))}
else if (!(is.null(input$Ego)) && input$Ego)
{bsTooltip("Ego", "Click to return to full network", "right",
options=list(container="body"))}
})
我得到完全相同的行为。这排除了这是两个observeEvent
块相互干扰和/或在 中具有两个输入的问题observeEvent
。if else if
我使用相同的逻辑将文本发送到全局环境中的对象,对逻辑进行了四次检查,并且全部检查出来。它一定是循环浏览工具提示的东西,这是我没有想法的地方。