问题
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