R networkD3: click action to show information from node data frame

。_饼干妹妹 提交于 2019-12-10 23:42:13

问题


I have this code:

library(networkD3)

# Load data
data(MisLinks)
data(MisNodes)

new.nodes <- MisNodes
new.nodes$var1 <- runif(nrow(MisNodes),1,2)
new.nodes$var2 <- runif(nrow(MisNodes),1,2)

# Some script to show the node index in the new.nodes data frame
script <- 'alert("row: " + (d.index + 1));'

# Plot
forceNetwork(Links = MisLinks, Nodes = new.nodes,
             Source = "source", Target = "target",
             Value = "value", NodeID = "name",
             Group = "group", opacity = 0.8,
             clickAction = script)

I figured out to get the row number of the node data frame by asking for d.index + 1. However I want to show a table containing all the node info, like so (perhaps nicer formatted):

    name group size     var1     var2
1 Myriel     1   15 1.501311 1.053062

This would require the JavaScript to have access to the node data frame, as I only have little knowledge of JavaScript I cannot figure out how to request this data.


回答1:


The reason this happens is that the forceNetwork function strips out all the unnecessary variables/columns in the data frame that it passes to JavaScript, which is advantageous usually, but not in this case. You can work around it by saving the htmlwidget object that forceNetwork creates, then add back in the variable you need to access, and then 'print'/display it.

library(networkD3)

data(MisLinks)
data(MisNodes)

MisNodes$var1 <- runif(nrow(MisNodes),1,2)

script <- 'alert("var1: " + (d.var1));'

fn <- forceNetwork(Links = MisLinks, Nodes = new.nodes, Source = "source", 
                   Target = "target", Value = "value", NodeID = "name", 
                   Group = "group", opacity = 0.8, clickAction = script)

fn$x$nodes$var1 <- MisNodes$var1

fn


This could be done with/for multiple variables as well, for example...

library(networkD3)

data(MisLinks)
data(MisNodes)

MisNodes$var1 <- runif(nrow(MisNodes),1,2)
MisNodes$var2 <- runif(nrow(MisNodes),1,2)

script <- 'alert("var1: " + d.var1 + "\\n" + "var2: " + d.var2);'

fn <- forceNetwork(Links = MisLinks, Nodes = new.nodes, Source = "source", 
                   Target = "target", Value = "value", NodeID = "name", 
                   Group = "group", opacity = 0.8, clickAction = script)

fn$x$nodes$var1 <- MisNodes$var1
fn$x$nodes$var2 <- MisNodes$var2

fn



回答2:


Unfortunately, I think it is not easily done if not impossible. It appears that only the used the arguments of forceNetwork relating to the nodes are initialized in the underlying code:

Consider for example:

script <- 'alert("row: "     + (d.index + 1) + 
                 ", name: "  + d.name + 
                 ", group: " + d.group + 
                 ", size: "  + d.nodesize + 
                 ", var1: "  + d.var1)'

# Plot
d3 <- forceNetwork(Links = MisLinks, Nodes = new.nodes,
             Source = "source", Target = "target",
             Value = "value", NodeID = "name", 
             Nodesize = "size",
             Group = "group", opacity = 0.8,
             clickAction = script)

print(d3)

As you can see when clicking a node below, the var1 is undefined. Note I added the Nodesize argument to the function call which now can be accessed through the script d.nodesize (and not d.size). The group variable and argument, in this case, are named identically so the distinction is lost here. However, the NodeID is apparently accessed by the stated name which I find inconsistent.

You can see the generated source by saving:

saveNetwork(d3, file = "test.html")

You can notice by looking at it, that the values you intend to output are not stored in the file.

Edit:

By your own suggestion, this comes somewhat close as a workaround:

new.nodes$newname  <- with(new.nodes, paste(", name: ", name, ", group: ", group, 
                                ", size: ", size, ", var1: ", var1,
                                ", var2: ", var2))

newscript <- 'alert("row: " + (d.index + 1) + d.name)'

forceNetwork(Links = MisLinks, Nodes = new.nodes,
             Source = "source", Target = "target",
             Value = "value", NodeID = "newname", Nodesize = "size",
             Group = "group", opacity = 0.8, opacityNoHover = 0,
             clickAction = newscript)

So, it is just a matter of formatting the string as you'd like it displayed. The downside is that name/NodeIDs are very long. And as you can see, the NodeID is just always called name on the JS side.



来源:https://stackoverflow.com/questions/52477969/r-networkd3-click-action-to-show-information-from-node-data-frame

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!