# Copyright 2008 by Wade Brainerd.
# This file is part of Finance.
#
# Finance is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Finance is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Finance. If not, see .
# Import standard Python modules.
import logging, os, math, time, copy, json, time, datetime, locale
from gettext import gettext as _
# Set up localization.
locale.setlocale(locale.LC_ALL, '')
# Import PyGTK.
import gobject, pygtk, gtk, pango, cairo
# Import Sugar UI modules.
import sugar.activity.activity
from sugar.graphics import *
# Import activity module
import finance
CHART_HELP = _('The Chart view shows the proportion of your expenses that is in each category.\nYou can categorize transactions in the Register view.')
class ChartScreen(gtk.HBox):
def __init__(self, activity):
gtk.HBox.__init__(self)
self.activity = activity
self.category_total = {}
self.sorted_categories = []
self.area = gtk.DrawingArea()
self.area.connect('expose-event', self.chart_expose_cb)
label = gtk.Label()
label.set_markup(''+_('Debit Categories')+'')
self.catbox = gtk.VBox()
box = gtk.VBox()
box.pack_start(gtk.VBox(), False, False, 40)
box.pack_start(label, False, False)
box.pack_start(gtk.HSeparator(), False, False)
box.pack_start(self.catbox, False, False, 10)
box.pack_start(gtk.VBox(), True, True)
self.pack_start(self.area, True, True)
self.pack_start(box, False, False, 40)
self.show_all()
def build(self):
# Build the category totals.
self.category_total = {}
for t in self.activity.visible_transactions:
cat = t['category']
amount = t['amount']
if t['type'] == 'debit':
if not self.category_total.has_key(cat):
self.category_total[cat] = amount
else:
self.category_total[cat] += amount
# Generate a list of names sorted by total.
self.sorted_categories = self.category_total.keys()
#self.sorted_categories.sort(lamba a, b: cmp(self.category_total[a], self.category_total[b]))
# Clear and rebuild the labels box.
for w in self.catbox.get_children():
self.catbox.remove(w)
catgroup = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
amountgroup = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
for c in self.sorted_categories:
hbox = gtk.HBox()
catlabel = gtk.Label()
catlabel.set_markup(c)
catgroup.add_widget(catlabel)
color = finance.get_category_color_str(c)
amountlabel = gtk.Label()
amountlabel.set_markup(locale.currency(self.category_total[c]))
amountgroup.add_widget(amountlabel)
hbox.pack_start(amountlabel, True, True, 20)
hbox.pack_start(catlabel, True, True, 20)
ebox = gtk.EventBox()
ebox.modify_bg(gtk.STATE_NORMAL, ebox.get_colormap().alloc_color(color))
ebox.add(hbox)
self.catbox.pack_end(ebox, False, False, 5)
self.show_all()
# Update the help text.
self.activity.set_help(CHART_HELP)
def chart_expose_cb(self, widget, event):
context = widget.window.cairo_create()
context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
context.clip()
# Draw pie chart.
bounds = widget.get_allocation()
x = bounds.width/2
y = bounds.height/2
r = min(bounds.width, bounds.height)/2 - 10
total = 0
for c in self.sorted_categories:
total += self.category_total[c]
if total != 0:
angle = 0.0
for c in self.sorted_categories:
slice = 2*math.pi * self.category_total[c] / total
color = finance.get_category_color(c)
context.move_to(x, y)
context.arc(x, y, r, angle, angle + slice)
context.close_path()
context.set_source_rgb(color[0], color[1], color[2])
context.fill_preserve()
context.set_source_rgb(0, 0, 0)
context.stroke()
angle += slice