Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Shiny - sankey plot with click events

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.

like image 263
IVR Avatar asked Jan 14 '17 00:01

IVR


1 Answers

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'))

enter image description here

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'))

enter image description here

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.

like image 128
danielson Avatar answered Oct 19 '22 02:10

danielson