Commit 9521891e authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Remove the old code based on extjs and rename the pandas controller graphs.

parent 1e17bee9
# -*- coding: utf-8 -*-
""" Controllers for building graphs
""" Controllers for building graphs using pandas library
"""
import json
import matplotlib
from datetime import datetime
from gluon.storage import Storage
from graph_tools import (do_linechart,
do_stackedchart,
mathplotlib_backend_server,
savefig)
from plugin_dbui import Selector
from reporting_tools import repr_team_project
INLINE_ALERT = "<script>Ext.Msg.alert('%s', '%s');</script>"
def dashboard():
"""Return a pre-configure linechart for public used.
Cumulative distribution for the publications are shown for
......@@ -20,211 +23,38 @@ def dashboard():
"""
selector = Storage()
selector.Linechart_selectorCumulative = True
selector.Linechart_selectorId = ''
selector.Linechart_selectorId_projects = ''
selector.Linechart_selectorId_teams = ''
selector.Linechart_selectorYear_start = datetime.now().year
selector.Linechart_selectorYear_end = ''
selector.Graph_selectorCumulative = True
selector.Graph_selectorId = ''
selector.Graph_selectorId_authors_roles = ''
selector.Graph_selectorId_graphs = 1
selector.Graph_selectorId_projects = ''
selector.Graphs_selectorId_teams = ''
selector.Graph_selectorYear_start = datetime.now().year
selector.Graph_selectorYear_end = ''
redirect(URL('graphs', 'linechart', vars=selector))
redirect(URL('graphs', 'index', vars=selector))
def index():
"""Render the selected graph.
"""Generate graph showing the number of publication per month / year
either as a linechart or as a stacked histograms.
"""
vars = Storage()
selector = Selector(virtdb.graph_selector)
fields = ('cumulative','id_graphs', 'year_start','year_end')
selector = Selector(virtdb.graph_selector, exclude_fields=fields)
# get the graph data
mathplotlib_backend_server()
# graph configuration
graph = db.graphs[selector.id_graphs]
# stacked chart
if graph.stack_axis:
vars.Stackedchart_selectorCumulative = selector.cumulative
vars.Stackedchart_selectorId = ''
vars.Stackedchart_selectorId_authors_roles = selector.id_authors_roles
vars.Stackedchart_selectorId_projects = selector.id_projects
vars.Stackedchart_selectorId_teams = selector.id_teams
vars.Stackedchart_selectorYear_start = selector.year_start
vars.Stackedchart_selectorYear_end = selector.year_end
vars.Stackedchart_selectorStack_axis = graph.stack_axis
vars.Stackedchart_selectorStack_granularity = graph.stack_granularity
redirect(URL('graphs', 'stackedchart', vars=vars))
ax = do_stackedchart(db.publications, selector, graph)
# line char
else:
vars.Linechart_selectorCumulative = selector.cumulative
vars.Linechart_selectorId = ''
vars.Linechart_selectorId_authors_roles = selector.id_authors_roles
vars.Linechart_selectorId_projects = selector.id_projects
vars.Linechart_selectorId_teams = selector.id_teams
vars.Linechart_selectorYear_start = selector.year_start
vars.Linechart_selectorYear_end = selector.year_end
redirect(URL('graphs', 'linechart', vars=vars))
def linechart():
"""show the cumulative distribution of the number of publications
as a function of the months. It can be build for the institute,
for a team or for a project.
"""
# get the user constraint.
selector = Selector(virtdb.linechart_selector,
exclude_fields=('cumulative',
'year_start',
'year_end'))
# query directive to count publications including
# foreign key constraints and user requirements
# related to team, project and year
query = selector.query(db.publications)
if selector.year_start and not selector.year_end:
query = (query) & (db.publications.submitted[0:4] == selector.year_start)
elif selector.year_start and selector.year_end:
q_start = db.publications.submitted[0:4] >= selector.year_start
q_end = db.publications.submitted[0:4] <= selector.year_end
query = (query) & ((q_start) & (q_end))
ax = do_linechart(db.publications, selector)
# count the number of publications
# they are grouped per year and and per month
group_by = [db.publications.submitted[:4], db.publications.submitted[5:7]]
count = db.publications.id.count()
rows = db(query).select(db.publications.submitted,
count,
groupby=group_by,
orderby=group_by)
# build the Ext.data.ArrayStore
cfg = Storage(fields=[], data=[])
cfg.fields.append({'name': 'submitted', 'type': 'string'})
cfg.fields.append({'name': 'publications', 'type': 'int'})
for row in rows:
# protection -- ignore publication with invalid submitted date
submitted = row.publications.submitted
if len(submitted) == 4:
continue
month_year = datetime.strptime(submitted[:7], "%Y-%m").strftime("%b %y")
cfg.data.append([month_year, row[count]])
# cumulative distribution
if selector.cumulative:
sum = 0
for i in range(len(cfg.data)):
sum += cfg.data[i][1]
cfg.data[i][1] = sum
# delegate rendering to the view
return dict(cfg_store=json.dumps(cfg),
team_project=repr_team_project(db, selector),
selector=selector)
def stackedchart():
"""show the distribution of publications as a function
of the month. It is displayed as a stacked chart showing for example
what happen per team or scientific domains.
"""
# get the user constraint.
# exclude the fields related to year and to the stack
selector = Selector(virtdb.stackedchart_selector,
exclude_fields=('cumulative',
'year_start',
'year_end',
'stack_axis',
'stack_granularity'))
# protection -- a stack has to be selected
if not selector.stack_axis:
return INLINE_ALERT % (T("Error"), T("Please select a stack..."))
# query directive to count publications including
# foreign key constraints and user requirements
# related to team, project and year
query = selector.query(db.publications)
if selector.year_start and not selector.year_end:
query = (query) & (db.publications.submitted[0:4] == selector.year_start)
elif selector.year_start and selector.year_end:
q_start = db.publications.submitted[0:4] >= selector.year_start
q_end = db.publications.submitted[0:4] <= selector.year_end
query = (query) & ((q_start) & (q_end))
# the stack field
# publications will be count as a function of the stack values
stack_field = db[selector.stack_axis][selector.stack_granularity]
# the value for the legend (only active items)
# dictionary, properly initialise, to count publications per stack value
stack_keys, stack_dict = [], {}
for row in db(query).select(stack_field, distinct=True, orderby=stack_field):
stack_keys.append(row[selector.stack_granularity])
stack_dict[row[selector.stack_granularity]] = 0
# group per year, per month and per stack value
group_by = [db.publications.submitted[:4],
db.publications.submitted[5:7],
stack_field]
count = db.publications.id.count()
rows = db(query).select(db.publications.submitted,
stack_field,
count,
groupby=group_by,
orderby=group_by)
# build the Ext.data.JsonStore
cfg = Storage(fields=[], data=[])
cfg.fields.append({'name': 'submitted', 'type': 'string'})
for key in stack_keys:
cfg.fields.append({'name': key, 'type': 'int'})
current = None
for row in rows:
# protection -- ignore publication with invalid submitted date
submitted = row.publications.submitted
if len(submitted) == 4:
continue
# initialise the new row for the store
if submitted[:7] != current:
current = submitted[:7]
di = dict(**stack_dict)
di['submitted'] = datetime.strptime(submitted[:7], "%Y-%m").strftime("%b %y")
cfg.data.append(di)
# fill the current row
stack = row[selector.stack_axis][selector.stack_granularity]
cfg.data[-1][stack] = row[count]
# cumulative distribution
if selector.cumulative:
for stack in stack_keys:
sum = 0
for i in range(len(cfg.data)):
sum += cfg.data[i][stack]
cfg.data[i][stack] = sum
# delegate rendering to the view
return dict(cfg_store=json.dumps(cfg),
team_project=repr_team_project(db, selector),
selector=selector,
stack_keys=stack_keys)
# delegate the rendering to the view
return dict(data=savefig(ax, "svg"))
# -*- coding: utf-8 -*-
""" Controllers for building graphs using pandas library
"""
import matplotlib
from datetime import datetime
from graph_tools import (do_linechart,
do_stackedchart,
mathplotlib_backend_server,
savefig)
from plugin_dbui import Selector
from reporting_tools import repr_team_project
def index():
"""Generate graph showing the number of publication per month / year
either as a linechart or as a stacked histograms.
"""
fields = ('cumulative','id_graphs', 'year_start','year_end')
selector = Selector(virtdb.graph_selector, exclude_fields=fields)
mathplotlib_backend_server()
# graph configuration
graph = db.graphs[selector.id_graphs]
# stacked chart
if graph.stack_axis:
ax = do_stackedchart(db.publications, selector, graph)
# line char
else:
ax = do_linechart(db.publications, selector)
# delegate the rendering to the view
return dict(data=savefig(ax, "svg"))
......@@ -157,6 +157,7 @@
'Created By': 'Created By',
'Created On': 'Created On',
'Cumulative': 'Cumulé',
'Cumulative sum of publications': 'Somme cumulée des publications',
'dashboard': 'tableau de bord',
'Data base scheme': 'Schéma base de donnée',
'Data institute': 'Les données du laboratoire',
......@@ -386,6 +387,7 @@
'Number for the first pages or a range 69-80': 'Numéro de la première page ou un range 69-80',
'Number of invalid records': "Nombre d'enregistrement non valide",
'Number of invalid records: %s': "Nombre d'enregistrement non valide : %s",
'Number of publications': 'Nombre de publications',
'Number of records added in the database': "Nombre d'enregistrements ajoutés à la base de donnée",
'Number of records already registered': "Nombre d'enregistrements déjà enregistrés dans la base de donnée",
'Number of records already validated': "Nombre d'enregistrements déjà validé",
......@@ -445,6 +447,7 @@
'proceeding': 'acte de conférence',
'Proceedings': 'Actes de conférence',
'Process': 'Analyser',
'Processing time %s seconds': 'Temps de calcul %s seconds',
'Profile': 'Profile',
'project': 'projet',
'Project': 'Projet',
......
# -*- coding: utf-8 -*-
""" linechart_selector (virtual table)
"""
#-------------------------------------------------------------------------------
#
# DEFINITION
#
#-------------------------------------------------------------------------------
virtdb.define_table('linechart_selector',
Field('year_start', 'integer', default=year),
Field('year_end', 'integer'),
Field('id_teams', 'reference teams', label='Team'),
Field('id_projects', 'reference projects', label='Project'),
Field('cumulative', 'boolean', default=True))
virtdb.linechart_selector.id_projects.requires = IS_IN_DB(db, 'projects.project')
virtdb.linechart_selector.id_teams.requires = IS_IN_DB(db, 'teams.team')
#-------------------------------------------------------------------------------
#
# FIELDS CONFIGURATiON
#
#-------------------------------------------------------------------------------
fieldsModifier = dbui.FieldsModifier('linechart_selector')
fieldsModifier.configure_field('year_start', flex=1)
fieldsModifier.configure_field('year_end', flex=1)
fieldsModifier.merge_fields('year_start', 'year_end', fieldLabel=T('Year'))
fieldsModifier.configure_field('id_projects', emptyText=T('select...'), xtype='xcomboboxuserreset')
fieldsModifier.configure_field('id_teams', emptyText=T('select...'), xtype='xcomboboxuserreset')
#-------------------------------------------------------------------------------
#
# FORM CONFIGURATiON
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#
# GRID CONFIGURATiON
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#
# STORE CONFIGURATiON
#
#-------------------------------------------------------------------------------
# -*- coding: utf-8 -*-
""" stackedchart_selector (virtual table)
"""
#-------------------------------------------------------------------------------
#
# DEFINITION
#
#-------------------------------------------------------------------------------
virtdb.define_table('stackedchart_selector',
Field('year_start', 'integer', default=year),
Field('year_end', 'integer'),
Field('id_teams', 'reference teams', label='Team'),
Field('id_projects', 'reference projects', label='Project'),
Field('id_authors_roles', 'reference authors_roles', label='Role'),
Field('stack_axis', 'string'),
Field('stack_granularity', 'string'),
Field('cumulative', 'boolean', default=True))
virtdb.stackedchart_selector.id_authors_roles.requires = IS_IN_DB(db, 'authors_roles.role')
virtdb.stackedchart_selector.id_projects.requires = IS_IN_DB(db, 'projects.project')
virtdb.stackedchart_selector.id_teams.requires = IS_IN_DB(db, 'teams.team')
#-------------------------------------------------------------------------------
#
# FIELDS CONFIGURATiON
#
#-------------------------------------------------------------------------------
fieldsModifier = dbui.FieldsModifier('stackedchart_selector')
fieldsModifier.configure_field('cumulative', checked=True)
fieldsModifier.configure_field('year_start', flex=1)
fieldsModifier.configure_field('year_end', flex=1)
fieldsModifier.merge_fields('year_start', 'year_end', fieldLabel=T('Year'))
fieldsModifier.configure_field('stack_axis', flex=1)
fieldsModifier.configure_field('stack_granularity', flex=1)
fieldsModifier.merge_fields('stack_axis', 'stack_granularity', fieldLabel=T('Stack'))
fieldsModifier.configure_field('id_authors_roles', emptyText=T('select...'), xtype='xcomboboxuserreset')
fieldsModifier.configure_field('id_projects', emptyText=T('select...'), xtype='xcomboboxuserreset')
fieldsModifier.configure_field('id_teams', emptyText=T('select...'), xtype='xcomboboxuserreset')
fieldsModifier.configure_field('stack_axis',
itemId='stack_axis',
displayField='AxesTr_axis',
valueField='AxesAxis',
refStore=dbui.get_store_id('axes'),
emptyText=T('Select axis...'),
userReset=True,
xtype='xcomboboxmaster')
fieldsModifier.configure_field('stack_granularity',
masterItemId='stack_axis',
masterValueField='AxesAxis',
displayField='AxesTr_granularity',
valueField='AxesGranularity',
refStore=dbui.get_store_id('axes'),
emptyText=T('Select granularity...'),
xtype='xcomboboxslave')
#-------------------------------------------------------------------------------
#
# FORM CONFIGURATiON
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#
# GRID CONFIGURATiON
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#
# STORE CONFIGURATiON
#
#-------------------------------------------------------------------------------
......@@ -196,7 +196,7 @@ dashBoardLeaf = Panel(loader=loader,
autoScroll=True)
graphLeaf = PanelWithUrlSelector(virtdb.graph_selector,
baseUrl=URL('graphs', 'index'))
baseUrl=URL('graphs', 'index'))
listLeaf = PanelWithUrlSelector(virtdb.list_selector,
baseUrl=URL('lists', 'index'),
......@@ -207,15 +207,11 @@ metricLeaf = PanelWithUrlSelector(virtdb.metric_selector,
baseUrl=URL('metrics', 'index'),
extField='format')
pandasLeaf = PanelWithUrlSelector(virtdb.graph_selector,
baseUrl=URL('pandas', 'index'))
reportNode = Node(T('Reports'))
reportNode.add_child(T('dashboard'), dashBoardLeaf)
reportNode.add_child(T('lists'), listLeaf)
reportNode.add_child(T('metrics'), metricLeaf)
reportNode.add_child(T('graphs'), graphLeaf)
reportNode.add_child('pandas', pandasLeaf)
#-------------------------------------------------------------------------------
#
......
......@@ -17,6 +17,7 @@ from StringIO import StringIO
FROM_TO = "from %s to %s"
TITLE = "Publications"
TITLE_CUMSUM = "Cumulative sum of publications"
TITLE_Y = "Number of publications"
def do_labels(ax, xlabel, ylabel):
......@@ -62,6 +63,7 @@ def do_linechart(publications, selector):
"""
db = publications._db
rx_submitted = re.compile(REG_SUBMITTED)
T = current.T
# query directive to count publications including
# foreign key constraints and user requirements
......@@ -102,7 +104,7 @@ def do_linechart(publications, selector):
# instantiate the plot
ax = df.plot(legend=False)
do_labels(ax, "", "Number of publications / month")
do_labels(ax, "", T(TITLE_Y))
do_tick(ax)
do_title(ax, db, selector)
......@@ -155,6 +157,7 @@ def do_stackedchart(publications, selector, graph):
"""
db = publications._db
rx_submitted = re.compile(REG_SUBMITTED)
T = current.T
# the stack field
tablename = graph.stack_axis
......@@ -216,7 +219,7 @@ def do_stackedchart(publications, selector, graph):
kind="area",
stacked=True)
do_labels(ax, "", "Number of publications / month")
do_labels(ax, "", T(TITLE_Y))
do_tick(ax)
do_title(ax, db, selector)
......
{{
#--------------------------------------------------------------------------
#
# The python controller return:
# - cfg_store, the configuration of the Ext.data.Array
# - team_project string
# - selector object
#
# prepare the data
# - build unique DIV identifier
# - Title and DIV block
#
#--------------------------------------------------------------------------
#
# unique identifier for the DIV block associated to the grid
#
divchart = "chart-%s" % id(cfg_store)
#
# The title and the DIV block for the Ext.grid.Panel
#
if selector.cumulative:
title = "%s %s" % (T("Sum of publications"), team_project)
else:
title = "%s %s" % (T("Publications"), team_project)
pass
response.write(H2(title, _class="dbui-h2 dbui-small-cap"))
response.write(DIV(_id=divchart, _style="padding-left: 12px;"))
#
# Export python variables to the javascript
#
jsvars = ["axes",
"cfgStore = %s" % cfg_store,
"chart",
"divchart = '%s'" % divchart,
"series"]
jsvars = " var %s;" % ',\n'.join(jsvars)
response.write(SCRIPT(jsvars), escape=False)
}}
<script>
// create the publications versus time axes
axes = [{
type: 'Numeric',
position: 'left',
fields: ['publications'],
grid: true,
minimum: 0,
minorTickSteps: 1
}, {
type: 'Category',
position: 'bottom',
fields: ['submitted'],
grid: true,
label: {
rotate: {
degrees: 270
}
}
}];
// how to display the series
// a single curve showing the cumulative sum of publication per month.
// no marker, no shadow, rather thin line
series = [{
type: 'line',
shadowAttributes: [],
showMarkers: false,
style: {
stroke: '#0084d1',
'stroke-width': 1.5
},
xField: 'submitted',
yField: 'publications'
}];
// instantiate the chart
chart = Ext.create('Ext.chart.Chart', {
axes: axes,
series: series,
store: Ext.create('Ext.data.ArrayStore', cfgStore),
width: 500,
height: 400,
renderTo: divchart
});
// inhibit context menu on the rest of the panel
chart.getEl().up('.x-panel-body').on('contextmenu', function(event) {
event.stopEvent();
});
</script>