summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_files/forms.py8
-rw-r--r--archaeological_files/models.py5
-rw-r--r--ishtar_common/models.py45
-rw-r--r--ishtar_common/static/media/style.css15
-rw-r--r--ishtar_common/templates/ishtar/dashboards/dashboard_main.html3
-rw-r--r--ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html88
-rw-r--r--ishtar_common/templatetags/date_formating.py19
-rw-r--r--ishtar_common/views.py11
8 files changed, 155 insertions, 39 deletions
diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py
index dbbbafbd9..68a004e4f 100644
--- a/archaeological_files/forms.py
+++ b/archaeological_files/forms.py
@@ -122,13 +122,15 @@ class FileFormSelection(forms.Form):
raise forms.ValidationError(_(u"You should select a file."))
return cleaned_data
-SLICING = (('year',_(u"years")), ("month",_(u"months")))
+SLICING = (("month",_(u"months")), ('year',_(u"years")),)
DATE_SOURCE = (('creation',_(u"Creation date")),
("reception",_(u"Reception date")))
class DashboardForm(forms.Form):
slicing = forms.ChoiceField(label=_("Slicing"), choices=SLICING,
required=False)
+ department_detail = forms.BooleanField(label=_("Department detail"),
+ required=False)
date_source = forms.ChoiceField(label=_("Date get from"),
choices=DATE_SOURCE, required=False)
file_type = forms.ChoiceField(label=_("File type"), choices=[],
@@ -145,6 +147,10 @@ class DashboardForm(forms.Form):
self.fields['saisine_type'].choices = models.SaisineType.get_types()
self.fields['file_type'].choices = models.FileType.get_types()
+ def get_show_detail(self):
+ return hasattr(self, 'cleaned_data') and \
+ self.cleaned_data.get('department_detail')
+
def get_date_source(self):
date_source = 'creation'
if hasattr(self, 'cleaned_data') and \
diff --git a/archaeological_files/models.py b/archaeological_files/models.py
index 70570e145..a649ceac1 100644
--- a/archaeological_files/models.py
+++ b/archaeological_files/models.py
@@ -230,7 +230,7 @@ class File(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem):
return sorted(owns.all(), key=lambda x:x.cached_label)
@classmethod
- def get_periods(cls, slice='year', fltr={}, date_source='creation'):
+ def get_periods(cls, slice='month', fltr={}, date_source='creation'):
date_var = date_source + '_date'
q = cls.objects.filter(**{date_var+'__isnull':False})
if fltr:
@@ -258,7 +258,8 @@ class File(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem):
q = cls.objects.filter(**{date_var+'__isnull':False})
if fltr:
q = q.filter(**fltr)
- return q.filter(**{date_var+'__year':year, date_var+'__month':month})
+ q = q.filter(**{date_var+'__year':year, date_var+'__month':month})
+ return q
@classmethod
def get_total_number(cls, fltr={}):
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 98f4addb7..c59f38674 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -561,10 +561,12 @@ class UserDashboard:
.order_by('person__person_types')
class Dashboard:
- def __init__(self, model, slice='year', date_source=None, fltr={}):
+ def __init__(self, model, slice='year', date_source=None, show_detail=None,
+ fltr={}):
# don't provide date_source if it is not relevant
self.model = model
self.total_number = model.get_total_number(fltr)
+ self.show_detail = show_detail
history_model = self.model.history.model
# last edited - created
self.recents, self.lasts = [], []
@@ -597,21 +599,40 @@ class Dashboard:
self.periods.sort()
if not self.total_number or not self.periods:
return
+ kwargs_num = base_kwargs.copy()
+ self.serie_labels = [_(u"Total")]
# numbers
if slice == 'year':
- self.values = [('year', _(u"Year"), reversed(self.periods))]
- self.numbers = [model.get_by_year(year, **base_kwargs).count()
+ self.values = [('year', "",
+ list(reversed(self.periods)))]
+ self.numbers = [model.get_by_year(year, **kwargs_num).count()
for year in self.periods]
- self.values += [('number', _(u"Number"), reversed(self.numbers))]
+ self.values += [('number', _(u"Number"),
+ list(reversed(self.numbers)))]
if slice == 'month':
- self.numbers = [model.get_by_month(*period, **base_kwargs).count()
- for period in self.periods]
- periods = reversed(self.periods)
- self.periods = ["%d-%s-01" % (period[0], ('0'+str(period[1]))
- if len(str(period[1])) == 1 else period[1])
- for period in periods]
- self.values = [('month', _(u"Month"), self.periods)]
- self.values += [('number', _(u"Number"), reversed(self.numbers))]
+ periods = list(reversed(self.periods))
+ self.periods = ["%d-%s-01" % (p[0], ('0'+str(p[1]))
+ if len(str(p[1])) == 1 else p[1])
+ for p in periods]
+ self.values = [('month', "", self.periods)]
+ if show_detail:
+ for dpt in settings.ISHTAR_DPTS:
+ self.serie_labels.append(unicode(dpt))
+ idx = 'number_' + unicode(dpt)
+ kwargs_num['fltr'] = {"towns__numero_insee__startswith":\
+ unicode(dpt)}
+ numbers = [model.get_by_month(*p.split('-')[:2],
+ **kwargs_num).count()
+ for p in self.periods]
+ self.values += [(idx, dpt, list(numbers))]
+ # put "Total" at the end
+ self.serie_labels.append(self.serie_labels.pop(0))
+ kwargs_num['fltr'] = {}
+ self.numbers = [model.get_by_month(*p.split('-')[:2],
+ **kwargs_num).count()
+ for p in self.periods]
+ self.values += [('number', _(u"Total"),
+ list(self.numbers))]
# calculate
self.average = self.get_average()
self.variance = self.get_variance()
diff --git a/ishtar_common/static/media/style.css b/ishtar_common/static/media/style.css
index 341308926..54a97ca77 100644
--- a/ishtar_common/static/media/style.css
+++ b/ishtar_common/static/media/style.css
@@ -669,6 +669,13 @@ table.confirm tr.spacer td:last-child{
padding:0.5em 1em;
}
+.chart-img{
+ display:none;
+}
+
+.chart-img-form{
+ margin-top:1em;
+}
#window table th, .dashboard table.resume th{
background-color:#922;
@@ -783,8 +790,7 @@ table.confirm tr.spacer td:last-child{
margin:0.3em;
}
-p.alert{
- color:#D14;
+p.info-box, p.alert{
display:block;
font-style:italic;
width:670px;
@@ -794,6 +800,11 @@ p.alert{
-moz-border-radius:8px;
-webkit-border-radius:8px;
border-radius:8px;
+ font-size: 0.9em;
+}
+
+p.alert{
+ color:#D14;
background-image:url(images/red_flag.png);
background-repeat:no-repeat;
background-position:left center;
diff --git a/ishtar_common/templates/ishtar/dashboards/dashboard_main.html b/ishtar_common/templates/ishtar/dashboards/dashboard_main.html
index 8822875b5..868f8a5c3 100644
--- a/ishtar_common/templates/ishtar/dashboards/dashboard_main.html
+++ b/ishtar_common/templates/ishtar/dashboards/dashboard_main.html
@@ -6,9 +6,12 @@
<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/jquery.jqplot.min.js"></script>
<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.canvasTextRenderer.min.js"></script>
<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js"></script>
+<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js"></script>
<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.highlighter.min.js"></script>
<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.pieRenderer.min.js"></script>
<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.dateAxisRenderer.min.js"></script>
+<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.cursor.min.js"></script>
+<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.cursor.min.js"></script>
<link rel="stylesheet" href="{{STATIC_URL}}js/jqplot/jquery.jqplot.min.css" />
{% endblock %}
{% block content %}
diff --git a/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html b/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html
index 610457ae3..820c50136 100644
--- a/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html
+++ b/ishtar_common/templates/ishtar/dashboards/dashboard_main_detail.html
@@ -1,11 +1,8 @@
-{% load i18n %}
+{% load i18n date_formating %}
{% load url from future %}
<div class='dashboard' id="{{unique_id}}-tab">
<div>
<h4>{% trans "Numbers" %}</h4>
- <p><strong>{% trans "Total:" %}</strong> {{dashboard.total_number}}</p>
- <div class='table'>
- <div id="chart_{{unique_id}}" style="height:400px; width:700px;"></div>
{% if form %}
<div class='form'>
<form method='post' action="{% url 'dashboard-main-detail' item_name %}" id='{{unique_id}}_form'>
@@ -16,15 +13,27 @@
</form>
</div>
{% endif %}
- {% comment %}
- <table>
+ <p><strong>{% trans "Total:" %}</strong> {{dashboard.total_number}}</p>
+ <div class='table'>
+ <div id="chart_{{unique_id}}" style="height:400px; width:700px;"></div>
+ <p class='info-box'>{% trans 'Draw rectangle on the graph to zoom. Double-click to reinitialize.' %}</p>
+ <div class='form chart-img-form'>
+ <button id="chart_img_display_{{unique_id}}" class='submit'>{% trans "Display as an image" %}</button>
+ <div id="chart_img_{{unique_id}}" class='chart-img'>
+ <div id="img_{{unique_id}}"></div>
+ <p class='info-box'>{% trans 'Right-click on this image to save it.' %}</p>
+ </div>
+ </div>
+ </div>
+ <div class='table'>
+ <table class='resume'>
{% for idx, lbl, values in dashboard.values %}
<tr class='idx {% if forloop.counter0|divisibleby:"2" %}even{%else%}odd{%endif%}'>
<th>{{lbl}}</th>
- {% for value in values %}<td>{{value}}</td>{% endfor%}
+ {% for value in values reversed %}{% if forloop.parentloop.counter0 %}<td>{% else %}<th>{%endif%}{{value|date_formating }}{% if forloop.parentloop.counter0 %}</td>{% else %}</th>{%endif%}{% endfor%}
</tr>
{% endfor%}
- </table>{% endcomment %}
+ </table>
</div>
{% if dashboard.periods %}
<h4>{% trans "By years" %}</h4>
@@ -71,23 +80,41 @@
</div>
<script language="javascript" type="text/javascript">
$(document).ready(function(){
-var values_{{unique_id}} = [];
+{% for idx, lbl, values in dashboard.values %} {% if forloop.counter0 > 0 %} var values_{{forloop.counter0}}_{{unique_id}} = []; {% for idx, lbl, values in dashboard.values %} {% for value in values %} {% if forloop.parentloop.counter0 == 0 %} values_{{forloop.parentloop.parentloop.counter0}}_{{unique_id}}.push([{{VALUE_QUOTE|safe}}{{value}}{{VALUE_QUOTE|safe}}, 0]); {% elif forloop.parentloop.parentloop.counter0 == forloop.parentloop.counter0 %} values_{{forloop.parentloop.parentloop.counter0}}_{{unique_id}}[{{forloop.counter0}}][1] = {{value}}; {% endif %} {% endfor%} {% endfor%} {% endif %} {% endfor %}
-{% for idx, lbl, values in dashboard.values %} {% for value in values %}{% ifequal forloop.parentloop.counter0 0 %}
-values_{{unique_id}}.push([{{VALUE_QUOTE|safe}}{{value}}{{VALUE_QUOTE|safe}}, 0]);
-{% else %}values_{{unique_id}}[{{forloop.counter0}}][1] = {{value}};{% endifequal %}{% endfor%}{% endfor%}
+{% comment %}
+# less compact version
+{% for idx, lbl, values in dashboard.values %}
+ {% if forloop.counter0 > 0 %}
+ {% for idx, lbl, values in dashboard.values %}
+ {% for value in values %}
+ {% if forloop.parentloop.counter0 == 0 %}
+ values_{{forloop.parentloop.counter0}}_{{unique_id}}.push([{{VALUE_QUOTE|safe}}{{value}}{{VALUE_QUOTE|safe}}, 0]);
+ {% elif forloop.parentloop.counter0 == forloop.counter0 %}
+ values_{{forloop.counter0}}_{{unique_id}}[{{forloop.counter0}}][1] = {{value}};
+ {% endif %}
+ {% endfor%}
+ {% endfor%}
+ {% endif %}
+{% endfor %}
+{% endcomment %}
+
+
+if (typeof values_1_{{unique_id}} === 'undefined'
+ || values_1_{{unique_id}}.length == 0){
-if (values_{{unique_id}}.length > 0){
+$('#chart_img_{{unique_id}}').hide();
+$('#chart_{{unique_id}}').html("<p class='alert'>{% trans 'No data for theses criteria.' %}</p>");
+} else {
var showmarker = false;
-if (values_{{unique_id}}.length < 25){
+if (values_1_{{unique_id}}.length < 25){
var showmarker = true;
}
var plot_{{unique_id}} = $.jqplot('chart_{{unique_id}}',
- [values_{{unique_id}}], {
- series:[{showMarker:showmarker}],
+ [{% for idx, lbl, values in dashboard.values %}{% if forloop.counter0 > 0 %} {% if forloop.counter0 > 1 %}, {% endif%} values_{{forloop.counter0}}_{{unique_id}} {% endif %} {% endfor%}], {
axes:{ {%ifequal slicing 'year'%}
xaxis:{
label:'{% trans "Year" %}',
@@ -98,7 +125,11 @@ var plot_{{unique_id}} = $.jqplot('chart_{{unique_id}}',
xaxis:{
label:'{% trans "Month" %}',
renderer:$.jqplot.DateAxisRenderer,
- tickOptions:{formatString:'%b %Y'},
+ tickRenderer:$.jqplot.CanvasAxisTickRenderer,
+ tickOptions:{
+ formatString:'%b %Y',
+ angle:-25
+ }
},{%endifequal%}
yaxis:{
label:'{% trans "Number"%}',
@@ -108,11 +139,28 @@ var plot_{{unique_id}} = $.jqplot('chart_{{unique_id}}',
highlighter: {
show: true,
sizeAdjust: 7.5
- }
+ },
+ series:[{% for label in dashboard.serie_labels %}
+ {%if forloop.counter0%}, {% endif %}{label:"{{label}}"}{% endfor %}
+ ],
+ cursor:{
+ show: true,
+ zoom:true,
+ showTooltip:false
+ },
+ legend: { show:true, location: 'nw' }
+ });
+
+ $('#chart_img_display_{{unique_id}}').click(function(){
+ $('#chart_img_{{unique_id}}').hide();
+ $('#img_{{unique_id}}').html(
+ $('<img/>').attr(
+ 'src', $('#chart_{{unique_id}}').jqplotToImageStr({})
+ )
+ );
+ $('#chart_img_{{unique_id}}').show('slow');
});
-} else {
-$('#chart_{{unique_id}}').html("<p class='alert'>{% trans 'No data for theses criteria.' %}</p");
}
$('#search_{{unique_id}}').click(function (){
diff --git a/ishtar_common/templatetags/date_formating.py b/ishtar_common/templatetags/date_formating.py
new file mode 100644
index 000000000..eb81cf52c
--- /dev/null
+++ b/ishtar_common/templatetags/date_formating.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from datetime import datetime
+
+from django.template import Library
+from django.utils.translation import ugettext as _
+
+register = Library()
+
+@register.filter
+def date_formating(value):
+ try:
+ d = datetime.strptime(unicode(value), '%Y-%m-%d')
+ return _(d.strftime("%B")).capitalize() + u" %d" % d.year
+ except ValueError:
+ # could be passed to non date value: on error return value
+ return value
+
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index d20b8b2af..d15157eed 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -730,7 +730,11 @@ def dashboard_main_detail(request, item_name):
'ishtar/dashboards/dashboard_main_detail_users.html',
dct, context_instance=RequestContext(request))
form = None
- slicing, date_source, fltr = 'year', None, {}
+ slicing, date_source, fltr, show_detail = 'year', None, {}, False
+ if (item_name == 'files' and \
+ 'archaeological_files' in settings.INSTALLED_APPS):\
+ #or item_name == 'operations':
+ slicing = 'month'
if item_name in DASHBOARD_FORMS:
if request.method == 'POST':
form = DASHBOARD_FORMS[item_name](request.POST)
@@ -739,13 +743,16 @@ def dashboard_main_detail(request, item_name):
fltr = form.get_filter()
if hasattr(form, 'get_date_source'):
date_source = form.get_date_source()
+ if hasattr(form, 'get_show_detail'):
+ show_detail = form.get_show_detail()
else:
form = DASHBOARD_FORMS[item_name]()
lbl, dashboard = None, None
if item_name == 'files' and \
'archaeological_files' in settings.INSTALLED_APPS:
from archaeological_files.models import File
- dashboard_kwargs = {'slice':slicing, 'fltr':fltr,}
+ dashboard_kwargs = {'slice':slicing, 'fltr':fltr,
+ 'show_detail':show_detail}
# date_source is only relevant when the form has set one
if date_source:
dashboard_kwargs['date_source'] = date_source