NOTE:
This project is no longer being maintained: it was developed for my masters thesis, which was completed in early 1997. I still, however, welcome any questions or comments that people may have.

Source Code for iHTML Statistics Display Demo


# Collect user interaction statistics from remote server, and
# display as a nice graphical bar-chart.

# Set host and port to connect with.
DEFHOST = 'www.cs.orst.edu'
DEFPORT = 55571

# Get the standard Python modules that are used.
import string

# Get the iHTML modules that are used.
import ihEvent,ihApp,ihURL

MODE_READY = 0
MODE_VIEW = 1

class StatsCollector(ihURL.LineURL):

    def __init__(self,doc,server,*args):

	self.div_stats = None
	self.total_time = 0.0
	self.mode = MODE_READY
	ihURL.LineURL.__init__(self,doc,server)
	result = (self.GetStatus(),self.GetURL())
	self.sock_result = `result`
	self.sock_address = self.GetURL()

	self.Write("* watch\n")

    def OnLine(self,lines):
	for i in lines:
	    cmds = string.split(i)
	    if( cmds and cmds[0] == '>' ):
		if( self.mode == MODE_VIEW ):
		    if( cmds[1] == 'total' ):
			self.total_time = string.atof(cmds[2])
		    elif( cmds[1] == 'div' ):
			self.div_stats.append(string.atof(cmds[2]))
		    elif( cmds[1] == 'end' and cmds[2] == 'view' ):
			self.mode = MODE_READY
			self.OnNewData()
		elif( cmds[1] == 'begin' and cmds[2] == 'view' ):
		    self.div_stats = []
		    self.mode = MODE_VIEW

class ihEmbed(ihApp.Application,StatsCollector):

    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 arguments
	if( args.has_key('Server') ):
	    self.server = args['Server']
	else:
	    self.server = 'tcp://'+DEFHOST+':'+`DEFPORT`

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

	StatsCollector.__init__(self,self._Document_,self.server)

    def OnNewData(self):
	self.num = len(self.div_stats)
	self.current = []  # [ barvalue, currentvalue, topy, width ]
	self.area_h = self.inner_h / self.num
	self.bar_h = (self.area_h*2)/3
	if( self.bar_h < (self.fh+2) ): self.bar_h = self.fh+2
	if( self.bar_h > self.area_h ): self.bar_h = self.area_h
	self.maxval = 0.0
	top = (self.area_h-self.bar_h)/2
	for i in self.div_stats:
	    texty = top + (self.bar_h/2) - (self.fh/2) + self.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

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

	self.draw_bars()
	self.redraw()

    def draw_bars(self):
	x, y, width, height = self.buffer.Dimensions()
	self.buffer.ForePen(self.background)
	self.buffer.FillRectangle(0,0,width,height)
	for i in self.current:
	    x, y, w, h = 1, i[2], i[3], self.bar_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 redraw(self):
	self.Paste(0,0,self.buffer)
	self.Flush()

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

__export__ = ['ihEmbed']

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

This web page and all material contained herein is Copyright (c) 1997 Dianne Hackborn, unless otherwise noted. All rights reserved.