2 Commits 049af94bd0 ... 7eae5cafa8

Author SHA1 Message Date
  Fabian Peter Hammerle 7eae5cafa8 graph: cluster coparents to make parent nodes neighbours 1 month ago
  Fabian Peter Hammerle 23454fa8b2 refactor graph: add _add_parent_node() 1 month ago
2 changed files with 32 additions and 34 deletions
  1. 8 8
      tests/persons/digraph.dot
  2. 24 26
      yamily/_graphviz.py

+ 8 - 8
tests/persons/digraph.dot

@@ -1,29 +1,29 @@
 digraph yamily {
-	{
+	subgraph "cluster_erika-mustermann" {
 		rank=same
 		"erika-mustermann" [label="Erika Mustermann\n*1957-08-12" shape=box]
-		"thomas-mustermann" [label="thomas-mustermann" shape=box]
 		"relation-erika-mustermann-thomas-mustermann" [shape=point width=0]
 		"erika-mustermann" -> "relation-erika-mustermann-thomas-mustermann" [arrowhead=none constraint=False]
 		"thomas-mustermann" -> "relation-erika-mustermann-thomas-mustermann" [arrowhead=none constraint=False]
+		"thomas-mustermann" [label="thomas-mustermann" shape=box]
 	}
-	{
+	subgraph "cluster_alice-mother" {
 		rank=same
 		"alice-mother" [label="Mum Test" shape=box]
-		"alice-father" [label="alice-father" shape=box]
 		"relation-alice-father-alice-mother" [shape=point width=0]
-		"alice-mother" -> "relation-alice-father-alice-mother" [arrowhead=none constraint=False]
 		"alice-father" -> "relation-alice-father-alice-mother" [arrowhead=none constraint=False]
+		"alice-mother" -> "relation-alice-father-alice-mother" [arrowhead=none constraint=False]
+		"alice-father" [label="alice-father" shape=box]
 	}
-	{
+	subgraph "cluster_alice-grandmother" {
 		rank=same
 		"alice-grandmother" [label="Grandma Test" shape=box]
 	}
-	{
+	subgraph cluster_alice {
 		rank=same
 		alice [label="Alice Test" shape=box]
 	}
-	{
+	subgraph "cluster_max-mustermann" {
 		rank=same
 		"max-mustermann" [label="Max Mustermann\n*1976-02-01" shape=box]
 	}

+ 24 - 26
yamily/_graphviz.py

@@ -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)