Commit be6dd3b1 authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Add the class StoreForMetric2DView.

parent 7ee82799
......@@ -13,7 +13,10 @@ from datetime import date, timedelta
from gluon.dal import smart_query
from gluon.storage import Storage
from plugin_dbui import Store
from reporting_tools import Report, StoreForListView, StoreForMetric1DView
from reporting_tools import (Report,
StoreForListView,
StoreForMetric1DView,
StoreForMetric2DView)
def list():
......@@ -134,6 +137,7 @@ def metric2D():
"""
metric = db.metrics[request.vars.id_metrics]
selector = virtdb.metric_selector_2D
report = Report(selector, exclude_fields=('category',
'metric',
......@@ -141,83 +145,16 @@ def metric2D():
'period_start',
'year'))
# decode filter condition from the metric
if metric.conditions:
q_conditions = smart_query(db.history, metric.conditions)
# vertical axis
groupfield_v = metric.field_vertical
label_v = groupfield_v.split('.')[-1]
# horizontal axis
groupfield_h = metric.field_horizontal
if groupfield_h == 'year':
label_h = 'year'
values_h = range(report.period_start.year, report.period_end.year + 1)
else:
tablename, fieldname = groupfield_h.split('.')
field_h = db[tablename][fieldname]
label_h = fieldname
rows = db().select(field_h, distinct=True)
values_h = [row[fieldname] for row in rows]
# how to count
counter = report.metric
# configure the Ext.data.ArrayStore
# one column for each horizontal value
cfg = dict()
cfg['data'] = []
cfg['fields'] = [{'name': 'group', 'type': 'string'}]
cfg['sorters'] = ['group']
for value in values_h:
cfg['fields'].append({'name': str(value), 'type': 'float'})
# prepare the intermediate dictionary for each vertical group
# the value is a list containing the group name and the metric
# for each horizontal value
data = {}
# configure the Ext.data.Store
store = StoreForMetric2DView(metric, report)
for value_h in values_h:
report.reset_extra_queries()
report.append_query(q_conditions)
# modify the selector criteria
if groupfield_h == 'year':
report.period_start = date(value_h, 1, 1)
report.period_end = date(value_h, 12, 31)
else:
report.append_query(field_h == value_h)
# for each vertical value build a list.
# it contains the metric for each horizontal value
for di in report.get_metric(groupfield_v):
if di['group'] not in data:
li = [di['group']]
li.extend([""]*len(values_h))
data[di['group']] = li
i = values_h.index(value_h) + 1
data[di['group']][i] = di[counter]
# from the intermediate dictionary
# build the data block of the store
for k in data.iterkeys():
cfg['data'].append(data[k])
# customize the standard view (Ext.grid.Panel)
view = Storage(columns=[], features=[], title=metric.title)
view.columns.append({'text': T(label_v.title()),
view.columns.append({'text': report.metric,
'dataIndex': 'group',
'flex': 0.8})
for value_h in values_h:
for value_h in store.values_h:
view.columns.append({'text': str(value_h),
'dataIndex': str(value_h),
'align': 'right',
......@@ -234,150 +171,4 @@ def metric2D():
# delegate the rendering to the standard view
response.view = 'report/grid.html'
return dict(cfg_store=cfg, view=view)
def metric():
""" build the table showing all metrics per category, code, ...
The group field category, code, ... is defined in the viewport
and send using the baseParams techniques.
"""
report = Report(virtdb.metric_selector, exclude_fields=('category',
'metric',
'period_end',
'period_start',
'year'))
report.append_query(db.events.event == "People")
# alias
groupfield = request.vars.group
tablename, fieldname = groupfield.split('.')
# configure the Ext.data.ArrayStore
cfg = dict()
cfg['data'] = []
cfg['fields'] = [{'name': 'group', 'type': 'string'},
{'name': 'count', 'type': 'float'},
{'name': 'sum_fte', 'type': 'float'},
{'name': 'avg_age', 'type': 'float'}]
cfg['sorters'] = ['group']
# fill the data block
for di in report.get_metric(groupfield):
cfg['data'].append([di['group'], di['count'], di['sum_fte'], di['avg_age']])
# customize the standard view (Ext.grid.Panel)
view = Storage(columns=[], features=[])
view.columns = [{'text': T(fieldname.title()), 'dataIndex': 'group', 'flex': 0.8},
{'text': '∑ person',
'dataIndex': 'count',
'align': 'right',
'flex': 0.5,
'summaryType': 'sum' },
{'text': '∑ fte',
'dataIndex': 'sum_fte',
'align': 'right',
'flex': 0.5,
'format': '0.00',
'summaryType': 'sum',
'xtype': 'numbercolumn'},
{'text': '<age>',
'dataIndex': 'avg_age',
'align': 'right',
'flex': 0.5,
'format': '0.00',
'xtype': 'numbercolumn'}]
view.features = [{'ftype': 'summary'}]
view.columns = json.dumps(view.columns)
view.features = json.dumps(view.features)
response.view = 'report/grid.html'
return dict(cfg_store=cfg, view=view)
def metric_per_year():
""" Build the table showing metric per category / quality as
a function of the year.
The metric, count, sum_fte or avg_age is selected via the
selector.
The group field, category, code is defined in the viewport
and send using the baseParams techniques.
"""
report = Report(virtdb.metric_selector, exclude_fields=('category',
'metric',
'period_end',
'period_start',
'year'))
report.append_query(db.events.event == "People")
# alias
groupfield = request.vars.group
tablename, fieldname = groupfield.split('.')
metric = report.metric
years = range(report.period_start.year, report.period_end.year + 1)
# configure the Ext.data.ArrayStore
cfg = dict()
cfg['data'] = []
cfg['fields'] = [{'name': 'group', 'type': 'string'}]
cfg['sorters'] = ['group']
# prepare the intermediate dictionary for each group
# the value is a list containing the group and the metric
# value for each year
data = {}
for year in years:
# add the column to the store
cfg['fields'].append({'name': str(year), 'type': 'float'})
# modify the selector criterai
report.period_start = date(year, 1, 1)
report.period_end = date(year, 12, 31)
# fill the columns
for di in report.get_metric(groupfield):
if di['group'] not in data:
li = [di['group']]
li.extend([""]*len(years))
data[di['group']] = li
i = years.index(year) + 1
data[di['group']][i] = di[metric]
# from the intermediate dictionary
# build the data block of the store
for k in data.iterkeys():
cfg['data'].append(data[k])
#customize the standard view (Ext.grid.Panel)
view = Storage(columns=[], features=[])
view.columns.append({'text': T(fieldname.title()),
'dataIndex': 'group',
'flex': 0.8})
for year in years:
view.columns.append({'text': str(year),
'dataIndex': str(year),
'align': 'right',
'flex': 0.5,
'format': '0.00',
'summaryType': 'sum',
'xtype': 'numbercolumn'})
view.features.append({'ftype': 'summary'})
view.columns = json.dumps(view.columns)
view.features = json.dumps(view.features)
response.view = 'report/grid.html'
return dict(cfg_store=cfg, view=view)
\ No newline at end of file
return dict(cfg_store=store.as_json(), view=view)
......@@ -7,7 +7,7 @@ import re
from datetime import date, timedelta
from gluon import current
from gluon.dal import Field
from gluon.dal import Field, smart_query
from gluon.storage import Storage
from plugin_dbui import Selector, Store
......@@ -523,4 +523,117 @@ class StoreForMetric1DView(StoreFactory):
"""
self.cfg_store.data.extend(rows)
class StoreForMetric2DView(StoreFactory):
"""Generate the Ext.data.Store configuration for the metric2D view.
"""
def __init__(self, metric, report):
"""
@type metric: gluon.dal.objects.Row
@param metric: the definition of the metric
@type report: Report
@param report:
"""
db = current.globalenv['db']
StoreFactory.__init__(self)
# extract the values and db field for the horizontal axis
if metric.field_horizontal == 'year':
values = range(report.period_start.year, report.period_end.year + 1)
field = None
else:
tablename, fieldname = metric.field_horizontal.split('.')
field = db[tablename][fieldname]
rows = db().select(field, distinct=True)
values = [row[fieldname] for row in rows]
self._field_h = field
self.values_h = values
# configure the store
self._get_fields()
self._get_data(metric, report)
def _get_fields(self):
""" Generate the Ext.data.Store.fields property.
The store contains the field group and one field per value of the
horizontal database field.
Data are grouped per the group field values.
"""
self.cfg_store.fields = [dict(name='group', type='string')]
for value in self.values_h:
self.cfg_store.fields.append(dict(name=str(value), type='float'))
self.cfg_store.sorters = ['group']
def _get_data(self, metric, report):
""" Generate the Ext.data.Store.data property.
It is a list of dictionaries. Each of them contains the data
for one row. One key, value pair for each Ext.data.Field.
The key is equal to the Ext.data.Field name.
@type metric: gluon.dal.objects.Row
@param metric: the definition of the metric
@type report: Report
@param report:
"""
db = current.globalenv['db']
# conditions from the metric definition
if metric.conditions:
q_conditions = smart_query(db.history, metric.conditions)
# prepare the intermediate dictionary for each vertical value
# the key is the vertical value while the value is a dictionary.
# The latter contains the group name and the metric
#for each horizontal value
tmp_di = {}
tpl_row_h = dict.fromkeys(self.values_h, '')
for value_h in self.values_h:
report.reset_extra_queries()
if metric.conditions:
report.append_query(q_conditions)
# modify the selector criteria
if metric.field_horizontal == 'year':
report.period_start = date(value_h, 1, 1)
report.period_end = date(value_h, 12, 31)
else:
report.append_query(self._field_h == value_h)
# for each vertical value build a dictionary.
# it contains the metric value for each horizontal value
for di in report.get_metric(metric.field_vertical):
value_v = di['group']
if value_v not in tmp_di:
tmp_di[value_v] = dict(group=value_v)
tmp_di[value_v].update(tpl_row_h)
tmp_di[value_v][value_h] = di[report.metric]
# from the intermediate dictionary
# build the tmp_di block of the store
for k in tmp_di.iterkeys():
self.cfg_store.data.append(tmp_di[k])
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment