def _create_pie(self, cr, uid, ids, report, fields, results, context): pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') ar = area.T(size=(350, 350), legend=legend.T(), x_grid_style=None, y_grid_style=None) colors = map(lambda x: fill_style.Plain(bgcolor=x), misc.choice_colors(len(results))) if reduce(lambda x, y: x + y, map(lambda x: x[1], results)) == 0.0: raise UserError( _("The sum of the data (2nd field) is null.\nWe can't draw a pie chart !" )) plot = pie_plot.T(data=results, arc_offsets=[0, 10, 0, 10], shadow=(2, -2, fill_style.gray50), label_offset=25, arrow_style=arrow.a3, fill_styles=colors) ar.add_plot(plot) ar.draw(can) can.close() self.obj = external_pdf(pdf_string.getvalue()) self.obj.render() pdf_string.close() return True
def __init__(self, data, file_name, title, author=None, format="ps"): #定义图标格式theme.get_options()中定义众多默认值,也可以指定phonto name和 format #"d:co:f:", ["format=", "output=", "color=","scale=", "font-family=", "font-size=","line-width=", "debug-level=", #"title=", "author=", "creation_date=", "creator=", "bbox="] args = ["--title=%s" % title, "--color=yes", "--font-size=10", "--output=%s.%s" %(file_name, format), "--debug-level=0"] theme.get_options(argv=args) #canvas函数,定义canvas名称和格式, 读取theme中定义的环境变量如title self.can = canvas.init(fname=file_name+"."+format, format=format) self.data = data
def __init__(self, data, file_name, title, author=None, format="ps"): #定义图标格式theme.get_options()中定义众多默认值,也可以指定phonto name和 format #"d:co:f:", ["format=", "output=", "color=","scale=", "font-family=", "font-size=","line-width=", "debug-level=", #"title=", "author=", "creation_date=", "creator=", "bbox="] args = [ "--title=%s" % title, "--color=yes", "--font-size=10", "--output=%s.%s" % (file_name, format), "--debug-level=0" ] theme.get_options(argv=args) #canvas函数,定义canvas名称和格式, 读取theme中定义的环境变量如title self.can = canvas.init(fname=file_name + "." + format, format=format) self.data = data
def detailchart(self, chartable): theme.reinitialize() min_y = 0 max_y = 0 capture = chartable.get('capture') for sortname, sortfn in self.sorts: data = capture[sortname] m = median(data) if m > max_y: max_y = m max_x = max(self.limits) min_x = min(self.limits) ipoints = 10.0 x_interval = (max_x - min_x) / ipoints y_interval = (max_y - min_y) / ipoints xaxis = axis.X(label='Limit', tic_interval = x_interval, format='/4{}%d') yaxis = axis.Y(label='Seconds', tic_interval = y_interval, format='/4{}%0.3f') ar = area.T( x_range = (min_x, max_x), y_range = (min_y, max_y), x_axis = xaxis, y_axis = yaxis, legend = legend.T(), ) tb = text_box.T(loc=(140,90), text='Rlen\n%s' % chartable['rlen']) for sortname, sortfn in self.sorts: data = capture[sortname] linedata = [ (self.limits[x], data[x]) for x in range(len(data)) ] ar.add_plot( line_plot.T(label="%s" % sortname, data=linedata) ) fd = open('detail-%s-%s.pdf' % (self.dbkey, chartable['rlen']), 'w') can = canvas.init(fd, 'pdf') ar.draw(can) tb.draw(can) can.close()
def _create_pie(self, cr, uid, ids, report, fields, results, context): pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') ar = area.T(size=(350,350), legend=legend.T(), x_grid_style = None, y_grid_style = None) colors = map(lambda x:fill_style.Plain(bgcolor=x), misc.choice_colors(len(results))) if reduce(lambda x,y : x+y, map(lambda x : x[1],results)) == 0.0: raise UserError(_("The sum of the data (2nd field) is null.\nWe can't draw a pie chart !")) plot = pie_plot.T(data=results, arc_offsets=[0,10,0,10], shadow = (2, -2, fill_style.gray50), label_offset = 25, arrow_style = arrow.a3, fill_styles=colors) ar.add_plot(plot) ar.draw(can) can.close() self.obj = external_pdf(pdf_string.getvalue()) self.obj.render() pdf_string.close() return True
def create_graph(label_x, label_y, data_x, alldata_y, filename, title, start_date, end_date, start_y, end_y): """ main func """ # alter file name (linpng do not seems to like spaces in filenames filename = filename.replace(' ', '_') # Graph style theme.get_options() theme.use_color = True theme.default_font_size = 12 theme.default_font_family = "AvantGarde-Book" theme.reinitialize() colors = [ color.blue, color.red, color.green, color.magenta, color.cyan1, color.orange, ] can = canvas.init("%s" % filename) # Draw graph title newtitle = "/hL/20%s" % title left = WIDTH / 2 - font.text_width(newtitle) / 2 can.show(left, HEIGHT + DELTA, newtitle) int_to_date = lambda x: '/a60{}' + time.strftime("%H:%M", time.localtime(x) ) xaxis = axis.X(format=int_to_date, label="/20%s" % label_x, label_offset=(0, -DELTA), minor_tic_interval=X_MINOR_TICK_INTERVAL, tic_interval=X_TICK_INTERVAL) yaxis = axis.Y( label="/20%s" % label_y, label_offset=(-DELTA, 0), minor_tic_interval=(end_y - start_y) / 20, tic_interval=(end_y - start_y) / 5, ) ar = area.T(size=(WIDTH, HEIGHT), x_axis=xaxis, y_axis=yaxis, x_grid_style=line_style.gray70_dash3, x_range=(start_date, end_date), y_range=(start_y, end_y), x_grid_interval=X_GRID_INTERVAL, y_grid_interval=(end_y - start_y) / 5) i = 0 # Draw a line for each columns for title, data_y in alldata_y.iteritems(): plot = line_plot.T(label=title, data=zip(data_x, data_y), line_style=line_style.T(color=colors[i], width=1)) ar.add_plot(plot) i += 1 ar.draw() can.close() return True
def create_graph(label_x, label_y, data_x, alldata_y, filename, title, start_date, end_date): # alter file name (linpng do not seems to like spaces in filenames filename = filename.replace(' ', '_') # Graph style theme.get_options() theme.use_color = True theme.default_font_size = 12 theme.default_font_family = "AvantGarde-Book" theme.reinitialize() colors = [ color.blue, color.red, color.green, color.magenta, color.cyan1, color.orange, ] can = canvas.init("%s"%filename) # Draw graph title newtitle = "/hL/20%s"%title left = WIDTH / 2 - font.text_width(newtitle)/2 can.show(left, HEIGHT + DELTA, newtitle) zip(data_x) int_to_date = lambda x: '/a60{}' + time.strftime("%H:%M", time.localtime(x)) xaxis = axis.X( format = int_to_date, label = "/20%s" % label_x, label_offset = (0, -DELTA), minor_tic_interval = X_MINOR_TICK_INTERVAL, tic_interval = X_TICK_INTERVAL ) yaxis = axis.Y( label = "/20%s" % label_y, label_offset = (-DELTA, 0), minor_tic_interval = Y_MINOR_TICK_INTERVAL, tic_interval = Y_TICK_INTERVAL ) ar = area.T( size = (WIDTH, HEIGHT), x_axis = xaxis, y_axis = yaxis, x_grid_style = line_style.gray70_dash3, x_range = (start_date, end_date), y_range = (0, Y_MAX), x_grid_interval = X_GRID_INTERVAL, y_grid_interval = Y_GRID_INTERVAL ) i = 0 # Draw a line for each columns for title, data_y in alldata_y.iteritems(): plot = line_plot.T( label = title, data = zip(data_x,data_y), line_style = line_style.T( color = colors[i], width = 1 ) ) ar.add_plot(plot) i += 1 ar.draw() can.close() return True
def comparisonchart(self, sortname1, sortname2): linedata = [] test_total = 0 test_wrong = 0 for rlendata in self.main: rlen = rlendata['rlen'] capture = rlendata['capture'] values1 = capture[sortname1] values2 = capture[sortname2] doc_ratio = rlen / float(self.numdocs) cutoff = None wins = [] #test = sortname1 == 'fwscan' and sortname2 in ('nbest', 'timsort') #test_fn = fwscan_wins test = sortname1 == 'nbest' and sortname2 == 'timsort' test_fn = nbest_ascending_wins for x in xrange(0, min(len(values1), len(values2))): t1 = values1[x] t2 = values2[x] limit = self.limits[x] limitratio = limit / float(self.numdocs) won = t1 < t2 if won: wins.append(limit) wrongmsg = "wrong %s? rlen %s, limit %s (%0.5f > %0.5f)%s" if test: test_total += 1 curvewin = test_fn(limit, rlen, self.numdocs) if won and (not curvewin): extra = '' if (t1 / t2) < .90: # more than 10% difference extra = " * (%0.2f)" % (t1/t2) print wrongmsg % ('curvelose', rlen, limit, t2, t1, extra) test_wrong +=1 elif (not won) and curvewin: extra = '' if (t2 / t1) < .90: # more than 10% difference extra = " * (%0.2f)" % (t2/t1) print wrongmsg % ('curvewin', rlen, limit, t1, t2, extra) test_wrong +=1 for limit in wins: limitratio = limit / float(self.numdocs) linedata.append((doc_ratio, limitratio)) if test: if test_total: test_right = test_total - test_wrong test_percent = test_right / float(test_total) print "test percentage %0.2f: (%s wrong out of %s)" % ( test_percent, test_wrong, test_total) comparename = 'compare-%s-%s-beats-%s' % (self.dbkey, sortname1, sortname2) xaxis=axis.X(label='Doc Ratio (rlen//numdocs)', tic_interval=.1, format='/4{}%0.2f') yaxis=axis.Y(label='Limit Ratio (limit//numdocs)', tic_interval=.1, format='/4{}%0.2f') ar = area.T( x_range = (0, 1), y_range = (0, 1), x_axis = xaxis, y_axis = yaxis, legend = legend.T(), ) ar.add_plot( line_plot.T(label="%s \nbeats \n%s" % (sortname1, sortname2), data=linedata), ) tb = text_box.T(loc=(140,90), text='Numdocs\n%s' % self.numdocs) fd = open('%s.pdf' % comparename, 'w') can = canvas.init(fd, 'pdf') ar.draw(can) tb.draw(can) can.close()
def queuedPies( queued, title, radius, names, titles, size, availCpus, colours, userColour ): # re-order the sorted 'queued' so that the labels fit on the pie better queued = bigSmallOrder( queued ) cpusUsed = 0 doPlot = 0 data = [] colour = [] cnt = 0 plotNum = 0 # limit plots to a maximum, otherwise we could be plotting 10000 cores # worth of jobs on a 1 core machine ie. too many plots to render and draw maxPlots = 100 # loop, adding a new 'queued' plot for each bob worth of nodes for j in range(len(queued)): cpus, cpusList, username = queued[j] #print 'cpus, username', cpus, username cpusUsed += cpus remainder = 0 if cpusUsed >= availCpus: # print 'cpusUsed >= totalCpus', cpusUsed, '>=', totalCpus, ', cpusAvailable', availCpus doPlot = 1 remainder = cpusUsed - availCpus # print 'remainder', remainder if j == len(queued)-1: doPlot = 1 percent = 100.0*float(cpus - remainder)/float(availCpus) stri = username + ' %d%%' % ( percent + 0.5 ) if len(cpusList) == 1: stri += ' (1 job)' else: stri += ' (%d jobs)' % len(cpusList) data.append( ( stri, percent ) ) if username in userColour.keys(): c = userColour[username] else: # used to round-robin the colours, but with many jobs coming and # going it's just a vast amount of colour churn - every update # changes the colours of many running jobs. # so instead choose one colour per user and stick to it. if users # don't like their colour then tough luck if username not in userColourHash.keys(): h = hashlib.md5(username).hexdigest() h = int(h, 16) % len(colours) # random colour number userColourHash[username] = int(h) # cast to int from long c = userColourHash[username] #print c, len(colour), len(colours) colour.append( colours[c] ) while doPlot and plotNum < maxPlots: plotNum += 1 #print 'doing plot, data', data arcOffsets = [] for i in range(len(data)): arcOffsets.append( 0 ) tmpFilename = tempfile.mktemp() n = string.split( tmpFilename, '/' ) # pull off the initial /tmp/ names.append( n[-1] ) titles.append( title ) can = canvas.init( tmpFilename + '.png' ) ar = area.T(size=size, legend=None, x_grid_style = None, y_grid_style = None) # percentages are always out of a total of 100 for these pies queuePlot = myPie( data=data, arc_offsets=arcOffsets, fill_styles=colour, #shadow = (2, -2, fill_style.gray50), #center=( 800, 500 - plotNum*200 ), # radius=100*(totalQueuedCpus/totalCpus), label_fill_style = None, label_offset = 25, radius = radius, # start_angle = 180, arrow_style = arrow.a0 ) ar.add_plot(queuePlot) ar.draw(can) can.close() # flush to file ASAP cpusUsed = 0 doPlot = 0 data = [] colour = [] doPlot = 0 # handle spillover from one queued pie to another # allow one persons queued jobs to be >> machine size... if remainder: cpus = remainder cpusUsed += cpus remainder = 0 if cpusUsed >= availCpus: doPlot = 1 remainder = cpusUsed - availCpus percent = 100.0*float(cpus - remainder)/float(availCpus) stri = username + ' %d%%' % ( percent + 0.5 ) # no job numbers in remainder mode... #if len(cpusList) == 1: # stri += ' (1 job)' #else: # stri += ' (%d jobs)' % len(cpusList) data.append( ( stri, percent ) ) colour.append( colours[c] ) if j == len(queued)-1: # last data doPlot = 1
def plotPie( r, s, q, b, availCpus ): if not doPie: return [], [], [] if availCpus <= 0: availCpus = 1 # return [], [], {} # availCpus is the total number of online/up cpus. # NOTE: offlined nodes that are still running jobs can push the total to >100% ! running, totalCpus, totalGpus = r suspended, totalSuspendedCpus, totalSuspendedGpus = s queued, totalQueuedCpus = q blocked, totalBlockedCpus = b #print 'running', r #print 'suspended', s #print 'queued', q #print 'blocked', b #sys.exit(1) theme.use_color = 1 theme.scale_factor = 1 theme.default_font_size = 12 theme.reinitialize() # filenames in /tmp/ where the png's are written names = [] # titles of the plots ie. Running, Queued, or Blocked titles = [] tmpFilename = tempfile.mktemp() n = string.split( tmpFilename, '/' ) # pull off the initial /tmp/ names.append( n[-1] ) titles.append( 'Running' ) can = canvas.init( tmpFilename + '.png' ) size=( 600, 450 ) ar = area.T(size=size, legend=None, x_grid_style = None, y_grid_style = None) colours = [ fill_style.red, fill_style.darkseagreen, fill_style.blue, fill_style.aquamarine1, fill_style.gray70, fill_style.darkorchid, fill_style.yellow, fill_style.green, fill_style.gray50, fill_style.goldenrod, fill_style.brown, fill_style.gray20 ] pieColours = [ 'red', 'darkseagreen', 'blue', rgbToHex( ( 0.498039, 1.0, 0.831373 ), scaleBy=255 ), # aquamarine1 rgbToHex( ( 0.7, 0.7, 0.7 ), scaleBy=255 ), # gray70 'darkorchid', 'yellow', 'green', rgbToHex( ( 0.5, 0.5, 0.5 ), scaleBy=255 ), # gray50 'goldenrod', 'brown', rgbToHex( ( 0.2, 0.2, 0.2 ), scaleBy=255 ) ] # gray20 # re-order the sorted 'running' so that the labels fit on the pie better if len(running) > 1: lastC, lastClist, lastU = running[-1] if lastU == 'idle': # but keep 'idle' last running = bigSmallOrder( running[:-1] ) running.append( ( lastC, lastClist, lastU ) ) else: running = bigSmallOrder( running ) # need to generate colours for both running and suspended pies because we # can draw those jobs on the node grid. prob wouldn't hurt to extend this to # all jobs? all = [] all.extend(running) all.extend(suspended) #all.extend(queued) #all.extend(blocked) # prescribe the colours for current biggest users. eg. biggest user is always in red userColour = {} # dict of colours that have been used for specific users cnt = 0 for cpus, cpusList, username in all: if username != 'idle': # username could be both in running and suspended, so only take the first (running) if username not in userColour.keys(): userColour[username] = cnt cnt += 1 if cnt == len(colours): break # the rest of the colours are hashes of the username for cpus, cpusList, username in all: if username not in userColourHash.keys(): h = hashlib.md5(username).hexdigest() h = int(h, 16) % len(colours) # random colour number userColourHash[username] = int(h) # cast to int from long if username not in userColour.keys(): userColour[username] = userColourHash[username] data = [] arcOffsets = [] colour = [] for cpus, cpusList, username in running: percent = 100.0*float(cpus)/float(availCpus) stri = username + ' %d%%' % ( percent + 0.5 ) if username != 'idle': if len(cpusList) == 1: stri += ' (1 job)' else: stri += ' (%d jobs)' % len(cpusList) data.append( ( stri, percent ) ) if username != 'idle': arcOffsets.append( 0 ) colour.append( colours[userColour[username]] ) else: arcOffsets.append( 20 ) colour.append( fill_style.white ) # offline nodes that are running jobs can make the total of the pie sum to more # than 100, so use the standard auto-scaling pie chart here. runPlot = pie_plot.T( data=data, arc_offsets=arcOffsets, fill_styles=colour, #shadow = (2, -2, fill_style.gray50), label_fill_style = None, label_offset = 25, arrow_style = arrow.a0 ) ar.add_plot(runPlot) ar.draw(can) can.close() # flush to file ASAP queuedPies( suspended, 'Suspended', 75, names, titles, size, availCpus, colours, userColour ) queuedPies( queued, 'Queued', 60, names, titles, size, availCpus, colours, userColour ) queuedPies( blocked, 'Blocked/Held', 40, names, titles, size, availCpus, colours, userColour ) # map userColour numbers to colour names c = {} for k, v in userColour.iteritems(): c[k] = pieColours[v] return names, titles, c
def comparisonchart(self, sortname1, sortname2): linedata = [] test_total = 0 test_wrong = 0 for rlendata in self.main: rlen = rlendata['rlen'] capture = rlendata['capture'] values1 = capture[sortname1] values2 = capture[sortname2] doc_ratio = rlen / float(self.numdocs) cutoff = None wins = [] #test = sortname1 == 'fwscan' and sortname2 in ('nbest', 'timsort') #test_fn = fwscan_wins test = sortname1 == 'nbest' and sortname2 == 'timsort' test_fn = nbest_ascending_wins for x in xrange(0, min(len(values1), len(values2))): t1 = values1[x] t2 = values2[x] limit = self.limits[x] limitratio = limit / float(self.numdocs) won = t1 < t2 if won: wins.append(limit) wrongmsg = "wrong %s? rlen %s, limit %s (%0.5f > %0.5f)%s" if test: test_total += 1 curvewin = test_fn(limit, rlen, self.numdocs) if won and (not curvewin): extra = '' if (t1 / t2) < .90: # more than 10% difference extra = " * (%0.2f)" % (t1 / t2) print wrongmsg % ('curvelose', rlen, limit, t2, t1, extra) test_wrong += 1 elif (not won) and curvewin: extra = '' if (t2 / t1) < .90: # more than 10% difference extra = " * (%0.2f)" % (t2 / t1) print wrongmsg % ('curvewin', rlen, limit, t1, t2, extra) test_wrong += 1 for limit in wins: limitratio = limit / float(self.numdocs) linedata.append((doc_ratio, limitratio)) if test: if test_total: test_right = test_total - test_wrong test_percent = test_right / float(test_total) print "test percentage %0.2f: (%s wrong out of %s)" % ( test_percent, test_wrong, test_total) comparename = 'compare-%s-%s-beats-%s' % (self.dbkey, sortname1, sortname2) xaxis = axis.X(label='Doc Ratio (rlen//numdocs)', tic_interval=.1, format='/4{}%0.2f') yaxis = axis.Y(label='Limit Ratio (limit//numdocs)', tic_interval=.1, format='/4{}%0.2f') ar = area.T( x_range=(0, 1), y_range=(0, 1), x_axis=xaxis, y_axis=yaxis, legend=legend.T(), ) ar.add_plot( line_plot.T(label="%s \nbeats \n%s" % (sortname1, sortname2), data=linedata), ) tb = text_box.T(loc=(140, 90), text='Numdocs\n%s' % self.numdocs) fd = open('%s.pdf' % comparename, 'w') can = canvas.init(fd, 'pdf') ar.draw(can) tb.draw(can) can.close()
def _create_bars(self, cr, uid, ids, report, fields, results, context): env = openerp.api.Environment(cr, uid, context or {}) pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') can.show(80, 380, '/16/H' + report['title']) process_date = { 'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]), 'M': lambda x: x.split('-')[1], 'Y': lambda x: x.split('-')[0] } ar = area.T(size=(350, 350), x_axis=axis.X(label=fields[0]['name'], format="/a-30{}%s"), y_axis=axis.Y( label=', '.join(map(lambda x: x['name'], fields[1:])))) idx = 0 date_idx = None fct = {} for f in fields: field_id = (f['field_child3'] and f['field_child3'][0]) or ( f['field_child2'] and f['field_child2'][0]) or ( f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0]) if field_id: ttype = env['ir.model.fields'].browse(field_id).ttype if ttype == 'date': date_idx = idx fct[idx] = process_date[report['frequency']] else: fct[idx] = lambda x: x else: fct[idx] = lambda x: x idx += 1 # plot are usually displayed year by year # so we do so if the first field is a date data_by_year = {} if date_idx is not None: for r in results: key = process_date['Y'](r[date_idx]) if key not in data_by_year: data_by_year[key] = [] for i in range(len(r)): r[i] = fct[i](r[i]) data_by_year[key].append(r) else: data_by_year[''] = results nb_bar = len(data_by_year) * (len(fields) - 1) colors = map(lambda x: fill_style.Plain(bgcolor=x), misc.choice_colors(nb_bar)) abscissa = {} for line in data_by_year.keys(): fields_bar = [] # sum data and save it in a list. An item for a fields for d in data_by_year[line]: for idx in range(len(fields) - 1): fields_bar.append({}) if d[0] in fields_bar[idx]: fields_bar[idx][d[0]] += d[idx + 1] else: fields_bar[idx][d[0]] = d[idx + 1] for idx in range(len(fields) - 1): data = {} for k in fields_bar[idx].keys(): if k in data: data[k] += fields_bar[idx][k] else: data[k] = fields_bar[idx][k] data_cum = [] prev = 0.0 keys = data.keys() keys.sort() # cumulate if necessary for k in keys: data_cum.append([k, float(data[k]) + float(prev)]) if fields[idx + 1]['cumulate']: prev += data[k] idx0 = 0 plot = bar_plot.T( label=fields[idx + 1]['name'] + ' ' + str(line), data=data_cum, cluster=(idx0 * (len(fields) - 1) + idx, nb_bar), fill_style=colors[idx0 * (len(fields) - 1) + idx]) ar.add_plot(plot) abscissa.update(fields_bar[idx]) idx0 += 1 abscissa = map(lambda x: [x, None], abscissa) abscissa.sort() ar.x_coord = category_coord.T(abscissa, 0) ar.draw(can) can.close() self.obj = external_pdf(pdf_string.getvalue()) self.obj.render() pdf_string.close() return True
def _create_bars(self, cr, uid, ids, report, fields, results, context): env = odoo.api.Environment(cr, uid, context or {}) pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') can.show(80,380,'/16/H'+report['title']) process_date = { 'D': lambda x: reduce(lambda xx, yy: xx + '-' + yy, x.split('-')[1:3]), 'M': lambda x: x.split('-')[1], 'Y': lambda x: x.split('-')[0] } ar = area.T(size=(350,350), x_axis=axis.X(label = fields[0]['name'], format="/a-30{}%s"), y_axis=axis.Y(label = ', '.join(map(lambda x : x['name'], fields[1:])))) idx = 0 date_idx = None fct = {} for f in fields: field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0]) if field_id: ttype = env['ir.model.fields'].browse(field_id).ttype if ttype == 'date': date_idx = idx fct[idx] = process_date[report['frequency']] else: fct[idx] = lambda x : x else: fct[idx] = lambda x : x idx+=1 # plot are usually displayed year by year # so we do so if the first field is a date data_by_year = {} if date_idx is not None: for r in results: key = process_date['Y'](r[date_idx]) if key not in data_by_year: data_by_year[key] = [] for i in range(len(r)): r[i] = fct[i](r[i]) data_by_year[key].append(r) else: data_by_year[''] = results nb_bar = len(data_by_year)*(len(fields)-1) colors = map(lambda x:fill_style.Plain(bgcolor=x), misc.choice_colors(nb_bar)) abscissa = {} for line in data_by_year.keys(): fields_bar = [] # sum data and save it in a list. An item for a fields for d in data_by_year[line]: for idx in range(len(fields)-1): fields_bar.append({}) if d[0] in fields_bar[idx]: fields_bar[idx][d[0]] += d[idx+1] else: fields_bar[idx][d[0]] = d[idx+1] for idx in range(len(fields)-1): data = {} for k in fields_bar[idx].keys(): if k in data: data[k] += fields_bar[idx][k] else: data[k] = fields_bar[idx][k] data_cum = [] prev = 0.0 keys = data.keys() keys.sort() # cumulate if necessary for k in keys: data_cum.append([k, float(data[k])+float(prev)]) if fields[idx+1]['cumulate']: prev += data[k] idx0 = 0 plot = bar_plot.T(label=fields[idx+1]['name']+' '+str(line), data = data_cum, cluster=(idx0*(len(fields)-1)+idx,nb_bar), fill_style=colors[idx0*(len(fields)-1)+idx]) ar.add_plot(plot) abscissa.update(fields_bar[idx]) idx0 += 1 abscissa = map(lambda x : [x, None], abscissa) abscissa.sort() ar.x_coord = category_coord.T(abscissa,0) ar.draw(can) can.close() self.obj = external_pdf(pdf_string.getvalue()) self.obj.render() pdf_string.close() return True
def create_graph(label_x, label_y, data_x, alldata_y, filename, title, start_date, end_date, start_y, end_y): """ main func """ # alter file name (linpng do not seems to like spaces in filenames filename = filename.replace(" ", "_") # Graph style theme.get_options() theme.use_color = True theme.default_font_size = 12 theme.default_font_family = "AvantGarde-Book" theme.reinitialize() colors = [ color.blue, color.red, color.green, color.magenta, color.cyan1, color.orange, color.darkblue, color.darkred, color.darkgreen, color.darkmagenta, color.darkcyan, color.gold, color.lightblue1, color.orangered, color.lightgreen, color.pink, color.lightcyan, color.goldenrod, color.mistyrose, color.honeydew, color.gainsboro, color.yellow, color.peachpuff, color.turquoise, color.chartreuse1, color.pink, color.brown, color.blue, color.red, color.green, color.magenta, color.cyan1, color.orange, color.darkblue, color.darkred, color.darkgreen, color.darkmagenta, color.darkcyan, color.gold, color.lightblue1, color.orangered, color.lightgreen, color.pink, color.lightcyan, color.goldenrod, color.mistyrose, color.honeydew, color.gainsboro, color.yellow, color.peachpuff, color.turquoise, color.chartreuse1, color.pink, color.brown, ] can = canvas.init("%s" % filename) # Draw graph title newtitle = "/hL/20%s" % title left = WIDTH / 2 - font.text_width(newtitle) / 2 can.show(left, HEIGHT + DELTA, newtitle) int_to_date = lambda x: "/a60{}" + time.strftime("%H:%M", time.localtime(x)) xaxis = axis.X( format=int_to_date, label="/20%s" % label_x, label_offset=(0, -DELTA), minor_tic_interval=X_MINOR_TICK_INTERVAL, tic_interval=X_TICK_INTERVAL, ) yaxis = axis.Y( label="/20%s" % label_y, label_offset=(-DELTA, 0), minor_tic_interval=(end_y - start_y) / 20, tic_interval=(end_y - start_y) / 5, ) ar = area.T( size=(WIDTH, HEIGHT), x_axis=xaxis, y_axis=yaxis, x_grid_style=line_style.gray70_dash3, x_range=(start_date, end_date), y_range=(start_y, end_y), x_grid_interval=X_GRID_INTERVAL, y_grid_interval=(end_y - start_y) / 5, ) i = 0 # Draw a line for each columns for title, data_y in alldata_y.iteritems(): plot = line_plot.T(label=title, data=zip(data_x, data_y), line_style=line_style.T(color=colors[i], width=1)) ar.add_plot(plot) i += 1 ar.draw() can.close() return True