chiark / gitweb /
0e7852513731f9177e031f329662a388ed4e706c
[familyTree.git] / cgiFiles / make_dot.py
1 #!/usr/bin/python
2
3 import cgi
4 import cgitb
5 import gv
6 import re
7 import sys
8 sys.path.append('/home/naath/familyTreeProject/familyTree')
9 import askQuestion as aQ
10
11
12 cgitb.enable()
13 def add_quotes(s):
14         return '\"'+str(s)+'\"'
15
16 def add_node(node,node_attr):
17         global dot
18         global nodes
19         node_attr = attr_string(node_attr)
20         if node not in nodes:
21                 dot = dot + add_quotes(node) + node_attr + ";\n"
22                 nodes.append(node)
23
24 def has_node(node):
25         if node in nodes:
26                 return 1
27         else:
28                 return 0
29 def has_edge(edge):
30         edge[0] = add_quotes(edge[0])
31         edge[1] = add_quotes(edge[1])
32         if edge in edges:
33                 return 1
34         else:
35                 return 0
36
37 def add_edge(n1,n2,edge_attr):
38         global dot
39         global edges
40         edge = (add_quotes(n1),add_quotes(n2))
41         edge_attr = attr_string(edge_attr)
42         if edge not in edges:
43                 dot = dot + edge[0] + ' -> ' + edge[1] + edge_attr + ";"
44                 edges.append(edge)
45
46 def add_arrow(n1,n2):
47         add_edge(n1,n2,edge_attr)
48
49 def add_no_arrow(n1,n2):
50         add_edge(n1,n2,nodir_attr)
51
52 def add_marriage(n1,n2,children,joinChildren):
53         global cNodes
54         
55         jN = n1+n2
56         jNRev = n2+n1
57         if has_node(jNRev):
58                 jN = jNRev
59         add_spot(jN)
60         add_person(n1)
61         add_person(n2)
62
63         
64
65         if len(children)>0 and joinChildren==1:
66                 cNode = jN + 'c'
67                 tcNode = cNode + children[0]
68                 
69                 if cNodes.has_key(cNode):
70                         if not has_node(tcNode):
71                                 if len(cNodes[cNode])>0:
72                                         last = cNodes[cNode][-1]
73                                 add_spot(tcNode)
74                                 cNodes[cNode].append(tcNode)
75                                 add_no_arrow(last,tcNode)
76                                 add_subgraph([tcNode,last])
77                 else:
78                         add_spot(tcNode)
79                         cNodes[cNode] = [tcNode]
80                         add_no_arrow(jN,tcNode)
81
82
83         elif len(children)>0:
84                 tcNode = jN
85
86         for c in children:
87                 add_person(c)
88                 add_arrow(tcNode,c)
89         for n in [n1, n2]:
90                 add_edge(n,jN,marriage_attr)
91         add_subgraph([n1,n2])
92
93
94 def add_subgraph(myG):
95         global subgraphs
96         subgraphs.append(myG)
97         
98 def add_subgraphs():
99         global dot
100         for sg in subgraphs:
101                 line = "\n{rank=same "
102
103                 for n in sg:
104                         line = line +add_quotes(n) + ' '
105
106                 line = line +"}"
107
108                 dot = dot + line
109
110 def end_dot():
111         global dot
112
113         dot = dot + "}"
114
115 def start_dot(fs):
116         global dot
117         global nodes
118         global edges
119         global subgraphs
120         global cNodes
121         nodes=[]
122         edges=[]
123         cNodes={}
124         dot = "digraph G{\n"
125         dot = dot + "ranksep = 0.2 nodesep = 0.1\n"
126         subgraphs=[]
127         set_attr(fs)
128
129 def add_highlight(name):
130         global dot
131
132         add_person(name)
133         dot = dot +'\n'\
134         'subgraph clusterhl {'+add_quotes(name)+';\n'
135         for a in highlight_attr:
136                 dot = dot + a[0] + '=' +a[1] +';\n'
137         dot = dot + '}'
138         
139
140 def add_person(name):
141         try:
142                 k=aQ.isKing(name)
143         except:
144                 k=0
145         ln = name.replace(', ','\\n')
146         ln = ln.replace(',','\\n')
147         ln = ln.replace(' ','\\n')
148         myLabel = '"'+str(ln)+'"'
149
150         if k==1:
151                  add_node(name,king_attr+[('label',myLabel)])
152         else:
153                 add_node(name,person_attr+[('label',myLabel)])
154 def add_spot(name):
155         add_node(name,spot_attr)
156
157
158 def set_attr(fs):
159         global person_attr
160         global highlight_attr
161         global king_attr
162         global spot_attr
163         global edge_attr
164         global invis_attr
165         global ignored_attr
166         global nodir_attr
167         global marriage_attr
168         global debug_attr
169         global debug_edge_attr
170         zero_size = [('width','0'),('height','0')]
171         person_attr = [('fontsize',str(fs))]+\
172                 [('shape','plaintext'),('margin','0'),\
173                 ('style','filled'),('fillcolor','white')] +\
174                 zero_size
175         highlight_attr =  \
176                 [('shape','box'),('color','red'),('style','filled')]
177         king_attr = person_attr +\
178                 [('fontcolor','purple4'),('shape','house'),('color','purple4')]
179         debug_attr = person_attr + [('fontcolor','green')]
180         spot_attr = [('shape','point')] + zero_size
181         edge_attr = [('len','0'),('arrowsize','0.5')]
182         debug_edge_attr = edge_attr + [('color','green')]
183         invis_attr = edge_attr + [('style','invis')]
184         nodir_attr = edge_attr + [('dir','none')]
185         marriage_attr = nodir_attr + [('weight','10'),('color','red')]
186         ignored_attr =edge_attr + [('constraint','false')] + nodir_attr
187
188 def attr_string(attr):
189         
190         attr_str = '['
191         for a in attr:
192                 attr_str = attr_str + a[0] + '=' + a[1]
193                 if a != attr[-1]:
194                         attr_str = attr_str +','
195
196         attr_str = attr_str + ']'
197         return attr_str
198
199 def render_dot():
200
201         f = open('tempfile','w')
202         f.write(dot)
203         f.close
204
205         gvv = gv.readstring(dot)
206         gv.layout(gvv,'dot')
207
208         format = 'png'
209
210         print "Content-type: image/" + format + "\n"
211         print gv.render(gvv,format)