[Image-SIG] Palette fill on lines?
Deirdre Saoirse Moen
deirdre@deirdre.net
Mon, 13 May 2002 21:30:53 -0700
BTW, got all the code working. For the picture it generates, see the page:
http://fuzzyorange.com/stats-month.php
It pulls from the same data shown tabularly on the page (stored in a
mysql database).
As this may be of interest to others, code is below. Feel free to use
in any manner except ridicule. :)
import Image
import ImageDraw
import ImageFont
import MySQLdb
class loggraph:
def __init__(self):
self.db = None
self.cursor = None
self.im = None
self.lg = None
self.curfont = None
self.imright = 0
self.imtop = 0
self.left = 0
self.right = 0
self.top = 0
self.bottom = 0
self.chartmax = 0
self.months = []
self.hits = []
self.indexhits = []
self.xpoints = []
def dbinit(lg):
# change if you need different parameters obviously
host = 'localhost'
db = 'destash_log'
user = 'foo'
passwd = 'bar'
lg.db = MySQLdb.connect(db=db, host=host, user=user, passwd=passwd)
lg.cursor = lg.db.cursor()
def drawBackground(lg):
lg.imright = 500
lg.imbottom = 305
lg.left = 50
lg.right = lg.imright - 10
lg.top = 10
lg.bottom = lg.imbottom - 35
lg.im = Image.new("P", (lg.imright, lg.imbottom), 0)
lg.im.putpalette([
255, 255, 255, # white background
127, 127, 127, # grey lines
0, 0, 0, # black axes
255, 0, 0, # index 3 is red
255, 255, 0, # index 4 is yellow
255, 153, 0, # index 5 is orange
0, 0, 255, # index 6 is blue
])
lg.d = ImageDraw.ImageDraw(lg.im)
lg.curfont = ImageFont.load('/usr/share/fonts/courB08.pil')
lg.d.setfill(1)
# draw outside box
lg.d.setink(2)
lg.d.setfill(0)
lg.d.rectangle((0, 0, lg.imright-1, lg.imbottom-1))
# draw inner box
lg.d.rectangle((lg.left, lg.top, lg.right, lg.bottom))
# make lines
lg.d.setink(4)
lg.d.setfill(1)
ys = (lg.chartmax / 500) - 1
for i in xrange(500, lg.chartmax, 500):
y = int((((lg.bottom - lg.top) / ys) * (i/500)) + lg.top)
lg.d.line((lg.left, y) + (lg.right, y), fill=128)
#d.line((0, 0) + im.size, fill=128)
def getChartMax(lg):
# we can't do complex statements in mysql, so we'll have to
# walk through the results. That's OK, we need to keep the
# results for later anyway
stmt = "select logdate, sum(hits) from logmonth where url = '/' or url = "
stmt = stmt + "'index-ebay.php' or url = '' or url = 'index.php' "
stmt = stmt + "group by logdate order by logdate"
lg.cursor.execute(stmt)
try:
resultSet = lg.cursor.fetchall()
for i in xrange(0, len(resultSet)):
lg.months.append(resultSet[i][0])
lg.indexhits.append(int(resultSet[i][1]))
except:
pass
stmt = "select logdate, sum(hits) from logmonth "
stmt = stmt + "group by logdate order by logdate"
lg.cursor.execute(stmt)
try:
resultSet = lg.cursor.fetchall()
for i in xrange(0, len(resultSet)):
lg.hits.append(int(resultSet[i][1]))
if (resultSet[i][1] > lg.chartmax):
lg.chartmax = int(resultSet[i][1])
except:
pass
lg.chartmax = float((((lg.chartmax / 500 ) + 1 ) * 500))
def calcXPoints(lg):
# assume we want to space evenly across n spaces
interval = (lg.right - lg.left) / len(lg.hits)
for i in xrange(0, len(lg.hits)):
lg.xpoints.append((interval * i) + (interval / 2) + lg.left)
def convertToY(lg, val):
y = (1 -(val / lg.chartmax)) * (lg.bottom - lg.top)
y += lg.top
return y
def drawLabels(lg):
lg.d.setfill(0)
lg.d.setink(6)
for i in xrange(0, len(lg.hits)):
lg.d.line((lg.xpoints[i], lg.bottom-2)+ (lg.xpoints[i], lg.bottom+2))
texts = lg.d.textsize(lg.months[i], font=lg.curfont)
lg.d.text((lg.xpoints[i] - (texts[0]/2), lg.bottom + 8),
lg.months[i], font=lg.curfont)
sections = ((lg.bottom - lg.top) / 20) -1
sectsize = int (lg.chartmax / (sections + 1))
for i in xrange(0, sections + 2):
val = lg.chartmax - (i * sectsize)
val = '%d' % (val,)
texts = lg.d.textsize(val, font=lg.curfont)
lg.d.text((lg.left - texts[0] - 4, lg.top + (i * 20) - 5), val,
font=lg.curfont)
def drawHits(lg):
for i in xrange(0, len(lg.hits) - 1):
# we have the x for each value, so draw lines
lg.d.setfill(0)
lg.d.setink(6)
lg.d.line((lg.xpoints[i], convertToY(lg, lg.hits[i]))
+ (lg.xpoints[i+1], convertToY(lg, lg.hits[i+1])))
lg.d.setfill(0)
lg.d.setink(3)
lg.d.line((lg.xpoints[i], convertToY(lg, lg.indexhits[i]))
+ (lg.xpoints[i+1], convertToY(lg, lg.indexhits[i+1])))
def drawGraph(lg):
getChartMax(lg)
drawBackground(lg)
calcXPoints(lg)
drawLabels(lg)
drawHits(lg)
def saveImage(lg):
lg.im.save("stats.gif")
if __name__ == '__main__':
lg = loggraph()
db = dbinit(lg)
drawGraph(lg)
saveImage(lg)
--
_Deirdre Stash-o-Matic: http://fuzzyorange.com http://deirdre.net
"I'm writing a book. I've got the page numbers done." - Steven Wright