#! /usr/bin/env python

from zplot import *

# populate zplot table from data file
t = table('verticalbars.data')

# create the postscript file we'll use as our canvas
canvas = svg('verticalbars.svg')

# on the x-axis, we want categories, not numbers.  Thus, we
# determine the number of categories by checking the max
# "rownumber" (a field automatically added by zplot).  We want a
# half bar width (0.5) to the left and right of the bar locations
# so we don't overflow the drawable.
d = drawable(canvas, xrange=[-0.5,t.getmax('rownumber')+0.5], yrange=[0,80])

# xmanual is a list of the form [(label1,x1), (label2,x2), ...].
# We want to use the "op" field from the data file as our labels
# and use "rownumber" as our x coordinate.
axis(d, xtitle='Operation', xmanual=t.query(select='op,rownumber'),
     ytitle='Latency (ms)', yauto=[0,80,20])

# we are going to create several bars with similar arguments.  One
# easy way to do this is to put all the arguments in a dict, and
# use Python's special syntax ("**") for using the dict as named
# args.  Then we can tweak the args between each call to
# verticalbars.
#
# yfield determines the bar height, and stackfields determines
# where the bottom of a bar starts.  This is useful for showing
# several bar sections to indicate a breakdown.  After the first
# bar, we append the previous yfield to stackfields to stack the bars.
p = plotter()
L = legend()
barargs = {'drawable':d, 'table':t, 'xfield':'rownumber',
           'linewidth':0.5, 'fill':True, 'barwidth':0.8,
           'legend':L, 'stackfields':[]}

# compute bar
barargs['yfield'] = 'compute'
barargs['legendtext'] = 'CPU'
barargs['fillcolor'] = 'red'
p.verticalbars(**barargs)

# network bar
barargs['stackfields'].append(barargs['yfield'])
barargs['yfield'] = 'network'
barargs['legendtext'] = 'Net'
barargs['fillcolor'] = 'green'
p.verticalbars(**barargs)

# storage bar
barargs['stackfields'].append(barargs['yfield'])
barargs['yfield'] = 'storage'
barargs['legendtext'] = 'Disk'
barargs['fillcolor'] = 'blue'
p.verticalbars(**barargs)

# we want legend entries to be all on one line.  Thus, we use
# skipnext=1 to get one row.  We specify the horizontal space
# between legend symbols (not considering text) with skipspace.
L.draw(canvas, coord=[d.left()+30, d.top()-5], skipnext=1, skipspace=40)
  
canvas.render()