93 lines
3.5 KiB
Python
93 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
import openerp
|
|
|
|
from lxml import etree
|
|
|
|
class GraphView(openerp.addons.web.controllers.main.View):
|
|
_cp_path = '/web_graph/graph'
|
|
|
|
@openerp.addons.web.http.jsonrequest
|
|
def data_get(self, req, model=None, domain=[], context={}, group_by=[], view_id=False, orientation=False, stacked=False, mode="bar", **kwargs):
|
|
obj = req.session.model(model)
|
|
|
|
res = obj.fields_view_get(view_id, 'graph')
|
|
fields = res['fields']
|
|
toload = filter(lambda x: x not in fields, group_by)
|
|
if toload:
|
|
fields.update( obj.fields_get(toload, context) )
|
|
|
|
tree = etree.fromstring(res['arch'])
|
|
|
|
pos = 0
|
|
xaxis = group_by or []
|
|
yaxis = []
|
|
for field in tree.iter(tag='field'):
|
|
if (field.tag != 'field') or (not field.get('name')):
|
|
continue
|
|
assert field.get('name'), "This <field> tag must have a 'name' attribute."
|
|
if (not group_by) and ((not pos) or field.get('group')):
|
|
xaxis.append(field.get('name'))
|
|
if pos and not field.get('group'):
|
|
yaxis.append(field.get('name'))
|
|
pos += 1
|
|
|
|
assert len(xaxis), "No field for the X axis!"
|
|
assert len(yaxis), "No field for the Y axis!"
|
|
|
|
# Convert a field's data into a displayable string
|
|
|
|
ticks = {}
|
|
def _convert_key(field, data):
|
|
if fields[field]['type']=='many2one':
|
|
data = data and data[0]
|
|
return data
|
|
|
|
def _convert(field, data, tick=True):
|
|
if fields[field]['type']=='many2one':
|
|
data = data and data[1]
|
|
elif (fields[field]['type']=='selection') and (type(fields[field]['selection']) in (list, tuple)):
|
|
d = dict(fields[field]['selection'])
|
|
data = d[data]
|
|
if tick:
|
|
return ticks.setdefault(data, len(ticks))
|
|
return data or 0
|
|
|
|
def _orientation(x, y):
|
|
if not orientation:
|
|
return (x,y)
|
|
return (y,x)
|
|
|
|
result = []
|
|
if mode=="pie":
|
|
res = obj.read_group(domain, yaxis+[xaxis[0]], [xaxis[0]], context=context)
|
|
for record in res:
|
|
result.append( {
|
|
'data': [(_convert(xaxis[0], record[xaxis[0]]), record[yaxis[0]])],
|
|
'label': _convert(xaxis[0], record[xaxis[0]], tick=False)
|
|
})
|
|
|
|
elif (not stacked) or (len(xaxis)<2):
|
|
for x in xaxis:
|
|
res = obj.read_group(domain, yaxis+[x], [x], context=context)
|
|
result.append( {
|
|
'data': map(lambda record: _orientation(_convert(x, record[x]), record[yaxis[0]] or 0), res),
|
|
'label': fields[x]['string']
|
|
})
|
|
else:
|
|
xaxis.reverse()
|
|
axis = obj.read_group(domain, yaxis+xaxis[0:1], xaxis[0:1], context=context)
|
|
for x in axis:
|
|
key = x[xaxis[0]]
|
|
res = obj.read_group(domain+[(xaxis[0],'=',_convert_key(xaxis[0], key))], yaxis+xaxis[1:2], xaxis[1:2], context=context)
|
|
result.append( {
|
|
'data': map(lambda record: _orientation(_convert(xaxis[1], record[xaxis[1]]), record[yaxis[0]] or 0), res),
|
|
'label': _convert(xaxis[0], key, tick=False)
|
|
})
|
|
|
|
res = {
|
|
'data': result,
|
|
'ticks': map(lambda x: (x[1], x[0]), ticks.items())
|
|
}
|
|
return res
|
|
|