cubicweb/web/views/plots.py
changeset 12503 b01dd0ef43aa
parent 11767 432f87a63057
equal deleted inserted replaced
12502:e651d5f24cb5 12503:b01dd0ef43aa
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """basic plot views"""
    18 """basic plot views"""
    19 
    19 
    20 
       
    21 from cubicweb import _
       
    22 
       
    23 from six import add_metaclass
       
    24 from six.moves import range
       
    25 
       
    26 from logilab.common.date import datetime2ticks
       
    27 from logilab.common.deprecation import class_deprecated
       
    28 from logilab.common.registry import objectify_predicate
    20 from logilab.common.registry import objectify_predicate
    29 from logilab.mtconverter import xml_escape
    21 from logilab.mtconverter import xml_escape
    30 
    22 
    31 from cubicweb.utils import UStringIO, json_dumps
    23 from cubicweb.utils import UStringIO
    32 from cubicweb.predicates import multi_columns_rset
    24 from cubicweb.predicates import multi_columns_rset
    33 from cubicweb.web.views import baseviews
    25 from cubicweb.web.views import baseviews
    34 
    26 
    35 @objectify_predicate
    27 @objectify_predicate
    36 def all_columns_are_numbers(cls, req, rset=None, *args, **kwargs):
    28 def all_columns_are_numbers(cls, req, rset=None, *args, **kwargs):
    85 
    77 
    86     def _render(self, *args, **kwargs):
    78     def _render(self, *args, **kwargs):
    87         raise NotImplementedError
    79         raise NotImplementedError
    88 
    80 
    89 
    81 
    90 @add_metaclass(class_deprecated)
       
    91 class FlotPlotWidget(PlotWidget):
       
    92     """PlotRenderer widget using Flot"""
       
    93     __deprecation_warning__ = '[3.14] cubicweb.web.views.plots module is deprecated, use the jqplot cube instead'
       
    94     onload = u"""
       
    95 var fig = jQuery('#%(figid)s');
       
    96 if (fig.attr('cubicweb:type') != 'prepared-plot') {
       
    97     %(plotdefs)s
       
    98     jQuery.plot(jQuery('#%(figid)s'), [%(plotdata)s],
       
    99         {points: {show: true},
       
   100          lines: {show: true},
       
   101          grid: {hoverable: true},
       
   102          /*yaxis : {tickFormatter : suffixFormatter},*/
       
   103          xaxis: {mode: %(mode)s}});
       
   104     jQuery('#%(figid)s').data({mode: %(mode)s, dateformat: %(dateformat)s});
       
   105     jQuery('#%(figid)s').bind('plothover', onPlotHover);
       
   106     fig.attr('cubicweb:type','prepared-plot');
       
   107 }
       
   108 """
       
   109 
       
   110     def __init__(self, labels, plots, timemode=False):
       
   111         self.labels = labels
       
   112         self.plots = plots # list of list of couples
       
   113         self.timemode = timemode
       
   114 
       
   115     def dump_plot(self, plot):
       
   116         if self.timemode:
       
   117             plot = [(datetime2ticks(x), y) for x, y in plot]
       
   118         return json_dumps(plot)
       
   119 
       
   120     def _render(self, req, width=500, height=400):
       
   121         if req.ie_browser():
       
   122             req.add_js('excanvas.js')
       
   123         req.add_js(('jquery.flot.js', 'cubicweb.flot.js'))
       
   124         figid = u'figure%s' % next(req.varmaker)
       
   125         plotdefs = []
       
   126         plotdata = []
       
   127         self.w(u'<div id="%s" style="width: %spx; height: %spx;"></div>' %
       
   128                (figid, width, height))
       
   129         for idx, (label, plot) in enumerate(zip(self.labels, self.plots)):
       
   130             plotid = '%s_%s' % (figid, idx)
       
   131             plotdefs.append('var %s = %s;' % (plotid, self.dump_plot(plot)))
       
   132             # XXX ugly but required in order to not crash my demo
       
   133             plotdata.append("{label: '%s', data: %s}" % (label.replace(u'&', u''), plotid))
       
   134         fmt = req.property_value('ui.date-format') # XXX datetime-format
       
   135         # XXX TODO make plot options customizable
       
   136         req.html_headers.add_onload(self.onload %
       
   137                                     {'plotdefs': '\n'.join(plotdefs),
       
   138                                      'figid': figid,
       
   139                                      'plotdata': ','.join(plotdata),
       
   140                                      'mode': self.timemode and "'time'" or 'null',
       
   141                                      'dateformat': '"%s"' % fmt})
       
   142 
       
   143 
       
   144 @add_metaclass(class_deprecated)
       
   145 class PlotView(baseviews.AnyRsetView):
       
   146     __deprecation_warning__ = '[3.14] cubicweb.web.views.plots module is deprecated, use the jqplot cube instead'
       
   147     __regid__ = 'plot'
       
   148     title = _('generic plot')
       
   149     __select__ = multi_columns_rset() & all_columns_are_numbers()
       
   150     timemode = False
       
   151     paginable = False
       
   152 
       
   153     def call(self, width=500, height=400):
       
   154         # prepare data
       
   155         rqlst = self.cw_rset.syntax_tree()
       
   156         # XXX try to make it work with unions
       
   157         varnames = [var.name for var in rqlst.children[0].get_selected_variables()][1:]
       
   158         abscissa = [row[0] for row in self.cw_rset]
       
   159         plots = []
       
   160         nbcols = len(self.cw_rset.rows[0])
       
   161         for col in range(1, nbcols):
       
   162             data = [row[col] for row in self.cw_rset]
       
   163             plots.append(filterout_nulls(abscissa, data))
       
   164         plotwidget = FlotPlotWidget(varnames, plots, timemode=self.timemode)
       
   165         plotwidget.render(self._cw, width, height, w=self.w)
       
   166 
       
   167 
       
   168 class TimeSeriePlotView(PlotView):
       
   169     __select__ = multi_columns_rset() & columns_are_date_then_numbers()
       
   170     timemode = True
       
   171 
       
   172 
       
   173 try:
    82 try:
   174     from GChartWrapper import Pie, Pie3D
    83     from GChartWrapper import Pie, Pie3D
   175 except ImportError:
    84 except ImportError:
   176     pass
    85     pass
   177 else:
    86 else: