CHARTS WITH CAIROPLOT
=====================

This test is done with chart generated by CairoPlot. You can find it here:

    http://linil.wordpress.com/2008/09/16/cairoplot-11/

Charts is other important thing in reports. Geraldo is compatible with every
library charts since it has a way to render the chart as a common image format,
like JPG, PNG, GIF, etc.

    >>> import os
    >>> cur_dir = os.path.dirname(os.path.abspath(__file__))

    >>> import Image as PILImage
    >>> from CairoPlot import pie_plot, bar_plot

    >>> from django.contrib.auth.models import User

    >>> from reportlab.lib.pagesizes import A4
    >>> from reportlab.lib.units import cm
    >>> from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY, TA_RIGHT
    >>> from reportlab.lib.colors import navy, yellow, red, white
    
    >>> from geraldo import Report, ReportBand, Label, ObjectValue, SystemField,\
    ...     SubReport, FIELD_ACTION_COUNT, FIELD_ACTION_AVG, FIELD_ACTION_MIN,\
    ...     FIELD_ACTION_MAX, FIELD_ACTION_SUM, FIELD_ACTION_DISTINCT_COUNT,\
    ...     BAND_WIDTH, Rect, Line, Image

Method to get chart

    >>> def get_chart_for_user(graphic):
    ...     data = [dic['id'] for dic in graphic.instance.user_permissions.values('id')]
    ... 
    ...     if not data:
    ...         return None
    ... 
    ...     filename = os.path.join(cur_dir, 'user-chart-%d.png'%graphic.instance.id)
    ... 
    ...     bar_plot(filename, data, 400, 300, border = 20, grid = True, rounded_corners = True)
    ... 
    ...     return PILImage.open(filename)

Report class

    >>> class UsersReport(Report):
    ...     title = 'Using chart from CairoPlot'
    ...     borders = {'all': True}
    ...     default_style = {'fontName': 'Helvetica'}
    ... 
    ...     class band_summary(ReportBand):
    ...         height = 5*cm
    ...         elements = [
    ...             Label(text="Users count:", top=0.1*cm, left=0.2*cm),
    ...             ObjectValue(attribute_name='username', top=0.1*cm, left=4*cm,\
    ...                 action=FIELD_ACTION_COUNT, display_format='%s permissions found'),
    ... 
    ...             Label(text="Users ids average:", top=0.6*cm, left=0.2*cm),
    ...             ObjectValue(attribute_name='id', top=0.6*cm, left=4*cm, action=FIELD_ACTION_AVG),
    ... 
    ...             Label(text="Users ids minimum:", top=1.1*cm, left=0.2*cm),
    ...             ObjectValue(attribute_name='id', top=1.1*cm, left=4*cm, action=FIELD_ACTION_MIN),
    ... 
    ...             Label(text="Users ids maximum:", top=1.6*cm, left=0.2*cm),
    ...             ObjectValue(attribute_name='id', top=1.6*cm, left=4*cm, action=FIELD_ACTION_MAX),
    ... 
    ...             Label(text="Users ids sum:", top=2.1*cm, left=0.2*cm),
    ...             ObjectValue(attribute_name='id', top=2.1*cm, left=4*cm, action=FIELD_ACTION_SUM),
    ... 
    ...             Label(text="Users first name distinct:", top=2.6*cm, left=0.2*cm),
    ...             ObjectValue(attribute_name='first_name', top=2.6*cm, left=4*cm, action=FIELD_ACTION_DISTINCT_COUNT),
    ... 
    ...             Image(filename=os.path.join(cur_dir, 'cairoplot.png'), left=11*cm, top=0.2*cm)
    ...         ]
    ...         borders = {'top': True}
    ... 
    ...     class band_page_footer(ReportBand):
    ...         height = 1*cm
    ...         elements = [
    ...             Label(text='Created with Geraldo Reports', top=0, left=0.5*cm),
    ...             SystemField(expression='Printed in %(now:%Y, %b %d)s at %(now:%H:%M)s  ', top=0,
    ...                 width=BAND_WIDTH, style={'alignment': TA_RIGHT, 'rightIndent': 0.5*cm}),
    ...         ]
    ... 
    ...     class band_detail(ReportBand):
    ...         height = 8.5*cm
    ...         force_new_page = True
    ...         elements = [
    ...             # check why BAND_WIDTH doesn't work XXX
    ...             Rect(width=BAND_WIDTH, height=1.6*cm, left=0, top=0, fill_color=yellow, fill=True, _test_temp=True),
    ...             ObjectValue(attribute_name='username', width=BAND_WIDTH, left=0.4*cm, top=0.4*cm,
    ...                 get_value=lambda instance: instance.get_full_name().strip() or instance.username,
    ...                 style={'fontName': 'Helvetica-Bold', 'fontSize': 16, 'textColor': navy}),
    ...             Image(left=0.5*cm, top=2*cm,
    ...                 get_image=lambda graphic: PILImage.open(os.path.join(cur_dir, '%d.jpg'%graphic.instance.id))),
    ...
    ...             Label(text='First name:', top=2*cm, left=5*cm),
    ...             ObjectValue(attribute_name='first_name', width=BAND_WIDTH, top=2*cm, left=7*cm),
    ...
    ...             Label(text='Last name:', top=2.5*cm, left=5*cm),
    ...             ObjectValue(attribute_name='last_name', width=BAND_WIDTH, top=2.5*cm, left=7*cm),
    ...
    ...             Label(text='Username:', top=3*cm, left=5*cm),
    ...             ObjectValue(attribute_name='username', width=BAND_WIDTH, top=3*cm, left=7*cm),
    ... 
    ...             Image(left=10.5*cm, top=2*cm, get_image=get_chart_for_user),
    ...         ]
    ...         borders = {'bottom': True}
    ...         child_bands = [
    ...             ReportBand(
    ...                 default_style={'textColor': white, 'fontName': 'Helvetica-Bold'},
    ...                 height = 0.6*cm,
    ...                 elements = [
    ...                     Rect(left=0, top=0, width=BAND_WIDTH, height=0.6*cm,
    ...                         fill_color=navy, fill=True, _test_temp=True),
    ...                     Label(text="ID", top=0.1*cm, left=0.5*cm),
    ...                     Label(text="Permission", top=0.1*cm, left=4*cm),
    ...                 ],
    ...                 borders={'bottom': True}),
    ...             ]
    ... 
    ...     subreports = [
    ...         SubReport(
    ...             queryset_string = '%(object)s.user_permissions.all()',
    ...             band_detail = ReportBand(
    ...                     default_style={'fontName': 'Helvetica'},
    ...                     height=0.5*cm,
    ...                     elements=[
    ...                         ObjectValue(attribute_name='id', top=0, left=0.5*cm),
    ...                         ObjectValue(attribute_name='name', top=0, left=4*cm),
    ...                     ],
    ...                     borders={'bottom': True},
    ...                 ),
    ...         ),
    ...     ]

    >>> queryset = User.objects.filter(id__in=[1,5]).order_by('-id')

    >>> report = UsersReport(queryset=queryset)

Creating some users

    >>> len([User.objects.get_or_create(username='Leticia'),
    ... User.objects.get_or_create(username='Tarsila', is_staff=True),
    ... User.objects.get_or_create(username='Mychelle', is_staff=True),
    ... User.objects.get_or_create(username='Mychell', is_staff=True),
    ... User.objects.get_or_create(username='Betty', is_staff=True),
    ... User.objects.get_or_create(username='Marta'),
    ... User.objects.get_or_create(username='Davi'),
    ... User.objects.get_or_create(username='Verinha'),
    ... User.objects.get_or_create(username='Miltinho'),
    ... User.objects.get_or_create(username='Waltinho'),
    ... User.objects.get_or_create(username='Leni')])
    11

Getting data

    >>> from geraldo.generators import PDFGenerator
    >>> report.queryset = queryset

Building the chart

    >>> data = dict([(user['username'], user['id']) for user in report.queryset.values('id', 'username')])
    >>> pie_plot(os.path.join(cur_dir, 'cairoplot.png'), data, 350, 200)

PDF generation

    >>> report.generate_by(PDFGenerator, filename=os.path.join(cur_dir, 'charts-cairoplot-report.pdf'))

