Graphviz图例/节点关键字

8
我正在尝试在Graphviz中创建一个包含节点和边的图例/键。虽然我已经阅读了这篇文章,但HTML表格似乎无法实现我想要的效果。
现在,我正在使用以下代码:
digraph G {
fontname="Helvetica";
labelloc=t;
rankdir=LR;
label="Course Graph";

node[style=filled, fontname="Helvetica", colorscheme=greens3, color=1];

subgraph cluster_key {
    rank=min;

    label="Key";
    rankdir=LR;

    kc1[label="Course", peripheries=2, color=2];
    k1[shape=plaintext, style=solid, label="Required Course"]
    prereq[label="Course 1"];
    kc2[label="Course 2"];
    prereq->kc2;
    k2[shape=plaintext, style=solid, label="Course 1 is a prerequisite for Course 2"]
    coreq1[label="Course 1"];
    coreq2[label="Course 2"];
    coreq1->coreq2[dir=both];
    k3[shape=plaintext, style=solid, label="Course 1 and Course 2 are corequisite"]

    or[style="dashed", color="black", shape="diamond", label="OR"];
    or1[label="Course 1"];
    or1 -> or[style="dashed", dir="none"];
    or2[label="Course 2"];
    or2 -> or[style="dashed", dir="none"];
    kc3[label="Course 3"]
    or->kc3;
    k4[shape=plaintext, style=solid, label="You must take either Course 1 OR\nCourse 2 before taking Course 3"]
    { rank=min;k1 k2 k3 k4 }
}

c3[color=3, peripheries=2];
c4[color=3, peripheries=2];

c1->c2[dir=both];
c2->c3;

c4_reqs[style="dashed", color="black", shape="diamond", label="OR"];
c4_reqs->c4;
c2->c4_reqs[style="dashed", dir="none"];
c5->c4_reqs[style="dashed", dir="none"];

}

这段代码的结果是:

The result of this code is

但我希望得到更像这样的结果 - 最好尺寸更小:

ebut I would like something more like

2个回答

10

你并不算离谱。在进行了一些微小调整后,我得到了以下结果:

enter image description here

我所做的最重要的改变是使用rank=source而不是rank=min来正确对齐节点。

为了修复文本对齐问题,我使用了\r将文本向右对齐(\l 向左对齐),并给所有纯文本节点设置了相同的宽度。

整个代码如下(我在进行更改的地方添加了一些注释):

digraph G {
    fontname="Helvetica";
    labelloc=t;
    rankdir=LR;
    label="Course Graph";

    node[style=filled, fontname="Helvetica", colorscheme=greens3, color=1];

    subgraph cluster_key {
        //rank=min; /* this doesn't really do anything for you */

        label="Key";
        //rankdir=LR; /* this is also not needed*/

        kc1[label="Course", peripheries=2, color=2];
        k1[shape=plaintext, style=solid, label="Required Course\r", width=3.5] // Add fixed width so all nodes line up

        prereq[label="Course 1"];
        kc2[label="Course 2"];
        prereq->kc2;
        k2[shape=plaintext, style=solid, label="Course 1 is a prerequisite for Course 2\r", width=3.5]  // Add fixed width

        coreq1[label="Course 1"];
        coreq2[label="Course 2"];
        coreq1->coreq2[dir=both];
        k3[shape=plaintext, style=solid, label="Course 1 and Course 2 are corequisite\r", width=3.5]    // Add fixed width

        or[style="dashed", color="black", shape="diamond", label="OR"];
        or1[label="Course 1"];
        or1 -> or[style="dashed", dir="none"];
        or2[label="Course 2"];
        or2 -> or[style="dashed", dir="none"];
        kc3[label="Course 3"]
        or->kc3;
        k4[shape=plaintext, style=solid, label="You must take either Course 1 OR\rCourse 2 before taking Course 3\r", width=3.5] // Add fixed width

        { rank=source;k1 k2 k3 k4 } // Use "source in stead of min
    }

    c3[color=3, peripheries=2];
    c4[color=3, peripheries=2];

    c1->c2[dir=both];
    c2->c3;

    c4_reqs[style="dashed", color="black", shape="diamond", label="OR"];
    c4_reqs->c4;
    c2->c4_reqs[style="dashed", dir="none"];
    c5->c4_reqs[style="dashed", dir="none"];

}

顺便提一下,通过将所有纯文本节点放在一起可以使代码更加清晰,这样不必多次声明属性。另外,此举还有一个好处是节点和排名属性不会在代码中被拆分成不同的部分:

    { 
        rank=source
        node [shape=plaintext, style=solid, width=3.5]

        k1 [label="Required Course\r"]
        k2 [label="Course 1 is a prerequisite for Course 2\r"]
        k3 [label="Course 1 and Course 2 are corequisite\r"]
        k4 [label="You must take either Course 1 OR\rCourse 2 before taking Course 3\r"]
    }

0

这里有一种更小、更简单的方法来构建这个图例/键:

  1. 将整个图例放在一个HTML表格中,并将其作为聚类标签
  2. 使用labelloclabeljust来定位标签/图例/表格
  3. 将左侧的每个图形都转换成独立的图像,然后使用IMG属性将它们包含进去

如下所示:

 digraph G {
    graph [fontname="Helvetica"  labelloc=t labeljust=c  rankdir=LR]
    graph [label="Course Graph"]
    subgraph clusterAll{
      graph [peripheries=0  labelloc=b labeljust=r  rankdir=LR]
      node[shape=none]
      graph[label=<
        <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
          <TR><TD ALIGN="LEFT" >Required Course</TD>
              <TD ALIGN="LEFT"><IMG SRC="courseKey1a.png"/></TD></TR>
          <TR><TD ALIGN="LEFT" >Course 1 is a prerequisite for Course 2</TD>
              <TD  ALIGN="LEFT"><IMG SRC="courseKey1b.png"/></TD></TR>
          <TR><TD  ALIGN="LEFT">Course 1 and Course 2 are corequisite</TD>
              <TD  ALIGN="LEFT"><IMG SRC="courseKey1c.png"/></TD></TR>
          <TR><TD  ALIGN="LEFT">You must take either Course 1<BR  ALIGN="LEFT"/>OR<BR  ALIGN="LEFT"/>Course 2 before taking Course 3</TD>
              <TD  ALIGN="LEFT"><IMG SRC="courseKey1d.png"/></TD></TR>
        </TABLE>
     >];

    node[shape=oval style=filled, fontname="Helvetica", colorscheme=greens3, color=1];

    c3[color=3, peripheries=2];
    c4[color=3, peripheries=2];

    c1->c2[dir=both];
    c2->c3;

    c4_reqs[style="dashed", color="black", shape="diamond", label="OR"];
    c4_reqs->c4;
    c2->c4_reqs[style="dashed", dir="none"];
    c5->c4_reqs[style="dashed", dir="none"];

    lots -> more -> of -> this -> that -> and -> the -> other
  }
}

生成了这个: {{link1:在此输入图片描述}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接