Web编程技术营地
研究、演示、创新

节点类型

撰写时间:2023-07-10

修订时间:2024-02-19

从节点的形状上来分类,节点共分为3种类型:基于多边形的、基于记录的,以及用户自定义的节点。

基于多边形的节点

shape属性指定多边形形状

Graphviz的多边形节点有丰富的节点形状。默认的形状为ellipse,也即椭圆型,我们可以通过设置节点的shape属性来指定更多形状。

digraph { box [shape=box]; }

多边形节点的所有形状

下面列出了所有的多边形形状。

digraph { rankdir=LR; subgraph clusterContainer { labelloc=b node [label=""]; color=invis; fontcolor=white; edge [color=invis]; subgraph cluster_box { box [shape=box]; label="box"; } subgraph cluster_polygon { polygon [shape=polygon sides=8]; label="polygon"; } subgraph cluster_ellipse { ellipse [shape=ellipse]; label="ellipse"; } subgraph cluster_oval { oval [shape=oval]; label="oval"; } subgraph cluster_circle { circle [shape=circle]; label="circle"; } subgraph cluster_point { point [shape=point]; label="point"; } subgraph cluster_egg { egg [shape=egg]; label="egg"; } subgraph cluster_triangle { triangle [shape=triangle]; label="triangle"; } subgraph cluster_plaintext { plaintext [shape=plaintext label="plaintext"]; label="plaintext"; } subgraph cluster_plain { plain [shape=plain]; label="plain"; } subgraph cluster_diamond { diamond [shape=diamond]; label="diamond"; } subgraph cluster_trapezium { trapezium [shape=trapezium]; label="trapezium"; } subgraph cluster_parallelogram { parallelogram [shape=parallelogram]; label="parallelogram"; } subgraph cluster_house { house [shape=house]; label="house"; } subgraph cluster_pentagon { pentagon [shape=pentagon]; label="pentagon"; } subgraph cluster_hexagon { hexagon [shape=hexagon]; label="hexagon"; } subgraph cluster_septagon { septagon [shape=septagon]; label="septagon"; } subgraph cluster_octagon { octagon [shape=octagon]; label="octagon"; } subgraph cluster_doublecircle { doublecircle [shape=doublecircle]; label="doublecircle"; } subgraph cluster_doubleoctagon { doubleoctagon [shape=doubleoctagon]; label="doubleoctagon"; } subgraph cluster_tripleoctagon { tripleoctagon [shape=tripleoctagon]; label="tripleoctagon"; } subgraph cluster_invtriangle { invtriangle [shape=invtriangle]; label="invtriangle"; } subgraph cluster_invtrapezium { invtrapezium [shape=invtrapezium]; label="invtrapezium"; } subgraph cluster_invhouse { invhouse [shape=invhouse]; label="invhouse"; } subgraph cluster_Mdiamond { Mdiamond [shape=Mdiamond]; label="Mdiamond"; } subgraph cluster_Msquare { Msquare [shape=Msquare]; label="Msquare"; } subgraph cluster_Mcircle { Mcircle [shape=Mcircle]; label="Mcircle"; } subgraph cluster_rect { rect [shape=rect]; label="rect"; } subgraph cluster_rectangle { rectangle [shape=rectangle]; label="rectangle"; } subgraph cluster_square { square [shape=square]; label="square"; } subgraph cluster_star { star [shape=star]; label="star"; } subgraph cluster_none { none [shape=none]; label="none"; } subgraph cluster_underline { underline [shape=underline]; label="underline"; } subgraph cluster_cylinder { cylinder [shape=cylinder]; label="cylinder"; } subgraph cluster_note { note [shape=note]; label="note"; } subgraph cluster_tab { tab [shape=tab]; label="tab"; } subgraph cluster_folder { folder [shape=folder]; label="folder"; } subgraph cluster_box3d { box3d [shape=box3d]; label="box3d"; } subgraph cluster_component { component [shape=component]; label="component"; } subgraph cluster_promoter { promoter [shape=promoter]; label="promoter"; } subgraph cluster_cds { cds [shape=cds]; label="cds"; } subgraph cluster_terminator { terminator [shape=terminator]; label="terminator"; } subgraph cluster_utr { utr [shape=utr]; label="utr"; } subgraph cluster_primersite { primersite [shape=primersite]; label="primersite"; } subgraph cluster_restrictionsite { restrictionsite [shape=restrictionsite]; label="restrictionsite"; } subgraph cluster_fivepoverhang { fivepoverhang [shape=fivepoverhang]; label="fivepoverhang"; } subgraph cluster_threepoverhang { threepoverhang [shape=threepoverhang]; label="threepoverhang"; } subgraph cluster_noverhang { noverhang [shape=noverhang]; label="noverhang"; } subgraph cluster_assembly { assembly [shape=assembly]; label="assembly"; } subgraph cluster_signature { signature [shape=signature]; label="signature"; } subgraph cluster_insulator { insulator [shape=insulator]; label="insulator"; } subgraph cluster_ribosite { ribosite [shape=ribosite]; label="ribosite"; } subgraph cluster_rnastab { rnastab [shape=rnastab]; label="rnastab"; } subgraph cluster_proteasesite { proteasesite [shape=proteasesite]; label="proteasesite"; } subgraph cluster_proteinstab { proteinstab [shape=proteinstab]; label="proteinstab"; } subgraph cluster_rpromoter { rpromoter [shape=rpromoter]; label="rpromoter"; } subgraph cluster_rarrow { rarrow [shape=rarrow]; label="rarrow"; } subgraph cluster_larrow { larrow [shape=larrow]; label="larrow"; } subgraph cluster_lpromoter { lpromoter [shape=lpromoter]; label="lpromoter"; } rarrow -> larrow -> lpromoter; rnastab -> proteasesite -> proteinstab -> rpromoter; assembly -> signature -> insulator -> ribosite; restrictionsite -> fivepoverhang -> threepoverhang -> noverhang; cds -> terminator -> utr -> primersite; folder -> box3d -> component -> promoter; underline -> cylinder -> note -> tab; rectangle -> square -> star -> none; Mdiamond -> Msquare -> Mcircle -> rect; tripleoctagon -> invtriangle -> invtrapezium -> invhouse; septagon -> octagon -> doublecircle -> doubleoctagon; parallelogram -> house -> pentagon -> hexagon; plaintext -> plain -> diamond -> trapezium; circle -> point -> egg -> triangle; box -> polygon -> ellipse -> oval; } }

一些特殊的多边形形状节点

同名的形状

box, rectrectangle都是表示矩形的同一形状;而ellipseoval都是表示椭圆的同一形状。

digraph { {rank=source; a, b, c} a [shape=box]; b [shape=rect]; c [shape=rectangle]; {rank=same; e, f} e [shape=ellipse]; f [shape=oval]; }

plaintext, none, plain及underline

digraph { subgraph clusterBorderedShapes { label="Bordered Shapes"; box [shape=box]; oval [shape=oval]; } subgraph clusterNonBorderedShapes { label="Non-Bordered Shapes"; underline [shape=underline]; plain [shape=plain]; none [shape=none]; plaintext [shape=plaintext]; } }

其他多边形节点都有边框,而plaintext, none, plainundeline均没有边框。前3个甚至没有任何线条,后者则只有一条下划线。尽管如此,默认情况下,它们都带有标签。

可以同时将它们的标签也取消掉,但由于没有边框,若对plaintext, none, plain设置边框颜色值则无效。而undeline则可设置边框底部的颜色。

digraph { underline [shape=underline, label="", color=red]; plaintext [shape=plaintext, label="", color=red]; underline -> plaintext; }

可以为它们设置背景颜色。

digraph { plain [shape=plain, style="filled", fillcolor="#88AACC99", margin=0.5]; plaintext [shape=plaintext, style="filled", fillcolor="#88AACC99", margin=0.5]; none [shape=none, style="filled", fillcolor="#88AACC99", margin=0.5]; plain -> plaintext -> none; }

上面可看出,plainwidth, heightmargin属性均被强制设置为0。此时,背景颜色的范围仅紧紧围绕其标签的内容而设定。而plaintextnone均可设置这些值。

margin属性类似于CSS中的padding属性。

noneplaintext的别名。none主要是指没有边框

point

可为point指定widthheight属性值,以inch为单位。这两个值如果不相等,则取最小值。

digraph { a [shape=point, width=2.5, height=1.5]; }

point指定label属性值无效。

point适用于无需文本而又想显式地表示为节点的场合。

digraph { node [shape=point, width=0.2]; a -> b -> c -> d; }

基于记录的节点

共有2种记录节点:recordMrecordrecord的边框为直角,Mrecord的边框为圆角。

最简单的记录节点

digraph { node [shape=record]; struct [label="left | middle | right"]; }

先将nodeshape设置为record,然后设置其label属性,格式为:item1 | item2 | item3等,即单元格的内容以|号分隔。首部与尾部不需加|号。

这种排列其实与画布的rankdir的设置有关。如果布局是竖直的,则最外层的节点按水平方向排列。如果布局是水平的,则最外层的节点按竖直方向排列。

默认情况下,画布的布局是竖直排列的:rankdir=TB,因此记录节点水平排列。

因此,我们可以通过改变画布的布局方向来改变最外层的记录节点的排列方向。

digraph { rankdir=LR; node [shape=record]; struct [label="left | middle | right"]; }

鉴于此,在使用记录节点时,建议显式地设置rankdir的值,在出现bug时,能第一时间检查该属性值。

行或列的翻转

如果需要翻转行列,只需使用{item1 | item2 | item3}的格式即可。

digraph { rankdir=TB; node [shape=record]; struct [label="left | {one | two} | right"]; }

这就实现了表格跨行或跨列的功能。并且我们还可以不断地细分:

digraph { rankdir=TB; node [shape=record]; struct [label="left | {one | {1 | 2}} | right"]; }

这个特点,比起在table中笨拙地跨行跨列来讲,方便了许多:table要返回原来的标签来人工写入跨多行跨多少列,而这里不需要。从最外层到最里层,不断地进行细分就行。

连接记录节点

记录节点可以实现子元素级别的直接连接,在需要进行连接的子元素前面加上<id>来声明箭头起始位置,然后连接时使用item:id进行引用即可。

digraph { node [shape=Mrecord]; struct1 [label="left | <f0> middle | right"]; struct2 [label="one | <f0> two"]; struct1:f0 -> struct2:f0; }

使用转义字符

digraph { node [shape=record]; struct1 [label="\ | one | \"]; }

范例

这一节中,我们实现WebGL中的例子。

digraph { node [shape=record]; subgraph clusterVBO { label="vbo"; color="invis"; vbo [label="<f0> 0.0 | <f1> 0.5 | -0.5 | -0.5 | 0.5 | -0.5"]; } subgraph clusterAPosition { label="aPosition"; color="invis"; aPosition [label=" | | |"]; } }

我们看到,vbo是一个数组,共有6个元素,其中每两个元素为一个顶点的一组坐标,因此共3组坐标。而顶点属性aPosition也是一个数组,但只有4个空位。我们现在需要考虑的是,如何将vbo中各个顶点的坐标值传输至aPosition数组中。

下面的图示实现连接。

digraph { node [shape=record]; vbo [label="<f0> 0.0 | <f1> 0.5 | -0.5 | -0.5 | 0.5 | -0.5"]; struct2 [label="<f0> aPosition | aColor"]; vbo:f0 -> struct2:f0; vbo:f1 -> struct2:f0; }

用户自定义节点

digraph { a -> b; }

参考资源

  1. Graphviz.org
  2. Graphviz Node Shapes