How to place nodes on the same rank in native DiagrammeR?

111 Views Asked by At

Q: In DiagrammeR native syntax, how does one force certain nodes to be on the same rank?

E.g., below I was able to force nodes 4, 5, 6, 7 onto the same rank by creating an invisible node 2, with invisible edges in and out of it. But this is just a hack. And the resulting diagram is a little off balance. There must be a better way to do this, right?

library(DiagrammeR)

g <- create_graph(attr_theme="tb")
g <- add_node(g) # node 1
g <- add_node(g, from=1, node_aes = node_aes(style = "invisible"), edge_aes = edge_aes(style = "invisible", arrowhead = "none")) # node 2, my invisible node
g <- add_node(g, from=1, edge_aes = edge_aes(style = "solid")) # node 3
g <- add_node(g, from=2, edge_aes = edge_aes(style = "invisible", arrowhead = "none")) # node 4
g <- add_node(g, from=2, edge_aes = edge_aes(style = "invisible", arrowhead = "none")) # node 5
g <- add_edge(g, from=1,to=4, edge_aes = edge_aes(style = "solid"))
g <- add_edge(g, from=1,to=5, edge_aes = edge_aes(style = "solid"))
g <- add_node(g, from=3) # node 6
g <- add_node(g, from=3) # node 7
render_graph(g)

enter image description here

1

There are 1 best solutions below

0
user2554330 On

I think the answer here is that if you want that level of control of positioning, you have to do all the positioning by yourself. For example,

library(DiagrammeR)

g <- create_graph()
g <- add_node(g, node_aes = node_aes(x = 0, y = 3)) # node 1
g <- add_node(g, from=1, node_aes = node_aes(x = 0.75, y = 2)) # node 2 (was 3)
g <- add_node(g, from=1, node_aes = node_aes(x = -1.5, y = 1)) # node 3 (was 4)
g <- add_node(g, from=1, node_aes = node_aes(x = -0.5, y = 1)) # node 4 (was 5)
g <- add_node(g, from=2, node_aes = node_aes(x = 0.5, y = 1)) # node 5 (was 6)
g <- add_node(g, from=2, node_aes = node_aes(x = 1.5, y = 1)) # node 6 (was 7)
render_graph(g, width = 400)

Created on 2023-09-03 with reprex v2.0.2

There are other graph packages (e.g. igraph, Rgraphviz) that have functions which do layouts and output the coordinates; perhaps one of those is more flexible than DiagrammeR and would allow you to do automatic placement subject to some constraints. You might even be able to use a different package for the layout, then use the same layout values in DiagrammeR.