linking a node in networkD3 to a website using clickAction = NULL - r

Is there a way to use a node as a link to an external website using the function forceNetwork() in the networkD3 package in r? I was thinking maybe modifying the clickAction?
Example data:
library(networkD3)
data(MisLinks)
data(MisNodes)
# Create a random URL in the nodes dataset
MisNodes$URL <- paste0("http://www.RANDOMLINK_", sample(1:100, NROW(MisNodes)), ".com")
head(MisNodes)
MyClickScript <- 'alert(d.index)'
forceNetwork(Links = MisLinks, Nodes = MisNodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
Group = "group", opacity = 0.8,
clickAction = MyClickScript)
Desired outcome: When a user clicks on a node, a new tab will open (e.g. window.open) pointing to the associated URL for the node - How can I get clickAction to point to MisNodes$URL[d.index]?

networkD3 design does not make this easy. Here is one way to answer. I'll try to comment inline to explain what we are doing in each step.
library(networkD3)
# example from ?forceNetwork
data(MisLinks)
data(MisNodes)
# Create graph
fn <- forceNetwork(
Links = MisLinks, Nodes = MisNodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
Group = "group", opacity = 0.4, zoom = TRUE
)
# let's look at our forceNetwork
# nodes are provided to JavaScript
# in a nodes data.frame
str(fn$x$nodes)
# make up some links to demonstrate
# how we can add them to our nodes df
fn$x$nodes$hyperlink <- paste0(
'http://en.wikipedia.org/wiki/Special:Search?search=',
MisNodes$name
)
# then with our hyperlinks in our data
# we can define a click action to open
# the hyperlink for each node in a new window
fn$x$options$clickAction = 'window.open(d.hyperlink)'
fn

Related

How to add title to a networkD3 visualisation when saving as a web page?

I have created a interactive visualisation using the following code:
library(networkD3)
nodes = data.frame("name" = c("node1", "node2","node3", "node4", "node5", "node6", "node7"))
links = as.data.frame(matrix(c(
0,1,7937,
0,2,6990,
0,3,2483,
1,4,2120,
2,4,666,
3,4,282,
1,5,4583,
2,5,5657,
3,5,731,
1,6,1234,
2,6,756,
3,6,1470), byrow = TRUE, ncol = 3))
names(links) = c("source", "target", "value")
sankey <- sankeyNetwork(Links = links, Nodes = nodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
fontSize= 12, nodeWidth = 15)'
This is my first time using the networkD3 package (or any interactive package for that matter) and from playing around I found that to keep it interactive it has to be published as a webpage (or is there another way??) but looking through the documentation for the package I can't see a way to add a title or a caption / comments. I want to share this piece of work round so need to explain what each level means on the published webpage ideally
There is no feature built-in to networkD3 to add titles or captions, but you can use functions in the htmlwidgets package to prepend or append content to an htmlwidget. There are numerous options, but for example....
library(htmlwidgets)
library(htmltools)
sankey <- htmlwidgets::prependContent(sankey, htmltools::tags$h1("Title"))
sankey <- htmlwidgets::appendContent(sankey, htmltools::tags$p("Caption"))
Responding to the comment, "I ended up using this to add a title, but it keeps pushing my viz down and cutting the bottom off. This stays off even when saving as a webpage. Is there anyway I can stop this from happening?"
I tried the suggested reply of adding sankey$sizingPolicy$viewer$fill <- FALSE, however, it made my sankey smaller than I wanted it. I found out that you can adjust the width and height of the Sankey prior to adding the HTML widget by adding width=(desired width) and height=(desired height) and this creates the space to then add in the title and the comment, as suggested by CJ Yetman.
library(networkD3)
library(htmlwidgets)
library(htmltools)
nodes = data.frame("name" = c("node1", "node2","node3", "node4", "node5", "node6", "node7"))
links = as.data.frame(matrix(c(
0,1,7937,
0,2,6990,
0,3,2483,
1,4,2120,
2,4,666,
3,4,282,
1,5,4583,
2,5,5657,
3,5,731,
1,6,1234,
2,6,756,
3,6,1470), byrow = TRUE, ncol = 3))
names(links) = c("source", "target", "value")
sankey <- sankeyNetwork(Links = links, Nodes = nodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
fontSize= 12, nodeWidth = 15,
width= 900, height=600)
sankey <- htmlwidgets::prependContent(sankey, htmltools::tags$h1("Title"))
sankey <- htmlwidgets::appendContent(sankey, htmltools::tags$p("Caption"))
sankey

Is it possible to show node id always with forcenetwork? (R)

I am using the forceNetwork function within the networkd3 package and can't get the node ID name to always show. I can see it only if I hover the mouse over it. Is there any way to make it always show?
I am using this code from the user guide:
# Load data
data(MisLinks)
data(MisNodes)
# Plot
forceNetwork(Links = MisLinks, Nodes = MisNodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
Group = "group", opacity = 0.8)
edit: It works really fine with #CJ Yetman.
One more question...
Is it possible to put weights in the edges and show it?
use the opacityNoHover = 1 argument...
library(networkD3)
data(MisLinks)
data(MisNodes)
# Plot
forceNetwork(Links = MisLinks, Nodes = MisNodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
Group = "group", opacity = 0.8,
opacityNoHover = 1)
The Value column in your links data frame determines the weight.

Saving networkD3 Sankey diagram using code only

I've created a Sankey diagram in R, using the networkD3 package, that I'd like to save as a static image, using code instead of clicking on 'Export' --> 'Save as Image...'.
The current code I've tried (using this Sankey diagram as an example) is:
library(networkD3)
URL <- paste0(
"https://cdn.rawgit.com/christophergandrud/networkD3/",
"master/JSONdata/energy.json")
Energy <- jsonlite::fromJSON(URL)
# Plot
jpeg( filename = "Sankey.jpg", width = 4000, height = 4000)
sankeyNetwork(Links = Energy$links, Nodes = Energy$nodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
units = "TWh", fontSize = 12, nodeWidth = 30)
dev.off()
All I'm getting though is a blank white box when I open the image though.
Simplest working solution I've found so far is:
Install PhantomJS. For example using Homebrew for OSX - brew install phantomjs
Install rbokeh - install.packages("rbokeh")
Then:
library(rbokeh)
sn <- sankeyNetwork(Links = Energy$links, Nodes = Energy$nodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
units = "TWh", fontSize = 12, nodeWidth = 30)
widget2png(sn, "sankey.png")
The result doesn't look great, but this might serve as a starting point for research and improvements.
EDIT: here's another potential solution using the webshot package.

R networkD3 change node IMG

I would like to replace the basic node image to a custom jpg in networkD3 package in R.
Here is an example:
library(networkD3)
# Load data
data(MisLinks)
data(MisNodes)
# Plot
forceNetwork(Links = MisLinks, Nodes = MisNodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
Group = "group", opacity = 0.8)
So I would like to create a node like this:
Instead of this:
Is it possible?
I would like to replace the basic node image to a custom jpg in
networkD3 package in R. [...] For me it is also good with any other
interacive R network package
For example, you could do
library(networkD3)
library(visNetwork)
library(dplyr)
data(MisLinks)
data(MisNodes)
visNetwork(
MisNodes %>%
rename("label"=name) %>%
mutate(id = seq_len(nrow(MisNodes))-1),
MisLinks %>%
rename("from"=source, "to"=target)
) %>%
visNodes(
shape = "image",
image = "http://cdn0.iconfinder.com/data/icons/octicons/1024/mark-github-128.png"
)
giving you

Sankey Diagram with networkD3 package will not plot

I am using the sankeyNetwork function in the networkD3 package in R using as an example the code found here. However, all I get is a blank screen. The diagram is supposed to show the flow of infections between age groups (by gender). My code is as below:
library(RCurl)
library(networkD3)
edges <- read.csv(curl("https://raw.githubusercontent.com/kilimba/data/master/infection_flows.csv"),stringsAsFactors = FALSE )
nodes = data.frame(ID = unique(c(edges$Source, edges$Target)))
nodes$indx =0
for (i in 1:nrow(nodes)){
nodes[i,]["indx"] = i - 1
}
edges2 <- merge(edges,nodes,by.x = "Source",by.y = "ID")
edges2$Source <-NULL
names(edges2) <- c("target","value","source")
edges2 <- merge(edges2,nodes,by.x = "target",by.y = "ID")
edges2$target <- NULL
names(edges2) <- c("value","source","target")
nodes$indx <- NULL
# Plot
sankeyNetwork(Links = edges2, Nodes = nodes,
Source = "source", Target = "target",
Value = "value", NodeID = "ID",
width = 700, fontsize = 12, nodeWidth = 30)
Are you sure there are no errors printed in your R console?
This works for me with two small modifications:
Load the curl package as well at the beginning
library("curl")
The fontsize parameter apparently does not work and should be removed.
# Plot
sankeyNetwork(Links = edges2, Nodes = nodes,
Source = "source", Target = "target",
Value = "value", NodeID = "ID",
width = 700, #fontsize = 12,
nodeWidth = 30)
Adjusting fontsize does work, but your argument is missing a capitalization: fontSize
sankeyNetwork(Links = edges2, Nodes = nodes,
Source = "source", Target = "target",
Value = "value", NodeID = "ID",
width = 700, fontSize = 12,
nodeWidth = 30)
you do not need RCurl, read.csv is able to read directly from a URL
it's probably safer to use the stringsAsFactors = FALSE option when creating the nodes data.frame
as others have pointed out, you must make sure that the source and target variables in the links data are numeric, and that they are zero-indexed
as others have pointed out, the font size parameter is properly named fontSize
I have provided a more direct way of creating the links data with numeric indexes of the nodes in the nodes data.frame
library(networkD3)
edges <- read.csv("https://raw.githubusercontent.com/kilimba/data/master/infection_flows.csv",stringsAsFactors = FALSE)
nodes = data.frame(ID = unique(c(edges$Source, edges$Target)), stringsAsFactors = FALSE)
edges$Source <- match(edges$Source, nodes$ID) - 1
edges$Target <- match(edges$Target, nodes$ID) - 1
sankeyNetwork(Links = edges, Nodes = nodes,
Source = "Source", Target = "Target",
Value = "Value", NodeID = "ID",
width = 700, fontSize = 12, nodeWidth = 30)
I solved it for me by making sure that source, target and values were all numeric.
For example:
Energy$links$value <- as.numeric(Energy$links$value)

Resources