#!/usr/bin/env python import sys import paint arial = '/win98/windows/fonts/arial.ttf' timesb = '/win98/windows/fonts/timesbd.ttf' black = paint.rgb(0,0,0) red = paint.rgb(0xff, 0, 0) yellow = paint.rgb(0xff, 0xff, 0) image = paint.image(450, 300) def center(y, font, text): xa, ya = font.advance(text) x = (image.width - xa) / 2 image.text(font, int(x), int(y), black, text) return y class BarChart: def __init__(self, image, x, y, width, height): self.image = image self.x = x self.y = y self.width = width self.height = height def text(self, font, x, y, color, text): self.image.text(font, int(x + 0.5), int(y + 0.5), color, text) def left_axis(self, label, tics): image = self.image x = self.x + 0.5 y = self.y + 0.5 image.stroke(paint.line(x, y, x, y + self.height), black, 1) step = float(self.height) / (len(tics) - 1) ty = y + self.height f = paint.font(arial, 8) maxa = 0 for tic in tics: image.stroke(paint.line(x - 4, ty, x, ty), black, 1) if tic: xa, ya = f.advance(tic) if xa > maxa: maxa = xa tx = x - xa - 8 self.text(f, tx, ty + (f.height + f.descent) / 2, black, tic) ty = ty - step if label: f = paint.font(arial, 13, 90) xa, ya = f.advance(label) y = y + (self.height - ya) / 2 x = x - maxa - 12 + f.descent self.text(f, x, y, black, label) def bottom_axis(self, label, tics): image = self.image x = self.x + 0.5 y = self.y + 0.5 self.num_points = len(tics) image.stroke(paint.line(x, y + self.height, x + self.width, y + self.height), black, 1) step = float(self.width) / len(tics) tx = x + step / 2 y = y + self.height f = paint.font(arial, 8) ty = y + 10 + f.height + f.descent for tic in tics: image.stroke(paint.line(tx, y, tx, y + 6), black, 1) if tic: xa, ya = f.advance(tic) self.text(f, tx - xa / 2, ty, black, tic) tx = tx + step if label: y = ty - f.descent + f.line_gap f = paint.font(arial, 13) y = y + f.ascent xa, ya = f.advance(label) self.text(f, (x - xa) / 2, y, black, label) def right_axis(self, label, tics): image = self.image x = self.x + self.width + 0.5 y = self.y + 0.5 image.stroke(paint.line(x, y, x, y + self.height), black, 1) step = float(self.height) / (len(tics) - 1) ty = y + self.height f = paint.font(arial, 8) maxa = 0 for tic in tics: image.stroke(paint.line(x, ty, x + 4, ty), black, 1) if tic: xa, ya = f.advance(tic) if xa > maxa: maxa = xa tx = x + 8 self.text(f, tx, ty + (f.height + f.descent) / 2, black, tic) ty = ty - step if label: f = paint.font(arial, 13, 270) xa, ya = f.advance(label) y = y + (self.height - ya) / 2 x = x + maxa + 12 - f.descent self.text(f, x, y, black, label) def bar_data(self, min, max, values): image = self.image x = self.x + 0.5 y = self.y + 0.5 step = float(self.width) / self.num_points tx = x + step / 2 tw = step * 2 / 3 for i in range(self.num_points): x1 = int(tx - tw / 2) + 0.5 x2 = int(tx + tw / 2) + 0.5 y1 = y + self.height - int(float(values[i]) / (float(max) - min) * self.height) y2 = y + self.height path = paint.rect(x1, y1, x2, y2) image.fill(path, yellow) image.stroke(path, black, 1) tx = tx + step def line_data(self, min, max, values): image = self.image x = self.x + 0.5 y = self.y + 0.5 step = float(self.width) / self.num_points tx = x + step / 2 tw = step * 2 / 3 lx = ly = None for i in range(self.num_points): px = int(tx) + 0.5 py = y + self.height - int((float(values[i]) -min) / (float(max) - min) * self.height) image.stroke(paint.line(px, py - 3, px, py + 3), red, 1) image.stroke(paint.line(px - 3, py, px + 3, py), red, 1) if lx is not None: image.stroke(paint.line(lx, ly, px, py).dash(0, (5, 2)), red, 1) lx, ly = px, py tx = tx + step f = paint.font(timesb, 15) y = f.line_gap center(y + f.ascent, f, 'BHP') y = y + f.height f = paint.font(timesb, 10) center(y + f.ascent, f, 'Volume / Av. Price') chart = BarChart(image, 60, 60, 310, 210) chart.left_axis('Volume', ('0M', '1M', '2M', '3M', '4M', '5M')) chart.bottom_axis(None, ('4/4', '5/4', '6/4', '7/4', '10/4', '11/4')) chart.right_axis('Av. Price', ('18.0', '18.1', '18.2', '18.3', '18.4', '18.5', '18.6', '18.7', '18.8', '18.9')) chart.bar_data(0, 500, (350, 400, 250, 245, 430, 40)) chart.line_data(180, 189, (186.5, 186, 188.5, 187.5, 183.7, 180)) image.write_png('new_bar.png')