Vaibhav
Vaibhav

Reputation: 107

Undo click event in Visnetwork in r shiny

I have created a network chart in Shiny and wanted to show details of selected node below network chart. Answer marked as correct on this link helped me in achieving that.

Click events for VisNetwork with Shiny

An additional thing I want to do is when the user clicks anywhere else (blank space) in the network chart, information present for the earlier clicked node should also disappear in the same manner it deselects the selected node.

Please suggest if this is possible. Below is the code

library(shiny)
library(visNetwork)

nodes <- data.frame(id = 1:15, label = paste("Label", 1:15),
                    group = sample(LETTERS[1:3], 15, replace = TRUE))

edges <- data.frame(from = trunc(runif(15)*(15-1))+1,
                    to = trunc(runif(15)*(15-1))+1)

server <- function(input, output, session) {
  output$network <- renderVisNetwork({
    visNetwork(nodes, edges, 
               height = "100%", width = "100%",
               main = "") %>%
      visEvents(click = "function(nodes){
                Shiny.onInputChange('click', nodes.nodes[0]);
                ;}"
      )
  })

  output$shiny_return <- renderPrint({
    visNetworkProxy("network") %>%
      visNearestNodes(target = input$click)
  })
}

ui <- fluidPage(
  visNetworkOutput("network"), 
  verbatimTextOutput("shiny_return")  
)

shiny::shinyApp(ui = ui, server = server)

Upvotes: 1

Views: 982

Answers (1)

kluu
kluu

Reputation: 2995

Yes you can. The trick is to pass another variable to R that kind of tell you whether you are clicking on a node or on the canvas. If you're clicking on the canvas, then node.node should be undefined. Store that information in a variable, pass it to R, and display the node information accordingly (or not).

server <- function(input, output, session) {
  output$network <- renderVisNetwork({
    visNetwork(nodes, edges, 
               height = "100%", width = "100%",
               main = "") %>%
      visEvents(click = "function(nodes){
                Shiny.onInputChange('click', nodes.nodes[0]);
                Shiny.onInputChange('node_selected', nodes.nodes.length);
                ;}"
      ) 
  })

  output$shiny_return <- renderPrint({
    if (!is.null(input$node_selected) && (input$node_selected == 1)) {
    visNetworkProxy("network") %>%
      visNearestNodes(target = input$click)
    } else {
      invisible()
    }
  })
} 

EDIT: answer to the comment

observe({
  input$node_selected 
  input$click
    if(!is.null(input$node_selected) && (input$node_selected == 1)){ 
      output$networkTable <- renderDataTable(data.frame(x = runif(10), 
                                                        y = runif(10))) 
    } else { 
      output$networkTable <- renderDataTable(NULL)
    } 
}) 

Upvotes: 1

Related Questions