Set node direction on graphviz
Asked Answered
S

2

5

Suppose this code using neato:

graph sample {
  layout=neato
  overlap=false
  splines=true
  tailclip=false
  headclip=false
  A -- I
  A -- J
  A -- B
  A -- H
  A -- E
  A -- K
  B -- D
  B -- C
  B -- L
  C -- M
  C -- N
  C -- O
  D -- P
  D -- Q
  E -- R
  F -- A
  G -- F
  H -- J
}

This gives us this diagram:

neato diagram

What I need is to place a node X, always fixed in a position south from his parent node. i.e. If I put another relation A -- X, X should be always placed south from A. And I don't really care where everything else ends up.

I've looked into the pos attribute, but it doesn't seems to be the solution since X is not really in a fixed position, but on a position relative to his relation.

Also tailport and headport, but they only define from where the edge will come out/in, but don't really affect the direction of the node.

Update

An additional image to make things clearer:

x should be south from his parent

I don't require neato, but I don't want the graph to look like a UD or LR dot tree, I don't want it to be linearly ordered. circo, fdp, sfdp, twopi are alright too.

Soup answered 10/1, 2012 at 19:43 Comment(0)
M
4

The neato program supports multiple modes, one of which can probably give you what you want. In particular, if you set mode=ipsep, you can specify dot-like constraints that are honored during the layout. For example, I take your graph and use the graph attributes

mode=ipsep
diredgeconstraints=true
levelsgap=0.5

The first turns on ipsep mode, the second tells the model to support directed edges as in dot, and the last specifies how strong the separation should be. I then set the edge dir attribute to none

edge[dir=none]

and add an edge A -- X [dir=1]

The dir=1 indicates this edge should induce a directional constraint. If I then run neato, I get the appended picture.

neato layout

The Graphviz attribute documentation http://www.graphviz.org/content/attrs provides more information about these attributes.

Mateo answered 17/1, 2012 at 19:57 Comment(2)
Thank you. With your directions I did ended up with the X node going exactly like your graph. But while is pointing to the south, is in a diagonal. I can't seem to make it to go exactly south. Would that be possible?Soup
This wasn't exactly what I wanted, but you can't get a more authoritative answer than this. So there goes the bounty.Soup
E
5

In response to the updated constraints, one solution is to pin A and X, and then lay out the graph around them:

graph sample {
overlap=false;
splines=true;
tailclip=false;
headclip=false;

A [pin=true,pos="0,.2"]
X [pin=true,pos="0,.1"]
A -- I
A -- J
A -- B
A -- H
A -- E
A -- K
B -- D
B -- C
B -- L
C -- M
C -- N
C -- O
D -- P
D -- Q
E -- R
F -- A
G -- F
H -- J
A -- X

graph output

I tried layout with both neato and fdp, and it seems to produce a graph like what you want. Naturally, if you want to impose such a constraint on arbitrary pairs of nodes in the same graph, this solution may not work.

--- Earlier answer ---

If you're committed to using neato, I'm not certain there is a way to solve the problem without modifying the graph in a post-processing step. If neato is just a convenient default, then you should be able to solve your problem by using dot as your layout engine instead, and using "rankdir=UD", plus a couple of additional kludges if X needs to be due south.

In the event that you only need the constraint to apply for a single node X, then putting X and A together in a cluster should do the job:

graph sample {
  rankdir=UD 
  layout=dot
  overlap=false
  // .. as before
  A -- X
  subgraph clusterone {
   style=invisible
   A
   X
  }
}

If you need a strictly-south constraint to apply to arbitrary children of A, then that kind of clustering followed by the trick described in:

How to force all nodes in the same column in graphviz?

might do the trick. The attribute clusterrank=local might also be useful in that case, but I'm not certain. Hope this helps.

Embosser answered 12/1, 2012 at 23:54 Comment(1)
neato is not a requirements per se, but I don't want the graph to look ordered, that's why I'm using neato instead of dot.Soup
M
4

The neato program supports multiple modes, one of which can probably give you what you want. In particular, if you set mode=ipsep, you can specify dot-like constraints that are honored during the layout. For example, I take your graph and use the graph attributes

mode=ipsep
diredgeconstraints=true
levelsgap=0.5

The first turns on ipsep mode, the second tells the model to support directed edges as in dot, and the last specifies how strong the separation should be. I then set the edge dir attribute to none

edge[dir=none]

and add an edge A -- X [dir=1]

The dir=1 indicates this edge should induce a directional constraint. If I then run neato, I get the appended picture.

neato layout

The Graphviz attribute documentation http://www.graphviz.org/content/attrs provides more information about these attributes.

Mateo answered 17/1, 2012 at 19:57 Comment(2)
Thank you. With your directions I did ended up with the X node going exactly like your graph. But while is pointing to the south, is in a diagonal. I can't seem to make it to go exactly south. Would that be possible?Soup
This wasn't exactly what I wanted, but you can't get a more authoritative answer than this. So there goes the bounty.Soup

© 2022 - 2024 — McMap. All rights reserved.