较早的graphviz排名
Earlier graphviz rank
在下图中,有没有我可以设置的属性,使 A 和 H 处于同一等级? D和G在同一级别?对于我的用例,每个节点都是一个进程,它将在传入节点进程完成后立即开始,我希望节点的位置指示开始时间。
digraph {
A -> B
B -> C
H -> C
C -> D
D -> E
E -> F
C -> G
G -> F
}
我希望结果如下所示,但由于这些图表是动态生成的,我不想计算我应该将哪些节点标记为相同等级。
digraph {
{ rank="same"; A; H }
{ rank="same"; D; G }
A -> B
B -> C
H -> C
C -> D
D -> E
E -> F
C -> G
G -> F
}
您要查找的内容作为 Flying Logic 软件中的一项设置存在,在那里称为偏差。
不幸的是,在我回答时(2021 年 3 月)这还不存在。请在 Twitter 上查看一位长期维护者对我的问题的回答。 https://twitter.com/Graphviz/status/1128339044826517508?s=20
这个 gvpr (https://www.graphviz.org/pdf/gvpr.1.pdf) 程序似乎正确地添加了带有 rank=same 的子图到请求的“raise”节点。
注意,如果源图有子图(尤其是簇),不要指望它能工作。
BEGIN {
int i, j, n, s=0, changed=0;
int checkedNode[];
int newRank[];
string str1, rankString[], fld[int];
node_t aNode, headNode;
edge_t anEdge;
graph_t aSub;
}
BEG_G{
for (aNode=fstnode($G); aNode; aNode = nxtnode(aNode)){
if (aNode.indegree==0){
newRank[aNode]=1;
}
}
while (1){
for (newRank[aNode]){
for (anEdge = fstout(aNode); anEdge; anEdge = nxtout(anEdge)){
headNode=anEdge.head;
if (newRank[headNode]=="" || (newRank[aNode]+1)>newRank[headNode]){
newRank[headNode]=newRank[aNode]+1;
print ("// rank=", newRank[headNode], " ", headNode.name);
changed++;
}
}
}
if (changed==0)break;
changed=0;
}
for (newRank[aNode]){
rankString[newRank[aNode]]=sprintf("%s%s|",rankString[newRank[aNode]],aNode.name);
}
/* create subgraphs w/ rank=same */
for (rankString[i]){
unset(fld);
n=tokens(rankString[i],fld,"|");
if (n>1){
str1=sprintf("__sub_%d",++s);
aSub=subg($G,str1);
aSub.rank="same";
for (j=0;j<n;j++){
print ("// fld: >", fld[j], "< ", j, " ", n);
aNode=node($G, fld[j]);
aNode=subnode(aSub, aNode);
}
}
}
}
像这样使用命令行:
gvpr -c -f raiseRanks.gvpr yourfile.gv | dot -Tpng >yourfile.png
给予:
// comments deleted
igraph {
subgraph __sub_1 {
graph [rank=same];
A;
H;
}
subgraph __sub_2 {
graph [rank=same];
D;
G;
}
A -> B;
B -> C;
C -> D;
C -> G;
H -> C;
D -> E;
E -> F;
G -> F;
}
在下图中,有没有我可以设置的属性,使 A 和 H 处于同一等级? D和G在同一级别?对于我的用例,每个节点都是一个进程,它将在传入节点进程完成后立即开始,我希望节点的位置指示开始时间。
digraph {
A -> B
B -> C
H -> C
C -> D
D -> E
E -> F
C -> G
G -> F
}
我希望结果如下所示,但由于这些图表是动态生成的,我不想计算我应该将哪些节点标记为相同等级。
digraph {
{ rank="same"; A; H }
{ rank="same"; D; G }
A -> B
B -> C
H -> C
C -> D
D -> E
E -> F
C -> G
G -> F
}
您要查找的内容作为 Flying Logic 软件中的一项设置存在,在那里称为偏差。
不幸的是,在我回答时(2021 年 3 月)这还不存在。请在 Twitter 上查看一位长期维护者对我的问题的回答。 https://twitter.com/Graphviz/status/1128339044826517508?s=20
这个 gvpr (https://www.graphviz.org/pdf/gvpr.1.pdf) 程序似乎正确地添加了带有 rank=same 的子图到请求的“raise”节点。
注意,如果源图有子图(尤其是簇),不要指望它能工作。
BEGIN {
int i, j, n, s=0, changed=0;
int checkedNode[];
int newRank[];
string str1, rankString[], fld[int];
node_t aNode, headNode;
edge_t anEdge;
graph_t aSub;
}
BEG_G{
for (aNode=fstnode($G); aNode; aNode = nxtnode(aNode)){
if (aNode.indegree==0){
newRank[aNode]=1;
}
}
while (1){
for (newRank[aNode]){
for (anEdge = fstout(aNode); anEdge; anEdge = nxtout(anEdge)){
headNode=anEdge.head;
if (newRank[headNode]=="" || (newRank[aNode]+1)>newRank[headNode]){
newRank[headNode]=newRank[aNode]+1;
print ("// rank=", newRank[headNode], " ", headNode.name);
changed++;
}
}
}
if (changed==0)break;
changed=0;
}
for (newRank[aNode]){
rankString[newRank[aNode]]=sprintf("%s%s|",rankString[newRank[aNode]],aNode.name);
}
/* create subgraphs w/ rank=same */
for (rankString[i]){
unset(fld);
n=tokens(rankString[i],fld,"|");
if (n>1){
str1=sprintf("__sub_%d",++s);
aSub=subg($G,str1);
aSub.rank="same";
for (j=0;j<n;j++){
print ("// fld: >", fld[j], "< ", j, " ", n);
aNode=node($G, fld[j]);
aNode=subnode(aSub, aNode);
}
}
}
}
像这样使用命令行:
gvpr -c -f raiseRanks.gvpr yourfile.gv | dot -Tpng >yourfile.png
给予:
// comments deleted
igraph {
subgraph __sub_1 {
graph [rank=same];
A;
H;
}
subgraph __sub_2 {
graph [rank=same];
D;
G;
}
A -> B;
B -> C;
C -> D;
C -> G;
H -> C;
D -> E;
E -> F;
G -> F;
}