0

I am new to using the package and I am trying to understand how to adjust the layout manually. As an example I have the following layout

library(networkD3)
library(tidyverse)
library(data.tree)
library(htmlwidgets)   
    
set.seed(1)
example = data.frame(lvl1 = rep("A", 5), lvl2 = sample(c("D" ,"B", "C"), 5, replace = T), value = sample(c(1,2,3), 5, replace = T))
> example
  lvl1 lvl2 value
1    A    D     3
2    A    C     3
3    A    D     2
4    A    B     2
5    A    D     3


Data_tree <- example %>% 
  unite(col="pathString",lvl1,lvl2,sep="-",remove=FALSE, na.rm = T) %>%
  as.Node(pathDelimiter = "-")


diagonalNetwork(ToListExplicit(Data_tree, unname = TRUE ),
                fontSize = 9,
                linkColour = "#ccc",
                nodeColour = "#fff",
                nodeStroke = "orange",
                textColour = "#000000")

What I would like to do is to somehow map the value column into the size of the node. Similarly to how aesthetic mappings work in ggplot2. So ideally for each level I would like the nodesize to be proportional to the total value for this breakdown.

So for example lvl1 has only one possible value A so the node should get 100% of the chosen nodesize. On the other hand, lvl2 has 3 values, so for D I would like it to have (3+2+3)/13 % of the full node size, C should have 3/13 % of the nodesize and B should have 2/13 % of the nodesize.

This is just an example and I can do any manipulation needed, but is this even possible for these types of charts?

CJ Yetman
  • 8,373
  • 2
  • 24
  • 56
User2321
  • 2,952
  • 23
  • 46

1 Answers1

2

This is not an intended use of diagonalNetwork, so expect that there will be complications (e.g. when you hover over the nodes with the mouse cursor, the default behavior will reset the node size back to the default size), however...

# add a value to the root node
data_list <- ToListExplicit(Data_tree, unname = TRUE)
data_list$value <- 5

# save the output of diagonalNetwork as an object
d3net <- diagonalNetwork(data_list,
                         fontSize = 9,
                         linkColour = "#ccc",
                         nodeColour = "#fff",
                         nodeStroke = "orange",
                         textColour = "#000000")

# write some JavaScript to set the circles' radii to the data's value
node_size_js <-
  '
    function(el) { 
      d3.select(el)
        .selectAll(".node")
        .selectAll("circle")
        .attr("r", d => d.data.value * 5);
    }
  '

# use onRender to run the JS when it loads
htmlwidgets::onRender(d3net, node_size_js)

enter image description here

CJ Yetman
  • 8,373
  • 2
  • 24
  • 56
  • This is brilliant thank you! You mentioned that this is not intended behavior, would you recommend some other chart perhaps? – User2321 Sep 22 '20 at 17:10
  • No, just want to be clear that the diagonal networks were designed to use the size of the node for highlighting a node when it’s hovered over, so overriding the node size with some other purpose/meaning is working a bit against the grain. The force network plots were designed to use node size as an indication of some value, but that’s not nearly equivalent to a “diagonal” hierarchical network. – CJ Yetman Sep 22 '20 at 21:28