1
2
3
4
5
6
7
8
9 import math
10 from Tkinter import *
11 import Pmw
12
13
14 gcolors = ['#bb0000', '#ccaa00', '#00bb00', '#0000bb', '#aa00aa', '#000000']
15
16 gstate = ['militarypower', 'economicpower', 'hardship']
17
18 chrome = '#efefef'
19 bronze = '#7e5b41'
20 ltbronze = '#9e7b61'
21
23
24 - def __init__(self, win, entities, type='state'):
25 self.master = win.frame
26 self.step = -1
27 self.rel = type
28 self.entity = entities.members()[0]
29 self.entities = entities
30 self.smoothing='linear'
31 self.symbols = 0
32 self.color = {}
33 self.color['militarypower'] = '#ff2050'
34 self.color['economicpower'] = '#00ff00'
35 self.color['hardship'] = '#a0a0a0'
36 self.names = map(lambda e:e.name, entities.members())
37
38
39
40 self.bframe = Frame(self.master,
41
42 borderwidth = 1,
43
44
45 highlightthickness = 1,
46 relief = RAISED)
47
48 self.bframe.pack(side='top', expand=1, fill = 'x')
49 self.relbuttons = Pmw.OptionMenu(self.bframe, labelpos='w',
50 label_text=":", command= lambda type,s=self:s.dorels(type))
51 self.enbuttons = Pmw.OptionMenu(self.bframe, labelpos='w',
52 label_text="Entity", command=lambda t,s=self:s.docurves(t))
53 self.enbuttons.pack(side = 'left', padx=1, pady=1)
54 self.relbuttons.pack(side = 'left', padx=1, pady=1)
55
56 i = 0
57 for n in self.entities.members():
58 self.color[n.name] = gcolors[i % len(gcolors)]
59 i = i + 1
60
61 self.vector_x = Pmw.Blt.Vector()
62 self.vector_y = {}
63 for n in self.entities.members():
64 self.vector_y[n.name] = {}
65 for n2 in gstate:
66 self.vector_y[n.name][n2] = Pmw.Blt.Vector()
67 for n2 in self.entities.members():
68 if n.name != n2.name:
69 self.vector_y[n.name][n2.name] = Pmw.Blt.Vector()
70
71 self.relbuttons.setitems(['State', 'Support_For'], 1)
72 self.enbuttons.setitems(map(lambda e:e.name, self.entities.members()), 0)
73
74
75 self.explorerPane = Pmw.PanedWidget(self.master, orient='vertical')
76 self.explorerPane.pack(side=TOP,
77 expand=YES,
78 fill=BOTH)
79 self.gpane = self.explorerPane.add('graphPane', min=.3)
80 self.tpane = self.explorerPane.add('textPane', min=.1, size = 20)
81 self.gpane.pack()
82 self.tpane.pack()
83
84
85
86 self.g = Pmw.Blt.Stripchart(self.gpane)
87 self.g.xaxis_configure(min="0.0")
88 self.g.xaxis_configure(subdivisions="1")
89 self.g.xaxis_configure(majorticks="")
90 self.loadHistory()
91
92
93
94
95
96 self.g.xaxis_configure(title="Time")
97 self.g.xaxis_configure(stepsize="1.0")
98 self.g.yaxis_configure(min="-1.0")
99 self.g.yaxis_configure(max="1.0")
100 self.g.pack(expand=1, fill='both')
101 self.scrotxt = Pmw.ScrolledText(self.tpane)
102 self.scrotxt.pack(expand=1, fill='both')
103 self.scrotxt.tag_config('bolden', font = ("Helvetica", 10, "bold"))
104
105 self.g.configure(title=self.rel)
106
107
108
109
110
111 self.opbuttons = Pmw.RadioSelect(self.bframe,
112 labelpos='w', label_text='Options',
113 command =lambda b,s=self:s.doopt(b),
114 frame_borderwidth = 2,
115 frame_relief = 'ridge'
116 )
117 self.opbuttons.pack(side='left', padx=1, pady=1)
118 self.opbuttons.add('Grid')
119 self.opbuttons.add('Smooth')
120
121
122
123 self.docurves(self.entity.name, self.rel)
124
126 return len(self.vector_x) == 0
127
128 - def saveHistory(self):
129 """Updates the history on the entities object (for saving
130 purposes)"""
131 self.entities.history['x'] = self.vector_x.get()
132 if not self.entities.history.has_key('y'):
133 self.entities.history['y'] = {}
134 for name1,vectorDict in self.vector_y.items():
135 if not self.entities.history['y'].has_key(name1):
136 self.entities.history['y'][name1] = {}
137 for name2,vector in vectorDict.items():
138 self.entities.history['y'][name1][name2] = vector.get()
139
140 - def loadHistory(self,entities=None):
141 """Updates the history vector based on the lists of values stored in
142 the entities object"""
143 if entities:
144 self.entity = entities.members()[0]
145 self.entities = entities
146 if not self.isEmpty():
147 self.deldata()
148 if self.entities.history:
149 map(lambda x,s=self:s.vector_x.append(x),
150 self.entities.history['x'])
151 for name1,vectorDict in self.entities.history['y'].items():
152 for name2,vector in vectorDict.items():
153 map(lambda y,s=self,n1=name1,n2=name2:
154 s.vector_y[n1][n2].append(y),
155 self.entities.history['y'][name1][name2])
156 else:
157
158 self.entities.history = {}
159 self.adddata(0)
160
162 if label is 'Smooth':
163 self.smooth()
164 elif label is 'Grid':
165 self.g.grid_toggle()
166
167
168
170 for name in self.g.element_names():
171 self.g.element_delete(name)
172
173
174 - def trend(self,name,step,type):
175 str = ""
176 if step - 1 < 0:
177 return str
178 n = self.entities[name]
179 self.entity = n
180 if type == n._supportFeature:
181 for c in self.entities.members():
182 if n.name != c.name:
183 ydatanow=self.vector_y[n.name][c.name][step]
184 ydataprev=self.vector_y[n.name][c.name][step - 1]
185 if ydatanow - ydataprev < -0.1:
186 str = str + "Support for " + c.name + " dropping significantly.\n"
187 if ydatanow - ydataprev > 0.1:
188 str = str + "Support for " + c.name + " increasingly significantly.\n"
189 else:
190 if type in gstate:
191 ydatanow=self.vector_y[n.name][type][step]
192 ydataprev=self.vector_y[n.name][type][step - 1]
193 if ydatanow - ydataprev < -0.1:
194 str = str + n.name + "\'s " + type + " is dropping significantly.\n"
195 if ydatanow - ydataprev > 0.1:
196 str = str + n.name + "\'s " + type + " is increasingly significantly.\n"
197 return str
198
199
201 n = self.entities[name]
202
203 self.newFile()
204 if type is None:
205 type = self.rel
206 else:
207 self.rel = type
208 self.entity = n
209 self.scrotxt.clear()
210 if type == n._supportFeature:
211 for c in self.entities.members():
212 if n.name != c.name:
213 curvename = c.name
214 self.g.line_create(curvename,
215 xdata=self.vector_x,
216 ydata=self.vector_y[n.name][c.name],
217 color=self.color[c.name],
218 dashes=0,
219 linewidth=2,
220 symbol='plus')
221 self.g.configure(title=n.name + ': Support for')
222 if self.step > 0:
223 self.scrotxt.component('text').insert('end', self.trend(n.name, self.step, n._supportFeature),('bolden'))
224
225 else:
226 for c in gstate:
227 curvename = c
228 self.g.line_create(curvename,
229 xdata=self.vector_x,
230 ydata=self.vector_y[n.name][c],
231 color=self.color[c],
232 dashes=0,
233 linewidth=2,
234 symbol='plus')
235 if self.step > 0:
236 self.scrotxt.component('text').insert('end', self.trend(n.name, self.step, c),('bolden'))
237
238 self.g.configure(title=n.name + ': State')
239
240
242 if type == 'State':
243 type = 'state'
244 if type == 'Support_For':
245 type = entity._supportFeature
246
247 self.docurves(self.entity.name, type)
248
249
250 - def adddata(self,step, types=None):
251 self.step = step
252 if not types:
253 types = gstate + ['_liking']
254 self.vector_x.append(step)
255 for type in types:
256 if type in ['_liking']:
257 for n in self.entities.members():
258 for n2 in self.entities.members():
259 if n.name != n2.name:
260 try:
261 self.vector_y[n.name][n2.name].append(n.getBelief(n2,type).mean())
262 except KeyError,e:
263 print n.name,n2.name
264
265 else:
266 for n in self.entities.members():
267 try:
268 n.getStateTotal(type,self.entities)
269 except KeyError:
270 print "Missing state info:", n.name, type
271 else:
272 tot,exp = n.getStateTotal(type,self.entities)
273 mean = tot.mean()
274 self.vector_y[n.name][type].append(mean)
275
276 self.saveHistory()
277 tickList = (0.,1.)
278 for i in range(1,len(self.vector_x)):
279 tickList = tickList + (float(i+1),)
280 self.g.xaxis_configure(majorticks=tuple(tickList))
281
283 if not typeList:
284 typeList = gstate + ['_liking']
285 del self.vector_x[:]
286 for type in typeList:
287 if type in ['_liking']:
288 for n in self.entities.members():
289 for n2 in self.entities.members():
290 if n.name != n2.name:
291 del self.vector_y[n.name][n2.name][:]
292 else:
293 for n in self.entities.members():
294 del self.vector_y[n.name][type][:]
295
296
298 global symbols
299 symbols = not symbols
300
301 for curvename in self.g.element_show():
302 if symbols:
303 self.g.element_configure(curvename, symbol='diamond')
304 else:
305 self.g.element_configure(curvename, symbol='')
306
307
309 if self.smoothing == 'linear': self.smoothing='quadratic'
310 elif self.smoothing == 'quadratic': self.smoothing='natural'
311 elif self.smoothing == 'natural': self.smoothing='step'
312 else: self.smoothing = 'linear'
313
314 for curvename in self.g.element_show():
315 self.g.element_configure(curvename, smooth=self.smoothing)
316
317
318
319 if __name__ == '__main__':
320 master = Tk()
321
322 g = Pmw.Blt.Graph(master)
323 g.pack(expand=1,fill=BOTH)
324 vector_x = Pmw.Blt.Vector()
325 vector_y = Pmw.Blt.Vector()
326
327
328
329 g.line_create('Graph',
330 xdata=vector_x,
331 ydata=vector_y)
332 g.xaxis_configure(min="0.0")
333 g.xaxis_configure(subdivisions="1")
334 tickList = (0.,1.)
335 for i in range(1,len(vector_x)):
336 tickList = tickList + (float(i+1),)
337 g.xaxis_configure(majorticks=tuple(tickList))
338 g.xaxis_configure(title="Time")
339 g.xaxis_configure(stepsize="1.0")
340 try:
341 master.mainloop()
342 except KeyboardInterrupt:
343 pass
344