1title = 'Blt Graph demonstration' 2 3# Import Pmw from this directory tree. 4import sys 5sys.path[:0] = ['../../..'] 6 7import string 8import Tkinter 9import Pmw 10 11# Simple random number generator. 12rand = 12345 13def random(): 14 global rand 15 rand = (rand * 125) % 2796203 16 return rand 17 18class 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 194class 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. 233if __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() 242