|
@@ -29,6 +29,18 @@ def _add_person_node(graph: graphviz.dot.Digraph, person: Person) -> None:
|
|
|
graph.node(person.identifier, label=label, shape="box")
|
|
|
|
|
|
|
|
|
+def _add_parent_node(graph: graphviz.dot.Digraph, parents: typing.Set[Person]) -> str:
|
|
|
+ parent_node_name = "relation-{}-{}".format(
|
|
|
+ parents[0].identifier, parents[1].identifier
|
|
|
+ )
|
|
|
+ graph.node(parent_node_name, shape="point", width="0")
|
|
|
+ for parent in parents:
|
|
|
+ graph.edge(
|
|
|
+ parent.identifier, parent_node_name, constraint="False", arrowhead="none",
|
|
|
+ )
|
|
|
+ return parent_node_name
|
|
|
+
|
|
|
+
|
|
|
def digraph(collection: PersonCollection) -> graphviz.dot.Digraph:
|
|
|
"""
|
|
|
>>> bob = Person('bob')
|
|
@@ -53,27 +65,27 @@ def digraph(collection: PersonCollection) -> graphviz.dot.Digraph:
|
|
|
>>> graph = digraph(collection)
|
|
|
>>> print(graph.source)
|
|
|
digraph yamily {
|
|
|
- {
|
|
|
+ subgraph cluster_grace {
|
|
|
rank=same
|
|
|
grace [label=grace shape=box]
|
|
|
}
|
|
|
- {
|
|
|
+ subgraph cluster_carol {
|
|
|
rank=same
|
|
|
carol [label=carol shape=box]
|
|
|
- bob [label=bob shape=box]
|
|
|
"relation-bob-carol" [shape=point width=0]
|
|
|
- carol -> "relation-bob-carol" [arrowhead=none constraint=False]
|
|
|
bob -> "relation-bob-carol" [arrowhead=none constraint=False]
|
|
|
+ carol -> "relation-bob-carol" [arrowhead=none constraint=False]
|
|
|
+ bob [label=bob shape=box]
|
|
|
}
|
|
|
- {
|
|
|
+ subgraph cluster_frank {
|
|
|
rank=same
|
|
|
frank [label=frank shape=box]
|
|
|
}
|
|
|
- {
|
|
|
+ subgraph cluster_alice {
|
|
|
rank=same
|
|
|
alice [label=alice shape=box]
|
|
|
}
|
|
|
- {
|
|
|
+ subgraph cluster_david {
|
|
|
rank=same
|
|
|
david [label=david shape=box]
|
|
|
}
|
|
@@ -91,32 +103,18 @@ def digraph(collection: PersonCollection) -> graphviz.dot.Digraph:
|
|
|
for person in collection:
|
|
|
if person in nodes:
|
|
|
continue
|
|
|
- with graph.subgraph() as subgraph:
|
|
|
+ # https://graphviz.gitlab.io/_pages/Gallery/directed/cluster.html
|
|
|
+ with graph.subgraph(name="cluster_" + person.identifier) as subgraph:
|
|
|
subgraph.attr(rank="same")
|
|
|
_add_person_node(subgraph, person)
|
|
|
nodes.add(person)
|
|
|
for coparent in collection.get_coparents(person):
|
|
|
- _add_person_node(subgraph, coparent)
|
|
|
- nodes.add(coparent)
|
|
|
parents = tuple(sorted((person, coparent), key=lambda p: p.identifier))
|
|
|
- parent_node_name = "relation-{}-{}".format(
|
|
|
- parents[0].identifier, parents[1].identifier
|
|
|
- )
|
|
|
- subgraph.node(parent_node_name, shape="point", width="0")
|
|
|
- subgraph.edge(
|
|
|
- person.identifier,
|
|
|
- parent_node_name,
|
|
|
- constraint="False",
|
|
|
- arrowhead="none",
|
|
|
- )
|
|
|
- subgraph.edge(
|
|
|
- coparent.identifier,
|
|
|
- parent_node_name,
|
|
|
- constraint="False",
|
|
|
- arrowhead="none",
|
|
|
- )
|
|
|
+ parent_node_name = _add_parent_node(subgraph, parents)
|
|
|
parent_node_names[parents] = parent_node_name
|
|
|
parent_node_names[tuple(parents[::-1])] = parent_node_name
|
|
|
+ _add_person_node(subgraph, coparent)
|
|
|
+ nodes.add(coparent)
|
|
|
for child in collection:
|
|
|
if child.mother is not None and child.father is not None:
|
|
|
parents = sorted(child.parents, key=lambda p: p.identifier)
|