NetworkD3 Sankey Plot in R: How to switch text labels from the right to the left of the inner nodes only

拜拜、爱过 提交于 2021-02-08 06:52:12

问题


I created a Sankey Plot using the NetworkD3 R package. Below is an example of the output:

Sankey Plot Example

I used the following code for the Sankey:

sankeyNetwork(Links = SankeyLinks, Nodes = SankeyNodes, Source = "source",
          Target = "target", Value = "value", NodeID = "names", 
          fontSize = 14, nodeWidth = 20,nodePadding = 15,NodeGroup = "nodeColor",
          colourScale = JS(ColourScale), LinkGroup = "linkColor",
          sinksRight = T)

The network generates text labels to the right of the middle nodes, which crowds the links to the leaf nodes. I would like to switch the text to the left side of the inner nodes without changing the text placement on the beginning node and leaf nodes (right and left, respectively).

I have researched a similar question: Place text values to right of sankey diagram

Here is another: How to place node title to the left or right of the node in d3 Sankey graph?

The answers are coded in D3.js, which I have not yet learned and don't know how to implement into my R code, or they are moving text labels to the right of the nodes.

Any suggestions that I can implement into R to move text of the inner nodes to the left would be greatly appreciated!

Edit: Using the example code given in the comment, when I use the set.seed it doesn't create inner nodes, so maybe that is the issue? Output Example


回答1:


Starting from @timelyportfolio's answer, you can modify it to filter to any subset of nodes before applying the formatting...

library(networkD3)
library(htmlwidgets)

links <- data.frame(
  src = c(0,0,1,1,2,2,3,3,4,4,5,5,6),
  target = c(3,6,4,5,5,6,7,9,8,9,7,10,7),
  value = 1
)

nodes <- data.frame(name = c(1, 2, 3,
                             "Middle 1", "Middle 2", "Middle 3", "Middle 4", 
                             4,5,6,7))

sn <- sankeyNetwork(
  Links=links, Nodes=nodes, Source='src', Target='target',
  Value='value', NodeID='name', fontSize=16,
  width=600, height=300,
  margin = list("left"=100)
)

sn

sn <- onRender(
  sn,
  '
  function(el,x){
  // select all our node text
  d3.select(el)
  .selectAll(".node text")
  .filter(function(d) { return d.name.startsWith("Middle"); })
  .attr("x", x.options.nodeWidth - 16)
  .attr("text-anchor", "end");
  }
  '
)

sn$jsHooks$render[[1]]
# $code
# [1] "\n  function(el,x){\n  // select all our node text\n  d3.select(el)\n  .selectAll(\".node text\")\n  .filter(function(d) { return d.name.startsWith(\"Middle\"); })\n  .attr(\"x\", x.options.nodeWidth - 16)\n  .attr(\"text-anchor\", \"end\");\n  }\n  "
# 
# $data
# NULL

sn




回答2:


I'll edit only CJ Yetman answer, his answer is awesome and very helpful.

The error was in this line of code in his function

  .filter(function(d) { return d.name.startsWith("Middle"); })

Here's what i did to make it works

onRender(
        sn,
        paste0('
        function(el,x){
        d3.select(el)
        .selectAll(".node text")
        .filter(function(d) { return (["',paste0(Middle,collapse = '","'),'"].indexOf(d.name) > -1);})
        .attr("x", 6 + x.options.nodeWidth)
        .attr("text-anchor", "end");
        }
        ')
)

I didn't use startsWith()function and used indexOf(), and middle is a variable in R which is,

Middle <- c("Middle 1","Middle 2","Middle 3","Middle 4")


来源:https://stackoverflow.com/questions/45466632/networkd3-sankey-plot-in-r-how-to-switch-text-labels-from-the-right-to-the-left

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