I'm trying to create an R shiny dashboard with a Sankey plot. I want to be able to extract the name of the clicked node.
There are two libraries that can plot Sankey diagrams, networkD3
and googleVis
. networkD3
does allow you to monitor click events, even though another type of plot implemented in the same library comes with such feature (forceNetwork()
).
googleVis
package however has a function gvisSankey
that can create sankey plots and as an option you can pass a parameter gvis.listener.jscode
that should be able to capture it.
I'm afraid I'm not that familiar with JS and I'm struggling to get what I'm looking for. This is how far I managed to get:
library(shiny)
library(googleVis)
datSK <- data.frame(From=c(rep("A",3), rep("B", 3)),
To=c(rep(c("X", "Y", "Z"),2)),
Weight=c(5,7,6,2,9,4))
SERVER <- function(input, output, session){
sankey_click <- sprintf("var text = chart.getSelection();
Shiny.onInputChange('%s', text.toString())", session$ns('text'))
output$sankey <- renderGvis(
gvisSankey(datSK, from="From", to="To", weight="Weight",
options=list(gvis.listener.jscode = sankey_click,
sankey = "{node: {interactivity: true, width: 50}}"))
)
click_event <- reactive({input$text})
output$click <- renderText(click_event())
}
UI <- fluidPage(
fluidRow(column(12, htmlOutput("sankey"))),
fluidRow(column(12, verbatimTextOutput("click")))
)
shinyApp(ui = UI, server = SERVER)
As you can see, all I get is object Object
.
I'll share some details on how I debugged this since you are new to JavaScript and it can hopefully help you in the future.
First, I added a console.log statement to sankey_click to see what kind of object we were dealing with. In Chrome, you can open the console with Ctrl+Shift+J.
sankey_click <- sprintf("var text = chart.getSelection();
Shiny.onInputChange('%s', text.toString()); console.log(text);", session$ns('text'))
So, now we can see why you were returning an object. The click is, in fact, returning an array of objects, each with a property 'name'. Then, it is an easy fix once you know this. Simply change sankey_click
sankey_click <- sprintf("var text = chart.getSelection()[0]['name'];
Shiny.onInputChange('%s', text.toString()); console.log(text);", session$ns('text'))
and when you're satisfied, remove the console.log
sankey_click <- sprintf("var text = chart.getSelection()[0]['name'];
Shiny.onInputChange('%s', text.toString());", session$ns('text'))
Just one way to deal with the Shiny Javascript when you don't know what is going on.