Slightly corrected diagram output
[findit] / src / debs / outdiagram.py
1 #!/usr/bin/env python
2 # -*-coding: utf-8 -*-
3 # vim: sw=4 ts=4 expandtab ai
4
5 from random import random
6 from math import pi, cos, sin, sqrt
7
8 #==============================================================================
9
10 class Cli_Presentation(object):
11     pass
12
13 #==============================================================================
14
15 class Gtk_Presentation(object):
16     def __init__(self, filelist, maxdata=10):
17         import gtk
18         import cairo
19
20         drawing = gtk.DrawingArea()
21
22         # `maxdata` biggest files from list
23         filelist.sort(reverse=True)
24         del filelist[maxdata:]
25         self.filelist = filelist
26
27         # sum of sizes
28         fullsize = sum((f[0] for f in filelist))
29
30         # sectors list
31         sectors = []
32         start_angle = 0
33         for bsize, name, size in filelist:
34             color = self.rand_color()
35             delta_angle = (float(bsize)/fullsize)*2*pi
36             end_angle = start_angle + delta_angle
37             color = self.rand_color()
38             sectors.append((start_angle, end_angle, color))
39             start_angle += delta_angle
40
41         drawing.connect('expose-event', self.expose_event, sectors)
42
43         self.toplevel = drawing
44
45     def expose_event(self, widget, event, sectors):
46         x, y, w, h, _ = widget.window.get_geometry()
47         R = min(w-w/3, h)/2 - 20
48
49         cr = widget.window.cairo_create()   # cairo context
50         cr.translate(w/2-w/6, h/2)          # moving coordinates
51
52         # drawing pie chart
53         for i, (start_angle, end_angle, color) in enumerate(sectors):
54             # drawing sector
55             cr.move_to(0, 0)
56             cr.set_source_rgb(*color)
57             cr.arc(0, 0, R, start_angle, end_angle)
58             cr.fill()
59
60             # to cartesian coordinates
61             delta_angle = end_angle - start_angle
62             x = R/1.7 * cos(start_angle+delta_angle/2)
63             y = R/1.7 * sin(start_angle+delta_angle/2)
64             area = 0.5*(delta_angle*R**2)   # sector area
65
66             # drawing text
67             cr.set_font_size(sqrt(area)/2)  # text size
68             text = str(i+1)                 # text string
69             xbearing, ybearing, textw, texth = cr.text_extents(text)[:4]
70             cr.move_to(x-(xbearing+textw/2), y-(ybearing+texth/2))  # text center
71             cr.set_source_rgb(.3, .3, .3)   # text color
72             cr.show_text(text)
73
74         cr.set_font_size(14)
75         cr.translate(w/2-w/6, -h/2+40)  # moving coordinates
76         cr.move_to(0, 0)
77
78         # drawing files list
79         for i, (bsize, name, size) in enumerate(self.filelist):
80             color = sectors[i][2]
81             cr.set_source_rgb(*color)
82             cr.rectangle(-20, 20*i+3, 14, -14)
83             cr.fill()
84
85             text = str(i+1) + '. ' + name + ' (' + str(size) + ')'
86             cr.move_to(0, 20*i)
87             cr.set_source_rgb(0, 0, 0)
88             cr.show_text(text)
89
90     def rand_color(self):
91         return random(), random(), random()