javascript - Vrátiť názov uzla v Networkd3 Sankey grafe (R/Shiny)


Mám diagram Sankey networkd3 vo svojej aplikácii R/Shiny, ktorý čerpá údaje z MySQL pripojenia. Snažím sa nájsť spôsob, ako 'preklikať' diagram - kliknúť na uzol a toto vráti názov uzla. Potom to použijem na odoslanie ďalšieho dopytu do databázy, ktorý naplní tabuľku v aplikácii.

Tu je, čo mám -

san <- sankeyNetwork(Links = sanData, Nodes = nodes, Source = "source",
    Target = "target", Value = "value")

Toto vykresľuje graf, ktorý funguje úplne dobre.

Tu je to, čo som zatiaľ vyskúšal -
Použite balík R htmlwidgets a spustite nasledujúci JS skript pomocou onRender na mojej sankeyovej diagramu.

Zástupný symbol pre JS skript:

clickFun <- 'd3.selectAll(".link").on("click",function(d) {alert(d.value);})'

Vo svojom výstupe Sankey:
onRender(san, clickFun)

Toto vráti hodnotu odkazu ako upozornenie. Skúsil som použiť ".node" a d.data.name, ako navrhli niektoré iné príklady, ale nikdy sa mi to nepodarilo rozbehnúť a žiadne upozornenie sa nezobrazí.

Tu sú moje otázky:
1. Ako môžem získať meno uzla zo sankey diagramu pri kliknutí myšou?
2. Za predpokladu, že som dosiahol vyššie uvedené, ako môžem použiť hodnotu, ktorú vráti môj JS skript, v mojej shiny aplikácii? Časť s alert() zmením na return(), ale neviem, ako to môžem použiť v mojej serverovej aplikácii.

Odpoveď č. 1

Dôvod, prečo vaša udalosť kliknutia funguje na odkazoch, ale nie na uzloch, je ten, že uzly majú pripojené aj správanie ťahania. Najjednoduchší spôsob, ako sa tomu vyhnúť, je zneplatniť správanie ťahania a potom pridať správanie kliknutia, takto...

library(networkD3)
library(htmlwidgets)

URL <- paste0('https://cdn.rawgit.com/christophergandrud/networkD3/',
              'master/JSONdata/energy.json')
energy <- jsonlite::fromJSON(URL)

san <- 
  sankeyNetwork(Links = energy$links, Nodes = energy$nodes, Source = 'source',
              Target = 'target', Value = 'value', NodeID = 'name',
              units = 'TWh', fontSize = 12, nodeWidth = 30)

clickFun <- 
  'function() { 
      d3.selectAll(".node").on("mousedown.drag", null);
      d3.selectAll(".node").on("click",function(d) { alert(d.name); })
   }'

onRender(san, clickFun)

tu je funkčný príklad, kde udalosť onclick vracia meno kliknutého uzla, ktoré je potom odovzdané do funkcie R, ktorá spracuje SQL príkaz a vráti výsledok do príkazu datatable, ktorý zobrazuje odkazy vyplývajúce z tohto uzla...

library(shiny)
library(networkD3)
library(DT)
library(sqldf)
library(htmlwidgets)

URL <- paste0('https://cdn.rawgit.com/christophergandrud/networkD3/',
              'master/JSONdata/energy.json')
energy <- jsonlite::fromJSON(URL)

energy$links$name <- energy$nodes$name[energy$links$source + 1]
df <- energy$links

funct <-
  function (n) {
    isp <- sprintf("Select * From df Where df.name='%s';", n)
    isd <- sqldf::sqldf(isp)
    return(isd)
  }

ui <- shinyUI(fluidPage(
  fluidRow(
    column(4, sankeyNetworkOutput("sankey")),
    column(4, DT::dataTableOutput("table"))
  )
))

server <- shinyServer(function(input, output, session) { 
  session$onSessionEnded(stopApp)
  output$sankey <- renderSankeyNetwork({
    san <- 
      sankeyNetwork(Links = energy$links, Nodes = energy$nodes, Source = 'source',
                    Target = 'target', Value = 'value', NodeID = 'name',
                    units = 'TWh', fontSize = 12, nodeWidth = 30)

    clickFun <- 
      'function() { 
          d3.selectAll(".node").on("mousedown.drag", null);
          d3.selectAll(".node").on("click",function(d) { Shiny.onInputChange("id", d.name); });
        }'

    onRender(san, clickFun)
  })

  output$table <- DT::renderDataTable(DT::datatable(funct(input$id)))
})

shinyApp(ui = ui, server = server)