web/views/plots.py
author Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
Thu, 21 May 2009 16:36:47 +0200
changeset 1891 dd7c1d7715e7
parent 1888 f36d43f00f32
child 1892 fb80d9c434e5
permissions -rw-r--r--
[views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1886
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     1
"""basic plot views
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     2
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     3
:organization: Logilab
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     4
:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL.
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     6
"""
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     7
__docformat__ = "restructuredtext en"
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
     8
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
import os
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    10
import time
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    11
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    12
from simplejson import dumps
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
from logilab.common import flatten
1886
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
    15
from logilab.mtconverter import html_escape
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    17
from cubicweb.utils import make_uid
742
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
    18
from cubicweb.vregistry import objectify_selector
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
from cubicweb.web.views import baseviews
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
742
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
    21
@objectify_selector
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    22
def at_least_two_columns(cls, req, rset, *args, **kwargs):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    23
    if not rset:
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    24
        return 0
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    25
    return len(rset.rows[0]) >= 2
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    26
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    27
@objectify_selector
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    28
def all_columns_are_numbers(cls, req, rset, *args, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
    """accept result set with at least one line and two columns of result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
    all columns after second must be of numerical types"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    for etype in rset.description[0]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
        if etype not in ('Int', 'Float'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
            return 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
    return 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
1886
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
    36
@objectify_selector
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    37
def second_column_is_number(cls, req, rset, *args, **kwargs):
1886
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
    38
    etype = rset.description[0][1]
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
    39
    if etype not  in ('Int', 'Float'):
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
    40
        return 0
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
    41
    return 1
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
    42
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    43
@objectify_selector
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    44
def columns_are_date_then_numbers(cls, req, rset, *args, **kwargs):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    45
    etypes = rset.description[0]
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    46
    if etypes[0] not in ('Date', 'Datetime'):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    47
        return 0
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    48
    for etype in etypes[1:]:
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    49
        if etype not in ('Int', 'Float'):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    50
            return 0
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    51
    return 1
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    52
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    54
def filterout_nulls(abscissa, plot):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    55
    filtered = []
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    56
    for x, y in zip(abscissa, plot):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    57
        if x is None or y is None:
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    58
            continue
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    59
        filtered.append( (x, y) )
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
    60
    return sorted(filtered)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
1891
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    62
def datetime2ticks(date):
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    63
    return time.mktime(date.timetuple()) * 1000
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    64
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    65
class FlotPlotWidget(object):
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    66
    """PlotRenderer widget using Flot"""
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    67
    onload = u'''
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    68
%(plotdefs)s
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    69
jQuery.plot(jQuery("#%(figid)s"), [%(plotdata)s],
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    70
    {points: {show: true},
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    71
     lines: {show: true},
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    72
     grid: {hoverable: true},
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    73
     xaxis: {mode: %(mode)s}});
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    74
jQuery('#%(figid)s').bind('plothover', onPlotHover);
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    75
'''
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    76
    
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    77
    def __init__(self, labels, plots, timemode=False):
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    78
        self.labels = labels
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    79
        self.plots = plots # list of list of couples
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    80
        self.timemode = timemode
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    81
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    82
    def dump_plot(self, plot):
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    83
        # XXX for now, the only way that we have to customize properly
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    84
        #     datetime labels on tooltips is to insert an additional column
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    85
        #     cf. function onPlotHover in cubicweb.flot.js
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    86
        if self.timemode:
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    87
            plot = [(datetime2ticks(x), y, datetime2ticks(x)) for x,y in plot]
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    88
        return dumps(plot)
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    89
    
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    90
    def render(self, req, width=500, height=400, w=None):
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    91
        # XXX IE requires excanvas.js
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    92
        req.add_js( ('jquery.flot.js', 'cubicweb.flot.js') )
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    93
        figid = u'figure%s' % make_uid('foo')
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    94
        plotdefs = []
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    95
        plotdata = []
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    96
        w(u'<div id="%s" style="width: %spx; height: %spx;"></div>' %
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    97
          (figid, width, height))
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    98
        for idx, (label, plot) in enumerate(zip(self.labels, self.plots)):
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
    99
            plotid = '%s_%s' % (figid, idx)
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   100
            plotdefs.append('var %s = %s;' % (plotid, self.dump_plot(plot)))
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   101
            plotdata.append("{label: '%s', data: %s}" % (label, plotid))
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   102
        req.html_headers.add_onload(self.onload %
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   103
                                    {'plotdefs': '\n'.join(plotdefs),
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   104
                                     'figid': figid,
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   105
                                     'plotdata': ','.join(plotdata),
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   106
                                     'mode': self.timemode and "'time'" or 'null'})
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   107
    
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   108
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   109
class PlotView(baseviews.AnyRsetView):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   110
    id = 'plot'
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   111
    title = _('generic plot')
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   112
    __select__ = at_least_two_columns() & all_columns_are_numbers()
1891
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   113
    timemode = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   115
    def call(self, width=500, height=400):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   116
        # prepare data
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   117
        rqlst = self.rset.syntax_tree()
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   118
        # XXX try to make it work with unions
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   119
        varnames = [var.name for var in rqlst.children[0].get_selected_variables()][1:]
1891
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   120
        abscissa = [row[0] for row in self.rset]
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   121
        plots = []
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   122
        nbcols = len(self.rset.rows[0])
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   123
        for col in xrange(1, nbcols):
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   124
            data = [row[col] for row in self.rset]
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   125
            plots.append(filterout_nulls(abscissa, plot))
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   126
        plotwidget = FlotPlotWidget(varnames, plots, timemode=self.timemode)
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   127
        plotwidget.render(self.req, width, height, w=self.w)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   129
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   130
class TimeSeriePlotView(PlotView):
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   131
    __select__ = at_least_two_columns() & columns_are_date_then_numbers()
1891
dd7c1d7715e7 [views][plots] extract the plotting mechanism in an HTMLWidget to make mit more re-usable
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1888
diff changeset
   132
    timemode = True
1886
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   133
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   134
try:
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   135
    from GChartWrapper import Pie, Pie3D
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   136
except ImportError:
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   137
    pass
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   138
else:
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   139
    class PieChartView(baseviews.AnyRsetView):
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   140
        id = 'piechart'
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   141
        pieclass = Pie
1888
f36d43f00f32 [views] plot with flot and get rid of matplotlib
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1886
diff changeset
   142
        __select__ = at_least_two_columns() & second_column_is_number()
1886
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   143
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   144
        def call(self, title=None, width=None, height=None):
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   145
            piechart = self.pieclass([(row[1] or 0) for row in self.rset])
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   146
            labels = ['%s: %s' % (row[0].encode(self.req.encoding), row[1])
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   147
                      for row in self.rset]
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   148
            piechart.label(*labels)
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   149
            if width is not None:
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   150
                height = height or width
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   151
                piechart.size(width, height)
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   152
            if title:
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   153
                piechart.title(title)
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   154
            self.w(u'<img src="%s" />' % html_escape(piechart.url))
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   155
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   156
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   157
    class PieChart3DView(PieChartView):
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   158
        id = 'piechart3D'
f0e28ddba7c5 [views] add pie chart views with google chart / GChartWrapper
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1133
diff changeset
   159
        pieclass = Pie3D