Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | title = 'Blt Graph demonstration' |
2 | ||
3 | # Import Pmw from this directory tree. | |
4 | import sys | |
5 | sys.path[:0] = ['../../..'] | |
6 | ||
7 | import string | |
8 | import Tkinter | |
9 | import Pmw | |
10 | ||
11 | # Simple random number generator. | |
12 | rand = 12345 | |
13 | def random(): | |
14 | global rand | |
15 | rand = (rand * 125) % 2796203 | |
16 | return rand | |
17 | ||
18 | class GraphDemo(Pmw.MegaToplevel): | |
19 | ||
20 | def __init__(self, parent=None, **kw): | |
21 | ||
22 | # Define the megawidget options. | |
23 | optiondefs = ( | |
24 | ('size', 10, Pmw.INITOPT), | |
25 | ) | |
26 | self.defineoptions(kw, optiondefs) | |
27 | ||
28 | # Initialise the base class (after defining the options). | |
29 | Pmw.MegaToplevel.__init__(self, parent) | |
30 | ||
31 | # Create the graph. | |
32 | self.createWidgets() | |
33 | ||
34 | # Check keywords and initialise options. | |
35 | self.initialiseoptions() | |
36 | ||
37 | def createWidgets(self): | |
38 | # Create vectors for use as x and y data points. | |
39 | self._numElements = 7 | |
40 | self._vectorSize = self['size'] | |
41 | self._vector_x = Pmw.Blt.Vector() | |
42 | self._vector_y = [] | |
43 | for y in range(self._numElements): | |
44 | self._vector_y.append(Pmw.Blt.Vector()) | |
45 | for index in range(self._vectorSize): | |
46 | self._vector_x.append(index) | |
47 | for y in range(self._numElements): | |
48 | self._vector_y[y].append(random() % 100) | |
49 | ||
50 | interior = self.interior() | |
51 | ||
52 | controlFrame = Tkinter.Frame(interior) | |
53 | controlFrame.pack(side = 'bottom', fill = 'x', expand = 0) | |
54 | ||
55 | # Create an option menu for the kind of elements to create. | |
56 | elementtype = Pmw.OptionMenu(controlFrame, | |
57 | labelpos = 'nw', | |
58 | label_text = 'Element type', | |
59 | items = ['bars', 'lines', 'mixed', 'none'], | |
60 | command = self._setelementtype, | |
61 | menubutton_width = 8, | |
62 | ) | |
63 | elementtype.pack(side = 'left') | |
64 | ||
65 | # Create an option menu for the barmode option. | |
66 | barmode = Pmw.OptionMenu(controlFrame, | |
67 | labelpos = 'nw', | |
68 | label_text = 'Bar mode', | |
69 | items = ['normal', 'stacked', 'aligned', 'overlap'], | |
70 | command = self._setbarmode, | |
71 | menubutton_width = 8, | |
72 | ) | |
73 | barmode.pack(side = 'left') | |
74 | ||
75 | # Create an option menu for the smooth option. | |
76 | self.smooth = Pmw.OptionMenu(controlFrame, | |
77 | labelpos = 'nw', | |
78 | label_text = 'Smooth', | |
79 | items = ['linear', 'step', 'natural', 'quadratic'], | |
80 | command = self._setsmooth, | |
81 | menubutton_width = 9, | |
82 | ) | |
83 | self.smooth.pack(side = 'left') | |
84 | ||
85 | # Create an option menu to reverse sort the elements. | |
86 | sortelements = Pmw.OptionMenu(controlFrame, | |
87 | labelpos = 'nw', | |
88 | label_text = 'Order', | |
89 | items = ['normal', 'reverse'], | |
90 | command = self._setsortelements, | |
91 | menubutton_width = 8, | |
92 | ) | |
93 | sortelements.pack(side = 'left') | |
94 | ||
95 | # Create an option menu for the bufferelements option. | |
96 | bufferelements = Pmw.OptionMenu(controlFrame, | |
97 | labelpos = 'nw', | |
98 | label_text = 'Buffering', | |
99 | items = ['buffered', 'unbuffered'], | |
100 | command = self._setbufferelements, | |
101 | menubutton_width = 10, | |
102 | ) | |
103 | bufferelements.pack(side = 'left') | |
104 | ||
105 | # Create a button to add a point to the vector. | |
106 | addpoint = Tkinter.Button(controlFrame, text = 'Add point', | |
107 | command = Pmw.busycallback(self._addpoint)) | |
108 | addpoint.pack(side = 'left', fill = 'x', expand = 0) | |
109 | ||
110 | # Create a button to close the window | |
111 | close = Tkinter.Button(controlFrame, text = 'Close', | |
112 | command = Pmw.busycallback(self.destroy)) | |
113 | close.pack(side = 'left', fill = 'x', expand = 0) | |
114 | ||
115 | # Create the graph and its elements. | |
116 | self._graph = Pmw.Blt.Graph(interior) | |
117 | self._graph.pack(expand = 1, fill = 'both') | |
118 | self._graph.yaxis_configure(command=self.yaxisCommand) | |
119 | elementtype.invoke('mixed') | |
120 | bufferelements.invoke('buffered') | |
121 | ||
122 | def yaxisCommand(self, graph, value): | |
123 | try: | |
124 | num = string.atoi(value) | |
125 | return '%d %3d' % (num * 3, num) | |
126 | except ValueError: | |
127 | num = string.atof(value) | |
128 | return '%g %3g' % (num * 3, num) | |
129 | ||
130 | def _setelementtype(self, type): | |
131 | elements = self._graph.element_names() | |
132 | apply(self._graph.element_delete, elements) | |
133 | ||
134 | if type == 'none': | |
135 | return | |
136 | ||
137 | colorList = Pmw.Color.spectrum(self._numElements) | |
138 | for elem in range(self._numElements): | |
139 | if elem == 0: | |
140 | hue = None | |
141 | else: | |
142 | hue = (elem + 1.0) / self._numElements * 6.28318 | |
143 | foreground = colorList[elem] | |
144 | background = Pmw.Color.changebrightness(self, foreground, 0.8) | |
145 | if type == 'mixed': | |
146 | if elem < self._numElements / 2: | |
147 | bar = 0 | |
148 | else: | |
149 | bar = 1 | |
150 | elif type == 'bars': | |
151 | bar = 1 | |
152 | else: | |
153 | bar = 0 | |
154 | if bar: | |
155 | self._graph.bar_create( | |
156 | 'var' + str(elem), | |
157 | xdata=self._vector_x, | |
158 | ydata=self._vector_y[elem], | |
159 | foreground = foreground, | |
160 | background = background) | |
161 | else: | |
162 | self._graph.line_create( | |
163 | 'var' + str(elem), | |
164 | linewidth = 4, | |
165 | xdata=self._vector_x, | |
166 | ydata=self._vector_y[elem], | |
167 | smooth = self.smooth.getcurselection(), | |
168 | color = foreground) | |
169 | ||
170 | def _setbarmode(self, tag): | |
171 | self._graph.configure(barmode = tag) | |
172 | ||
173 | def _setsmooth(self, tag): | |
174 | for element in self._graph.element_show(): | |
175 | if self._graph.element_type(element) == 'line': | |
176 | self._graph.element_configure(element, smooth = tag) | |
177 | ||
178 | def _setbufferelements(self, tag): | |
179 | self._graph.configure(bufferelements = (tag == 'buffered')) | |
180 | ||
181 | def _setsortelements(self, tag): | |
182 | element_list = list(self._graph.element_show()) | |
183 | if len(element_list) > 1: | |
184 | if (tag == 'normal') == (element_list[-1] != 'var0'): | |
185 | element_list.reverse() | |
186 | self._graph.element_show(element_list) | |
187 | ||
188 | def _addpoint(self): | |
189 | self._vector_x.append(self._vectorSize) | |
190 | for y in range(self._numElements): | |
191 | self._vector_y[y].append(random() % 100) | |
192 | self._vectorSize = self._vectorSize + 1 | |
193 | ||
194 | class Demo: | |
195 | def __init__(self, parent): | |
196 | if not Pmw.Blt.haveblt(parent): | |
197 | message = 'Sorry\nThe BLT package has not been\n' + \ | |
198 | 'installed on this system.\n' + \ | |
199 | 'Please install it and try again.' | |
200 | w = Tkinter.Label(parent, text = message) | |
201 | w.pack(padx = 8, pady = 8) | |
202 | return | |
203 | ||
204 | message = 'This is a simple demonstration of the\n' + \ | |
205 | 'BLT graph widget.\n' + \ | |
206 | 'Select the number of points to display and\n' + \ | |
207 | 'click on the button to display the graph.' | |
208 | w = Tkinter.Label(parent, text = message) | |
209 | w.pack(padx = 8, pady = 8) | |
210 | ||
211 | # Create combobox to select number of points to display. | |
212 | self.combo = Pmw.ComboBox(parent, | |
213 | scrolledlist_items = ('10', '25', '50', '100', '300'), | |
214 | entryfield_value = '10') | |
215 | self.combo.pack(padx = 8, pady = 8) | |
216 | ||
217 | # Create button to start blt graph. | |
218 | start = Tkinter.Button(parent, | |
219 | text = 'Show BLT graph', | |
220 | command = Pmw.busycallback(self.showGraphDemo)) | |
221 | start.pack(padx = 8, pady = 8) | |
222 | ||
223 | self.parent = parent | |
224 | ||
225 | def showGraphDemo(self): | |
226 | size = string.atoi(self.combo.get()) | |
227 | demo = GraphDemo(self.parent, size = size) | |
228 | demo.focus() | |
229 | ||
230 | ###################################################################### | |
231 | ||
232 | # Create demo in root window for testing. | |
233 | if __name__ == '__main__': | |
234 | root = Tkinter.Tk() | |
235 | Pmw.initialise(root) | |
236 | root.title(title) | |
237 | ||
238 | exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) | |
239 | exitButton.pack(side = 'bottom') | |
240 | widget = Demo(root) | |
241 | root.mainloop() |