R Shiny - sankey plot with click events
Asked Answered
M

1

7

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.

Macedonia answered 14/1, 2017 at 0:1 Comment(0)
K
9

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.

Karyogamy answered 14/1, 2017 at 15:31 Comment(1)
I'd give you a 100 upvotes for this answer if I could, thank you! You didn't just give me the answer, you showed me how to resolve similar issues in the future.Macedonia

© 2022 - 2024 — McMap. All rights reserved.