在Networkd3 Sankey图表中返回节点名称(R / Shiny)

时间:2018-01-26 00:51:46

标签: javascript r shiny networkd3

我的R / Shiny应用程序中有一个networkd3 Sankey图,它从MySQL连接中提取数据。我试图找到一种方法来“深入”到图表中 - 单击一个节点,这将返回节点的名称。然后我将使用它将另一个查询传递给数据库,该数据库将填充应用程序中的表。

这就是我所拥有的 -

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

这绘制了可以正常工作的图表。

这是我到目前为止所尝试的内容 -
使用R package htmlwidgets,并在我的sankey图表上使用 onRender 运行后续的JS脚本。

JS脚本的占位符:

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

在我的sankey输出中:
onRender(san, clickFun)

这会将链接的值作为警报返回。我尝试使用其他一些示例中提到的".node"d.data.name,但我无法使其工作,也没有弹出警报。

以下是我的问题:
1.如何在鼠标单击时从sankey图中检索节点的名称?
2.假设我已经实现了上述目标,如何在闪亮的应用程序中使用我的JS脚本返回的值?我会将alert()位更改为return(),但我不知道如何在服务器应用程序中使用它。

1 个答案:

答案 0 :(得分:1)

您的点击事件对链接起作用但不在节点上起作用的原因是因为节点也附加了拖动行为。解决这个问题的最简单方法是使拖动行为无效,然后添加点击行为,就像这样......

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)

这里是一个工作示例,其中onclick事件返回所单击节点的名称,然后将其传递给处理SQL命令的R函数,并将结果返回到datatable命令,该命令显示以下链接来自那个节点...

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)