Sourabh Kumar
Sourabh Kumar

Reputation: 41

R-Customized tooltip in networkD3::sankeyNetwork

We have created sankey diagram to show flow between different cities via networkD3::sankeyNetwork() in R. We have received client requirement to show "state" name corresponding to city on tooltip/hover of sankey node.

In following code we want to show State value on tool-tip(hover) of node

library(shiny)
library(networkD3)
library(shinydashboard)
value <-  c(12,21,41,12,81)
source <- c(4,1,5,2,1)
target <- c(0,0,1,3,3)

edges2 <- data.frame(cbind(value,source,target))

names(edges2) <- c("value","source","target")
indx  <- c(0,1,2,3,4,5)
ID    <- c('CITY1','CITY2','CITY3','CITY4','CITY5','CITY6')
State <- c( 'IL','CA','FL','NW','GL','TX')
nodes <-data.frame(cbind(ID,indx,State))

ui <- dashboardPage(
  dashboardHeader(
  ),
  dashboardSidebar(disable = TRUE),
  dashboardBody(
    fluidPage(
      sankeyNetworkOutput("simple")
    )
  )
)

server <- function(input, output,session) {
  
  
  output$simple <- renderSankeyNetwork({
    sankeyNetwork(Links = edges2, Nodes = nodes,
                  Source = "source", Target = "target",
                  Value = "value",  NodeID = "ID" 
                  ,units = " " )
  })
}
shinyApp(ui = ui, server = server)

As the networkD3 package does not provide a customized tooltip feature, please suggest how it can be achieved via javascript or some other way in networkD3::sankeyNetwork().

Upvotes: 3

Views: 2240

Answers (1)

CJ Yetman
CJ Yetman

Reputation: 8848

You can use a technique similar to this Stack Overflow answer. Save the output of the sankeyNetwork function, then add back in the data that gets stripped out, then use htmlwidgets::onRender to add some JavaScript to modify the tooltip text of the nodes...

library(shiny)
library(networkD3)
library(shinydashboard)
value <-  c(12,21,41,12,81)
source <- c(4,1,5,2,1)
target <- c(0,0,1,3,3)

edges2 <- data.frame(cbind(value,source,target))

names(edges2) <- c("value","source","target")
indx  <- c(0,1,2,3,4,5)
ID    <- c('CITY1','CITY2','CITY3','CITY4','CITY5','CITY6')
State <- c( 'IL','CA','FL','NW','GL','TX')
nodes <-data.frame(cbind(ID,indx,State))

ui <- dashboardPage(
    dashboardHeader(
    ),
    dashboardSidebar(disable = TRUE),
    dashboardBody(
        fluidPage(
            sankeyNetworkOutput("simple")
        )
    )
)

server <- function(input, output,session) {


    output$simple <- renderSankeyNetwork({
        sn <- sankeyNetwork(Links = edges2, Nodes = nodes,
                      Source = "source", Target = "target",
                      Value = "value",  NodeID = "ID" 
                      ,units = " " )

        # add the states back into the nodes data because sankeyNetwork strips it out
        sn$x$nodes$State <- nodes$State

        # add onRender JavaScript to set the title to the value of 'State' for each node
        sn <- htmlwidgets::onRender(
            sn,
            '
            function(el, x) {
                d3.selectAll(".node").select("title foreignObject body pre")
                .text(function(d) { return d.State; });
            }
            '
        )

        # return the result
        sn
    })
}
shinyApp(ui = ui, server = server)

Upvotes: 6

Related Questions