80 return self._stream.getvalue() |
80 return self._stream.getvalue() |
81 |
81 |
82 class FlotPlotWidget(PlotWidget): |
82 class FlotPlotWidget(PlotWidget): |
83 """PlotRenderer widget using Flot""" |
83 """PlotRenderer widget using Flot""" |
84 onload = u""" |
84 onload = u""" |
85 var fig = jQuery("#%(figid)s"); |
85 var fig = jQuery('#%(figid)s'); |
86 if (fig.attr('cubicweb:type') != 'prepared-plot') { |
86 if (fig.attr('cubicweb:type') != 'prepared-plot') { |
87 %(plotdefs)s |
87 %(plotdefs)s |
88 jQuery.plot(jQuery("#%(figid)s"), [%(plotdata)s], |
88 jQuery.plot(jQuery('#%(figid)s'), [%(plotdata)s], |
89 {points: {show: true}, |
89 {points: {show: true}, |
90 lines: {show: true}, |
90 lines: {show: true}, |
91 grid: {hoverable: true}, |
91 grid: {hoverable: true}, |
|
92 /*yaxis : {tickFormatter : suffixFormatter},*/ |
92 xaxis: {mode: %(mode)s}}); |
93 xaxis: {mode: %(mode)s}}); |
93 jQuery("#%(figid)s").bind("plothover", onPlotHover); |
94 jQuery('#%(figid)s').data({mode: %(mode)s, dateformat: %(dateformat)s}); |
|
95 jQuery('#%(figid)s').bind('plothover', onPlotHover); |
94 fig.attr('cubicweb:type','prepared-plot'); |
96 fig.attr('cubicweb:type','prepared-plot'); |
95 } |
97 } |
96 """ |
98 """ |
97 |
99 |
98 def __init__(self, labels, plots, timemode=False): |
100 def __init__(self, labels, plots, timemode=False): |
99 self.labels = labels |
101 self.labels = labels |
100 self.plots = plots # list of list of couples |
102 self.plots = plots # list of list of couples |
101 self.timemode = timemode |
103 self.timemode = timemode |
102 |
104 |
103 def dump_plot(self, plot): |
105 def dump_plot(self, plot): |
104 # XXX for now, the only way that we have to customize properly |
|
105 # datetime labels on tooltips is to insert an additional column |
|
106 # cf. function onPlotHover in cubicweb.flot.js |
|
107 if self.timemode: |
106 if self.timemode: |
108 plot = [(datetime2ticks(x), y, datetime2ticks(x)) for x, y in plot] |
107 plot = [(datetime2ticks(x), y) for x, y in plot] |
109 return json_dumps(plot) |
108 return json_dumps(plot) |
110 |
109 |
111 def _render(self, req, width=500, height=400): |
110 def _render(self, req, width=500, height=400): |
112 if req.ie_browser(): |
111 if req.ie_browser(): |
113 req.add_js('excanvas.js') |
112 req.add_js('excanvas.js') |
120 for idx, (label, plot) in enumerate(zip(self.labels, self.plots)): |
119 for idx, (label, plot) in enumerate(zip(self.labels, self.plots)): |
121 plotid = '%s_%s' % (figid, idx) |
120 plotid = '%s_%s' % (figid, idx) |
122 plotdefs.append('var %s = %s;' % (plotid, self.dump_plot(plot))) |
121 plotdefs.append('var %s = %s;' % (plotid, self.dump_plot(plot))) |
123 # XXX ugly but required in order to not crash my demo |
122 # XXX ugly but required in order to not crash my demo |
124 plotdata.append("{label: '%s', data: %s}" % (label.replace(u'&', u''), plotid)) |
123 plotdata.append("{label: '%s', data: %s}" % (label.replace(u'&', u''), plotid)) |
|
124 fmt = req.property_value('ui.date-format') # XXX datetime-format |
|
125 # XXX TODO make plot options customizable |
125 req.html_headers.add_onload(self.onload % |
126 req.html_headers.add_onload(self.onload % |
126 {'plotdefs': '\n'.join(plotdefs), |
127 {'plotdefs': '\n'.join(plotdefs), |
127 'figid': figid, |
128 'figid': figid, |
128 'plotdata': ','.join(plotdata), |
129 'plotdata': ','.join(plotdata), |
129 'mode': self.timemode and "'time'" or 'null'}) |
130 'mode': self.timemode and "'time'" or 'null', |
|
131 'dateformat': '"%s"' % fmt}) |
130 |
132 |
131 |
133 |
132 class PlotView(baseviews.AnyRsetView): |
134 class PlotView(baseviews.AnyRsetView): |
133 __regid__ = 'plot' |
135 __regid__ = 'plot' |
134 title = _('generic plot') |
136 title = _('generic plot') |