如何使用graphviz将节点置于其他节点之上?

8yparm6h  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(329)

我正在尝试设计一种具有特定颜色和形状的非常特定类型的图形,但我无法判断这是否可以通过graphviz实现。
我的目标是绘制一个有向图,其中每个节点:
由3个水平排列的小盒子组成(
striped rectanglerecord , rounded )
包含3个 labels 因此
充满了梯度
在中间框的顶部有一个黑色方形节点
示例(已手动放置所有黑框):

我已经达到了第三个要求,但我正在努力实现最后一个要求。如何放置方形节点( rect , square , box ,等等)放置在第一组节点(彩色矩形)的顶部,以使它们完全适合它们要覆盖的中间框的尺寸?这在graphviz身上可能吗?
示例代码(python):

from graphviz import Digraph

# Dictionary storing relations between nodes

d = {0: set([1, 2, 3]), 
     1: set([4, 5, 6]), 
     2: set([7, 8, 9, 10]), 
     3: set([0]), 
     4: set([]), 
     5: set([]), 
     6: set([]), 
     7: set([]), 
     8: set([0]), 
     9: set([]), 
     10: set([])} 

# List of node labels (3 labels per node)

P = [('S', 'M', 'S'),
     ('M', 'S', 'L'),
     ('M', 'S', 'S'),
     ('M', 'S', 'M'),
     ('S', 'L', 'L'),
     ('S', 'L', 'M'),
     ('S', 'L', 'X'),
     ('S', 'S', 'S'),
     ('S', 'S', 'M'),
     ('S', 'S', 'L'),
     ('S', 'S', 'X')]

# Dictionary storing the colors corresponding to each label

c = {'S':'olivedrab1', 
     'M':'mediumturquoise', 
     'L':'deepskyblue', 
     'X':'palevioletred1'}

# Create a "directed graph" with general node and edge attributes

G = Digraph(node_attr={'shape':'record',  
                       'style':'rounded, filled',
                       'color':'white', 
                       'height':'0.1',
                       'fontcolor':'white'},

            edge_attr={'color':'grey', 
                       'arrowhead':'vee'} 
           )

G.attr('graph', bgcolor='transparent')

# 1st pass: create all nodes (0 to 10)

for k in d:
    l1, l2, l3 = P[k]

    # set specific attribute to each node (label & colors)
    G.attr('node', label='{} | {} | {}'.format(l1, ' ', l2), fillcolor='{}:{}'.format(c[l1], c[l2]))
    G.node(str(k))

# 2nd pass: create edges between nodes

for k in d:
    l1, l2, l3 = P[k]
    for i in d[k]:
        if i in d:
            G.edge(str(k), str(i))

# Then, how to overlap black square nodes ?
xytpbqjk

xytpbqjk1#

我认为在dot/graphviz中不可能强制节点将一个节点叠加到另一个节点上;我想这可能有点挫败了可视化绘制图形的全部意义。
此代码使用html(-like)形状作为节点;这些描述了一个三单元格表格,左右两侧为渐变色,中间为纯黑色和白色文本。

import graphviz

# Dictionary storing relations between nodes

d = {0: set([1, 2, 3]), 
     1: set([4, 5, 6]), 
     2: set([7, 8, 9, 10]), 
     3: set([0]), 
     4: set([]), 
     5: set([]), 
     6: set([]), 
     7: set([]), 
     8: set([0]), 
     9: set([]), 
     10: set([])} 

# List of node labels (3 labels per node)

P = [('S', 'M', 'S'),
     ('M', 'S', 'L'),
     ('M', 'S', 'S'),
     ('M', 'S', 'M'),
     ('S', 'L', 'L'),
     ('S', 'L', 'M'),
     ('S', 'L', 'X'),
     ('S', 'S', 'S'),
     ('S', 'S', 'M'),
     ('S', 'S', 'L'),
     ('S', 'S', 'X')]

# Dictionary storing the colors corresponding to each label

c = {'S':'olivedrab1:grey', 
     'M':'mediumturquoise:gray', 
     'L':'deepskyblue:gray', 
     'X':'palevioletred1:gray'}

# Create a "directed graph" with general node and edge attributes

G = graphviz.Digraph(
            format='svg'
            ,edge_attr={'color':'grey', 
                       'arrowhead':'vee'} 
           )

G.attr('graph', bgcolor='transparent')

# 1st pass: create all nodes (0 to 10)

for k in d:
    l1, l2, l3 = P[k]

    G.node(name=str(k),shape='plain',label=f'''<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
  <TR>
    <TD BGCOLOR="{c[l1]}" GRADIENTANGLE="45">{l1}</TD>
    <TD BGCOLOR="black"><FONT COLOR="white">{l2}</FONT></TD>
    <TD BGCOLOR="{c[l3]}" GRADIENTANGLE="135">{l3}</TD>
  </TR>
</TABLE>
>
'''
)

# 2nd pass: create edges between nodes

for k in d:
    l1, l2, l3 = P[k]
    for i in d[k]:
        if i in d:
            G.edge(str(k), str(i))

G.view()

结果:

笔记:
当shape设置为“plain”时,节点获取html的形状
颜色梯度在单元格中指定 <TD> 作为 BGCOLOR=“colour1:colour2” 渐变的Angular 也在单元格中指定 <TD> 例如。 GRADIENTANGLE=“45” 有关html节点的详细信息,请参见:http://graphviz.org/doc/info/shapes.html#gradientangle

相关问题