chiark / gitweb /
changed graphs to manual dot file; added pictures; faffed about with text
[familyTree.git] / cgiFiles / make_dot.py
diff --git a/cgiFiles/make_dot.py b/cgiFiles/make_dot.py
new file mode 100755 (executable)
index 0000000..9c9e20b
--- /dev/null
@@ -0,0 +1,177 @@
+#!/usr/bin/python
+
+import cgi
+import cgitb
+import gv
+import re
+
+cgitb.enable()
+def add_quotes(s):
+        return '\"'+str(s)+'\"'
+
+def add_node(node,node_attr):
+       global dot
+       global nodes
+       node_attr = attr_string(node_attr)
+       if node not in nodes:
+               dot = dot + add_quotes(node) + node_attr + ";\n"
+               nodes.append(node)
+
+def has_node(node):
+       if node in nodes:
+               return 1
+       else:
+               return 0
+def has_edge(edge):
+       edge[0] = add_quotes(edge[0])
+       edge[1] = add_quotes(edge[1])
+       if edge in edges:
+               return 1
+       else:
+               return 0
+
+def add_edge(n1,n2,edge_attr):
+       global dot
+       global edges
+       edge = (add_quotes(n1),add_quotes(n2))
+       edge_attr = attr_string(edge_attr)
+       if edge not in edges:
+               dot = dot + edge[0] + ' -> ' + edge[1] + edge_attr + ";"
+               edges.append(edge)
+
+def add_arrow(n1,n2):
+       add_edge(n1,n2,edge_attr)
+
+def add_no_arrow(n1,n2):
+       add_edge(n1,n2,nodir_attr)
+
+def add_marriage(n1,n2,children,joinChildren):
+       global cNodes
+       
+       jN = n1+n2
+       jNRev = n2+n1
+       if has_node(jNRev):
+               jN = jNRev
+       add_spot(jN)
+       add_person(n1)
+       add_person(n2)
+
+       
+
+       if len(children)>0 and joinChildren==1:
+               cNode = jN + 'c'
+               e = [cNode,children[0]]
+               if has_node(cNode):
+                       tcNode = cNode + children[0]
+                       if len(cNodes[cNode])>0:
+                               last = cNodes[cNode][-1]
+                       else:
+                               last = cNode
+                       add_spot(tcNode)
+                       cNodes[cNode].append(tcNode)
+                       add_no_arrow(last,tcNode)
+                       add_subgraph([tcNode,cNode])
+               else:
+                       tcNode = cNode
+                       add_spot(cNode)
+                       cNodes[cNode] = []
+                       add_no_arrow(jN,cNode)
+
+       elif len(children)>0:
+               tcNode = jN
+
+       for c in children:
+               add_person(c)
+               add_arrow(tcNode,c)
+       for n in [n1, n2]:
+               add_edge(n,jN,marriage_attr)
+       add_subgraph([n1,n2])
+
+
+def add_subgraph(myG):
+       global subgraphs
+       subgraphs.append(myG)
+       
+def add_subgraphs():
+       global dot
+       for sg in subgraphs:
+               line = "\n{rank=same "
+
+                for n in sg:
+                        line = line +add_quotes(n) + ' '
+
+                line = line +"}"
+
+                dot = dot + line
+
+def end_dot():
+       global dot
+        dot = dot + "}"
+
+def start_dot():
+       global dot
+       global nodes
+       global edges
+       global subgraphs
+       global cNodes
+       nodes=[]
+       edges=[]
+       cNodes={}
+       dot = "digraph G{\n"
+       dot = dot + "ranksep = 0.5 nodesep = 0\n"
+       subgraphs=[]
+       set_attr()
+
+def add_highlight(name):
+       add_node(name,highlight_attr)
+
+def add_person(name):
+       add_node(name,person_attr)
+
+def add_spot(name):
+       add_node(name,spot_attr)
+
+
+def set_attr():
+       global person_attr
+        global highlight_attr
+        global spot_attr
+        global edge_attr
+        global invis_attr
+        global ignored_attr
+        global nodir_attr
+       global marriage_attr
+       global debug_attr
+       global debug_edge_attr
+       zero_size = [('width','0'),('height','0')]
+        person_attr = [('fontsize','8'),('shape','plaintext')] + zero_size
+       highlight_attr = person_attr + \
+               [('fontcolor','red'),('shape','box'),('color','red')]
+       debug_attr = person_attr + [('fontcolor','green')]
+       spot_attr = [('shape','point')] + zero_size
+       edge_attr = [('len','0'),('arrowsize','0.5')]
+       debug_edge_attr = edge_attr + [('color','green')]
+       invis_attr = edge_attr + [('style','invis')]
+       nodir_attr = edge_attr + [('dir','none')]
+       marriage_attr = nodir_attr + [('weight','10'),('color','red')]
+       ignored_attr =edge_attr + [('constraint','false')] + nodir_attr
+
+def attr_string(attr):
+       
+       attr_str = '['
+       for a in attr:
+               attr_str = attr_str + a[0] + '=' + a[1]
+               if a != attr[-1]:
+                       attr_str = attr_str +','
+
+       attr_str = attr_str + ']'
+       return attr_str
+
+def render_dot():
+       gvv = gv.readstring(dot)
+        gv.layout(gvv,'dot')
+
+        format = 'png'
+
+        print "Content-type: image/" + format + "\n"
+        print gv.render(gvv,format)