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