AniBars Source Code


# An animated bar-graph.

# Yes, more comments would be nice. :p

import ihEvent,string,ihApp

class ihEmbed(ihApp.Application):

    def __init__(self,**args):

	apply(ihApp.Application.__init__,(self,),args)

	# Allocate colors, buffer.
	self.red = self.MakeColor(.9,.2,.1)
	self.white = self.MakeColor(1,1,1)
	self.black = self.MakeColor(0,0,0)
	self.background = self.BackPen()
	self.foreground = self.ForePen()
	x, y, width, height = self.Dimensions()
	self.buffer = self.MakePixmap(width,height)
	self.buffer.ForePen(self.background)
	self.buffer.FillRectangle(0,0,width,height)

	# Extract bar arguments
	if( args.has_key('Bars') ):
	    self.bars = eval(args['Bars'])
	    if( type(self.bars) != type(()) ):
		raise TypeError,'"Bars" parameter must be a tuple'

	# Extract update arguments
	if( args.has_key('Steps') ):
	    self.steps = string.atoi(args['Steps'])
	else:
	    self.steps = 50
	if( args.has_key('Rate') ):
	    self.rate = string.atof(args['Rate'])
	else:
	    self.rate = 0.05
	if( args.has_key('Ticks') ):
	    self.ticks = string.atof(args['Ticks'])
	else:
	    self.ticks = 10

	# Find font dimensions
	fw,fh,asc,desc = self.TextExtent('Wg')
	self.frame_w = width
	self.frame_h = height - (fh*2)
	self.tick_y = height - desc - 2
	self.inner_w = self.frame_w - 2
	self.inner_h = self.frame_h - 2

	# Initialize an array to hold current bar values
	self.num = len(self.bars)
	self.current = []  # [ barvalue, currentvalue, topy, width ]
	self.area_h = self.inner_h / self.num
	self.bar_h = (self.area_h*2)/3
	self.maxval = 0.0
	top = (self.area_h-self.bar_h)/2
	for i in self.bars:
	    texty = top + (self.bar_h/2) - (fh/2) + asc
	    self.current.append( [i, 0.0, top, 0.0, texty, "%.2f" % i] )
	    if( self.maxval < i ):
		self.maxval = i
	    top = top + self.area_h
	if( self.maxval <= 0 ):
	    self.maxval = 1.0

	# Set number of steps, and start
	self.curstep = 0

	self.update(1)

    def update(self,restart):
	if( restart ):
	    self.curstep = 0
	    self.draw_scales()

	if( self.curstep < self.steps ):
	    self.call = self.FutureCall(self.rate,self.update,(0,))
	else:
	    self.call = self.FutureCall(10,self.update,(1,))

	cur = self.curstep + 1
	self.curstep = cur

	#print 'Doing step #',cur

	for i in self.current:
	    i[1] = (i[0]*cur)/self.steps
	    i[3] = (self.inner_w*i[1])/self.maxval

	#print 'Ready to draw...'

	self.draw_bars()

	#print 'Updating display...'

	self.redraw()

    def draw_bars(self):
	for i in self.current:
	    x, y, w, h = 1, i[2], i[3], self.bar_h
	    #print 'Drawing bar: (%s,%s) at (%sx%s)' % (x,y,w,h)
	    self.buffer.ForePen(self.red)
	    self.buffer.FillRectangle(x,y,w,h)
	    if( w > 0 ):
		self.buffer.ForePen(self.black)
		self.buffer.DrawLine(x,y+h-1,x+w-1,y+h-1)
		self.buffer.DrawLine(x+w-1,y,x+w-1,y+h-1)
		self.buffer.ForePen(self.white)
		self.buffer.DrawLine(x,y,x+w-1,y)
		self.buffer.DrawLine(x,y,x,y+h-1)
		self.buffer.ForePen(self.foreground)
		self.buffer.DrawText(x+5,i[4],i[5],-1)
	
    def draw_scales(self):
	x, y, width, height = self.Dimensions()
	self.buffer.ForePen(self.background)
	self.buffer.FillRectangle(0,0,width,height)

	# Place the tick marks
	self.tick_marks = []
	for i in range(self.ticks):
	    text = '%.0f' % ((i*self.maxval)/(self.ticks-1))
	    tw,th,ta,td = self.buffer.TextExtent(text)
	    xpos = (i*self.frame_w)/(self.ticks-1) - 1
	    val = (i*self.maxval)/(self.ticks-1)
	    tx = xpos - (tw/2)
	    if( tx < 0 ):
		tx = 0
	    elif( (tx+tw) > self.frame_w ):
		tx = self.frame_w - tw - 1
	    self.tick_marks.append( ( val,
				      xpos,
				      tx, text,
				      ) )
	self.buffer.ForePen(self.foreground)
	for i in self.tick_marks:
	    self.buffer.DrawLine(i[1],0,i[1],self.frame_h-1)
	    self.buffer.DrawText(i[2],self.tick_y,i[3],-1)
	self.buffer.ForePen(self.black)
	self.buffer.DrawLine(0,self.frame_h-1,self.frame_w-1,self.frame_h-1)
	self.buffer.DrawLine(self.frame_w-1,0,self.frame_w-1,self.frame_h-1)
	self.buffer.ForePen(self.white)
	self.buffer.DrawLine(0,0,self.frame_w-1,0)
	self.buffer.DrawLine(0,0,0,self.frame_h-2)

    def redraw(self):
	self.Paste(0,0,self.buffer)

    def OnRedraw(self,ev,x,y,w,h):
	self.redraw()

    def OnMouse(self,ev,x,y,state,hit):

	if( ev.Code == ihEvent.CodeNames['MousePress'] ):
	    if( self.call ):
		self.call.Stop()
	    self.update(1)

_________.oo_Q_Q_oo.____________________________________________
Dianne Kyra Hackborn <hackbod@angryredplanet.com>
Last modified: Wed Aug 14 14:23:04 PDT 1996

This web page and all material contained herein is the fault and Copyright ©1998 Dianne Hackborn, unless otherwise noted. All rights reserved.