1

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]?

JasonAizkalns
  • 20,243
  • 8
  • 57
  • 116
fjvost
  • 30
  • 5
  • Yes, what have you tried? You can do something like `MyClickScript <- 'window.open("http://www.google.com");` and then pass `MyClickScript` to `clickAction` -- such as `forceNetwork(..., clickAction = MyClickScript)` – JasonAizkalns Apr 27 '16 at 17:02
  • Thanks, Jason. I was actually trying to see if each node could have its own link address. You see, I have a network of faculty members in our research program, and I was trying to have each node be a faculty member, once clicked on that node/faculty member it would open that particular faculty's website. – fjvost Apr 27 '16 at 17:12
  • Can you provide some sample data? Are the faculty website addresses standardized? Such as `http://www.school.edu/faculty1`, `http://www.school.edu/faculty2`, etc. – JasonAizkalns Apr 27 '16 at 17:14
  • For example, consider this: `MyClickScript <- 'var link = "http://www." + d.name + ".com"; alert(link);'` Using the example data: `forceNetwork(Links = MisLinks, Nodes = MisNodes, Source = "source", Target = "target", Value = "value", NodeID = "name", Group = "group", opacity = 0.8, clickAction = MyClickScript)` – JasonAizkalns Apr 27 '16 at 17:30
  • no, their addresses are not standardized. I have a column in my "Links" data frame that has the URL for each prof. I was thinking using something like: 'window.open(Links$URL)' – fjvost Apr 27 '16 at 18:07
  • that of course doesn't work... – fjvost Apr 27 '16 at 18:09
  • Look at the documents for d3js..there is an exact block of how this works...then generate the data structure including the link..and in the js you'll need to include the d.link information into the node append – Carl Boneri Apr 28 '16 at 00:03
  • 1
    Also...alert won't open a tab..just an alert...you want `` – Carl Boneri Apr 28 '16 at 00:05
  • @CarlBoneri I think this may be more involved -- there is not a straight forward way (?) to add a link/URL property, `d.link`, to the nodes? Hi-jacking another property in the [example shown here](http://stackoverflow.com/a/36137753/2572423) could be a possibility, but feels like a hack and could have unintended consequences. – JasonAizkalns Apr 28 '16 at 13:57
  • 1
    My suggestion would be to put it in a tool tip. The node is svg which you don't want to wrap around an HTML tag. This is the concept behind how I do it. http://bl.ocks.org/d3noob/c37cb8e630aaef7df30d – Carl Boneri Apr 28 '16 at 16:05

1 Answers1

5

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
timelyportfolio
  • 6,479
  • 30
  • 33
  • @ timelyportfolio your answer is extremely useful for my work on networkD3. Could you also please point me to documentation or reference for all the other options I can do with `fn$x` like jsHooks, etc? I would be indebted. – Syamanthaka Aug 19 '16 at 11:44
  • do you have anything particular in mind? In general, `htmlwidgets::onRender` is my primary choice for manipulating post-render with JavaScript. In the above case though we need additional data from R, so `onRender` will not suffice. Since an `htmlwidget` is a `list` we can change it after creation. – timelyportfolio Aug 20 '16 at 11:08
  • So I was looking at this [link](http://www.coppelia.io/2014/07/an-a-to-z-of-extra-features-for-the-d3-force-layout/) to add some extras to the properties of the nodes or the links for example. And I see i get a fn$jsHooks when I list all the options under fn in Rstudio. I was thinking maybe there is a way to write some custom javascript, into these jsHooks. Also, what are all the possible things that can be modified with fn$x? Where can I find documentation on that? (My searches did not yield satisfactory results). Thanks in advance for the pointers. – Syamanthaka Aug 22 '16 at 05:41
  • 1
    I will try to write up a post on this, but for now see if `?htmlwidgets::onRender` and these [lines](https://github.com/ramnathv/htmlwidgets/blob/master/R/htmlwidgets.R#L71-L155) + [this line](https://github.com/ramnathv/htmlwidgets/blob/master/inst/www/htmlwidgets.js#L626) offers any insight. In terms of `fn$x`, these are usually the data and config options passed as arguments to the htmlwidget function. `networkD3` unfortunately does not pass the whole data.frame, so in the example I added data from R, so it would be available in JavaScript as `d.hyperlink`. – timelyportfolio Aug 26 '16 at 11:09
  • Thank you. :) look forward to your post. I'm trying to add post render interactivity to get the best benefits from the visualization. – Syamanthaka Aug 27 '16 at 08:01
  • anything specific that you are trying to achieve? – timelyportfolio Aug 27 '16 at 12:37
  • A few things actually.. My network plot is a representation of protein mutations, and how they have progressed - with more order combination mutations from the previous. So what I would like to achieve would be 1. Include a search, where one can search for a specific node rather than having to click through the nodes. Pointers for this were available [here](http://www.coppelia.io/2014/07/an-a-to-z-of-extra-features-for-the-d3-force-layout/) but then I need to somehow include the html for this in a generated html (after saveNetwork) – Syamanthaka Aug 28 '16 at 13:35
  • 2. Make html tables with info of the nodes and their properties - again edit the saveNetwork generated html maybe. Or probably pass back the values to R and take it forward from there. This would be like the OP has tried to do in their URL links. Have you done something similar? Where can I read about your blogs on these? – Syamanthaka Aug 28 '16 at 13:37