summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/models.py9
-rw-r--r--ishtar_common/static/js/ishtar-map.js35
-rw-r--r--ishtar_common/static/js/ishtar.js279
-rw-r--r--ishtar_common/templates/base.html14
-rw-r--r--ishtar_common/templates/blocks/DataTables-tabs.html14
-rw-r--r--ishtar_common/templates/blocks/DataTables.html64
-rw-r--r--ishtar_common/views_item.py31
7 files changed, 379 insertions, 67 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 7aa8706b3..8e5983a45 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -1931,10 +1931,13 @@ class TemplateItem:
class StatisticItem:
- STATISTIC_MODALITIES = [] # example: "operation type", "material type"
+ STATISTIC_MODALITIES = [] # example: "year", "operation_type__label"
+ STATISTIC_MODALITIES_OPTIONS = OrderedDict() # example:
+ # OrderedDict([('year', _("Year")),
+ # ("operation_type__label", _("Operation type"))])
STATISTIC_SUM_VARIABLE = OrderedDict(
- (("pk", _("number")),)
- ) # example: "price", "volume"
+ (("pk", _("Number")),)
+ ) # example: "Price", "Volume"
class BaseHistorizedItem(StatisticItem, TemplateItem, FullSearch, Imported,
diff --git a/ishtar_common/static/js/ishtar-map.js b/ishtar_common/static/js/ishtar-map.js
index 1b0d4384b..a93813e61 100644
--- a/ishtar_common/static/js/ishtar-map.js
+++ b/ishtar_common/static/js/ishtar-map.js
@@ -27,6 +27,41 @@ var geolocation = {};
var geoloc_feature = {};
var geoloc_activated = {};
+var fetching_msg = "Fetching data...";
+
+var _map_submit_search = function(query_vars, name, source){
+ var modal_base_text = $('.modal-progress .modal-header').html();
+ $('.modal-progress .modal-header').html(fetching_msg);
+ $('.modal-progress').modal('show');
+ var data = search_get_query_data(query_vars, name);
+ var nb_select = jQuery("#id_" + name + "-length_map").val();
+ if (!nb_select) nb_select = 10;
+
+ var url = source + "json-map?length=" + nb_select + "&submited=1&" + data;
+ var use_map_limit = false;
+ if(data.indexOf("no_limit=true") == -1){
+ url += "&limit=" + current_map_limit;
+ use_map_limit = true;
+ }
+ $.getJSON(url, function(data) {
+ var timestamp = Math.floor(Date.now() / 1000);
+ var map_id = "map-" + timestamp;
+ $('.modal-progress .modal-header').html("{% trans 'Render map...' %}");
+
+ var html = render_map(map_id, use_map_limit);
+ $("#tab-content-map-" + name).html(html);
+ $("#id_" + name + "-length_map").change(map_submit_search);
+ if ($('.modal-progress').length > 0){
+ $('.modal-progress').modal('hide');
+ $('.modal-progress .modal-header').html(modal_base_text);
+ }
+ register_map(map_id, data);
+ });
+
+ return false;
+
+};
+
var geoloc_activated_message = function(map_id){
setTimeout(function(){
diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js
index 2527c1bd7..54823968c 100644
--- a/ishtar_common/static/js/ishtar.js
+++ b/ishtar_common/static/js/ishtar.js
@@ -1095,6 +1095,33 @@ var get_hover_div = function(table_cols, data){
return hover;
};
+var _gallery_submit_search = function(image_page, query_vars, name, source){
+ if (image_page) {
+ current_image_page = image_page;
+ } else {
+ current_image_page = 1;
+ }
+ $('.modal-progress').modal('show');
+ var data = search_get_query_data(query_vars, name);
+ var nb_select = jQuery("#id_" + name + "-length_image").val();
+ if (!nb_select) nb_select = 10;
+
+ var url = source + "json-image?length=" + nb_select + "&submited=1&" + data;
+ $.getJSON(url, function(data) {
+ var timestamp = Math.floor(Date.now() / 1000);
+ var gallery_id = "gallery-" + timestamp;
+ $("#tab-content-gallery-" + name).html(
+ render_gallery(data, name, nb_select, gallery_id));
+ $("#id_" + name + "-length_image").change(gallery_submit_search);
+ register_image_gallery(gallery_id);
+ $('.card[data-toggle="tooltip"]').tooltip();
+ if ($('.modal-progress').length > 0){
+ $('.modal-progress').modal('hide');
+ }
+ });
+ return false;
+}
+
var render_gallery = function(data_table, table_name, nb_select, gallery_id){
var html = '<div class="ishtar-gallery-wrapper container-fluid">';
html += render_paginate_select(table_name, 'image', nb_select);
@@ -1343,6 +1370,7 @@ var register_map = function(map_id, points){
var main_submit_search = function(){
if (current_tab == "table") datatable_submit_search();
if (current_tab == "gallery") gallery_submit_search();
+ if (current_tab == "stats") stats_submit_search();
if (current_tab == "map") map_submit_search();
};
@@ -1376,3 +1404,254 @@ var search_get_query_data = function(query_vars, table_name){
}
return data;
};
+
+var registered_stats = false;
+
+var register_stats = function(query_vars, name, source){
+ if (registered_stats) return;
+ registered_stats = true;
+ $("#stats-form-" + name + " select").on('change', function() {
+ _stats_submit_search(query_vars, name, source);
+ }
+ );
+ $('#chart-img-display-' + name).click(function(){
+ $('#chart-img-' + name).hide();
+ $('#img-' + name).html(
+ $('<img/>').attr(
+ 'src', $('#chart-' + name).jqplotToImageStr({})
+ )
+ );
+ $('#chart-img-' + name).show('slow');
+ });
+};
+
+var _stats_submit_search = function(query_vars, name, source){
+ $('.modal-progress').modal('show');
+
+ var data = search_get_query_data(query_vars, name);
+ register_stats(query_vars, name, source);
+
+ var url = source + "json-stats?submited=1&" + data;
+ var modality_1 = $("#stats_modality_1-" + name).val();
+ if (modality_1) url += '&stats_modality_1=' + modality_1;
+ var modality_2 = $("#stats_modality_2-" + name).val();
+ if (modality_2) url += '&stats_modality_2=' + modality_2;
+ $.getJSON(url, function(data) {
+ var timestamp = Math.floor(Date.now() / 1000);
+ var stats_id = "stats-" + timestamp;
+ $("#tab-content-stats-" + name).html(
+ render_stats(data, name));
+ if ($('.modal-progress').length > 0){
+ $('.modal-progress').modal('hide');
+ }
+ });
+ return false;
+}
+
+var stats_showmarker = false;
+var stats_incompatible_modality = "This graph type accept only one modality.";
+var stats_current_graph;
+
+var _render_stats_table = function(stats_values, name){
+ var modality_1 = $("#stats_modality_1-" + name).val();
+ var modality_2 = $("#stats_modality_2-" + name).val();
+ var rows = new Array();
+
+ var current_row = new Array();
+ var html = "";
+ html += "<table class='table w-75 mt-4 pt-4 mx-auto'><thead>";
+ html += "<tr><th>";
+ var modality_1_lbl = $('#stats_modality_1-' + name + ' option:selected').text();
+ current_row.push(modality_1_lbl);
+ html += modality_1_lbl;
+ if (modality_2 && modality_2 != modality_1){
+ html += "</th><th>";
+ var modality_2_lbl = $('#stats_modality_2-' + name + ' option:selected').text();
+ html += modality_2_lbl;
+ current_row.push(modality_2_lbl);
+ }
+ html += "</th><th>";
+ var sum_lbl = $('#stats_sum-' + name + ' option:selected').text();
+ html += sum_lbl;
+ current_row.push(sum_lbl);
+ html += "</th></tr></thead><tbody>";
+ rows.push(current_row);
+
+ if (modality_2 && modality_2 != modality_1){
+ for (idx in stats_values){
+ var start_row = "";
+ row_content = "";
+ for (inner_idx in stats_values[idx][1]){
+ current_row = new Array();
+ var colspan = parseInt(inner_idx) + 1;
+ start_row = "<tr><td rowspan='" + colspan + "'>" + stats_values[idx][0] + "</td>";
+ current_row.push(stats_values[idx][0]);
+ if (inner_idx > 0) row_content += "<tr>";
+ row_content += "<td>" + stats_values[idx][1][inner_idx][0] + "</td>";
+ current_row.push(stats_values[idx][1][inner_idx][0]);
+ row_content += "<td>" + stats_values[idx][1][inner_idx][1] + "</td></tr>";
+ current_row.push(stats_values[idx][1][inner_idx][1]);
+ rows.push(current_row);
+ }
+ html += start_row + row_content;
+ }
+ } else {
+ for (idx in stats_values){
+ current_row = new Array();
+ html += "<tr><td>" + stats_values[idx][0] + "</td>";
+ current_row.push(stats_values[idx][0]);
+ html += "<td>" + stats_values[idx][1] + "</td></tr>";
+ current_row.push(stats_values[idx][1]);
+ rows.push(current_row);
+ }
+ }
+
+ html += "</tbody></table>";
+ $("#charts-" + name).hide();
+ $("#stats-table-content-" + name).html(html);
+ $("#stats-table-" + name).show();
+
+ var csv_content = "data:text/csv;charset=utf-8," + rows.map(e => e.join(",")).join("\n");
+ var encoded_uri = encodeURI(csv_content);
+ $("#stats-table-csv-" + name).attr("href", encoded_uri);
+ $("#stats-table-csv-" + name).attr("download", "ishtar-stats.csv");
+};
+
+var render_stats = function(stats_values, name){
+ var stats_type = $("#stats_renderer-" + name).val();
+
+ if (!stats_values || !stats_values['data']) return;
+ stats_values = stats_values['data'];
+
+ if (stats_current_graph){
+ stats_current_graph.destroy();
+ }
+ if (stats_type == "table"){
+ return _render_stats_table(stats_values, name);
+ }
+
+ $("#stats-table-" + name).hide();
+ $("#charts-" + name).show();
+ var modality_1 = $("#stats_modality_1-" + name).val();
+ var modality_2 = $("#stats_modality_2-" + name).val();
+
+ stats_xaxis = {
+ label: $('#stats_modality_1-' + name + ' option:selected').text()
+ };
+
+ var stats_help = $("#stats-zoom-help-" + name);
+
+ if (stats_type == "pie"){
+ stats_help.hide();
+ if (modality_2){
+ display_info(stats_incompatible_modality);
+ return;
+ }
+ } else {
+ stats_help.show();
+ var stats_xaxis_tickoptions;
+ if (modality_1 == "year"){
+ stats_xaxis_tickoptions = {formatString: "%d"};
+ } else {
+ stats_xaxis_tickoptions = {angle:-25};
+ }
+ stats_xaxis["tickOptions"] = stats_xaxis_tickoptions
+ }
+
+ var stats_showmarker = false;
+ if (stats_values.length < 25){
+ stats_showmarker = true;
+ }
+ var jqvalues = new Array();
+ var ticks = new Array();
+ var series = new Array();
+ var series_conf = new Array();
+ if (modality_2 && modality_2 != modality_1){
+ for (idx in stats_values){
+ ticks.push(stats_values[idx][0]);
+ var serie_values = stats_values[idx][1];
+ var current_serie_values = new Array();
+ for (inner_idx in serie_values){
+ var serie_value = serie_values[inner_idx][0];
+ if (series.indexOf(serie_value) == -1){
+ series.push(serie_value);
+ var fill_values = new Array();
+ if (idx > 0){ // put 0 for previous items
+ for (var fill_idx = 0 ; fill_idx < idx ; fill_idx++ ){
+ fill_values.push(0);
+ }
+ }
+ jqvalues.push(fill_values);
+ }
+ current_serie_values.push(serie_value);
+ var current_value = serie_values[inner_idx][1];
+ jqvalues[series.indexOf(serie_value)].push(current_value);
+ }
+ // put 0 for missing series for this item
+ for (idx_serie in series){
+ if (current_serie_values.indexOf(series[idx_serie]) == -1){
+ jqvalues[series.indexOf(series[idx_serie])].push(0);
+ }
+ }
+ }
+ stats_xaxis['ticks'] = ticks;
+ } else {
+ jqvalues = [stats_values];
+ series.push("Total");
+ }
+ if (stats_type != "pie"){
+ stats_xaxis['renderer'] = $.jqplot.CategoryAxisRenderer;
+ stats_xaxis['labelRenderer'] = $.jqplot.CanvasAxisLabelRenderer;
+ stats_xaxis['tickRenderer'] = $.jqplot.CanvasAxisTickRenderer;
+ }
+
+ var stats_renderer;
+ if (stats_type == "bar"){
+ stats_renderer = $.jqplot.BarRenderer;
+ } else if (stats_type == "pie"){
+ stats_renderer = $.jqplot.PieRenderer;
+ }
+ for (idx in series){
+ var serie_conf = {
+ label: series[idx],
+ showmarker: stats_showmarker
+ };
+ if (stats_renderer){
+ serie_conf["renderer"] = stats_renderer;
+ }
+ serie_conf["rendererOptions"] = {
+ padding: 8, showDataLabels: true,
+ dataLabels: 'value',
+ fill: false, sliceMargin: 4
+ };
+ series_conf.push(serie_conf);
+ }
+
+ var stats_options = {
+ axes: {
+ xaxis: stats_xaxis,
+ yaxis: {
+ label: $('#stats_sum-' + name + ' option:selected').text(),
+ min: 0
+ }
+ },
+ highlighter: {
+ show: true,
+ tooltipAxes: 'y',
+ sizeAdjust: 7.5
+ },
+ series: series_conf,
+ legend: { show:true, location: 'e', placement: 'outside' }
+ };
+ if (stats_type != "pie"){
+ stats_options["cursor"] = {
+ show: true,
+ zoom: true,
+ showTooltip: false
+ }
+ }
+
+ stats_current_graph = $.jqplot('chart-' + name,
+ jqvalues, stats_options
+ );
+};
diff --git a/ishtar_common/templates/base.html b/ishtar_common/templates/base.html
index 8d569711e..f88f1eba6 100644
--- a/ishtar_common/templates/base.html
+++ b/ishtar_common/templates/base.html
@@ -32,6 +32,17 @@
<script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/ishtar.js?ver={{VERSION}}"></script>
<script language="javascript" type="text/javascript"
src="{{STATIC_URL}}datatables/i18n/{{LANGUAGE_CODE}}.js?ver={{VERSION}}"></script>
+ <!-- jqplot -->
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/jquery.jqplot.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.categoryAxisRenderer.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.canvasTextRenderer.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.highlighter.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.barRenderer.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.pieRenderer.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.dateAxisRenderer.min.js?ver={{VERSION}}"></script>
+ <script language="javascript" type="text/javascript" src="{{STATIC_URL}}js/jqplot/plugins/jqplot.cursor.min.js?ver={{VERSION}}"></script>
{{EXTRA_JS|safe}}
<script type='text/javascript'>
var static_path = "{{STATIC_URL}}";
@@ -54,6 +65,8 @@
var select_only_one_msg = "{% trans "Select only one item." %}";
var YES = "{% trans 'yes' %}";
var NO = "{% trans 'no' %}";
+ var fetching_msg = "{% trans 'Fetching data...' %}";
+ var stats_incompatible_modality = "{% trans 'This graph type accept only one modality.' %}";
var show_msg = "{% trans "Show" %}";
var entries_msg = "{% trans "entries" %}";
var info_show_msg = "{% trans "Showing" %}";
@@ -85,6 +98,7 @@
<link rel="stylesheet" href="{{STATIC_URL}}datatables/dataTables.bootstrap4.min.css?ver={{VERSION}}">
<link type="text/css" rel="stylesheet" href="{{STATIC_URL}}lightgallery/css/lightgallery.css?ver={{VERSION}}">
<link rel="stylesheet" href="{{STATIC_URL}}ol/ol.css?ver={{VERSION}}">
+ <link rel="stylesheet" href="{{STATIC_URL}}js/jqplot/jquery.jqplot.min.css?ver={{VERSION}}" />
<link rel="stylesheet" href="{{STATIC_URL}}media/styles.css?ver={{VERSION}}">
{% for url_css in JQGRID_CSS %}<link rel="stylesheet" href="{{url_css}}?ver={{VERSION}}">{% endfor %}
{{EXTRA_CSS|safe}}
diff --git a/ishtar_common/templates/blocks/DataTables-tabs.html b/ishtar_common/templates/blocks/DataTables-tabs.html
index 73653061d..a2f354240 100644
--- a/ishtar_common/templates/blocks/DataTables-tabs.html
+++ b/ishtar_common/templates/blocks/DataTables-tabs.html
@@ -22,6 +22,14 @@
{% trans "Map" %}
</a>
</li>{% endif %}
+ {% if current_model.STATISTIC_MODALITIES %}
+ <li class="nav-item">
+ <a class="nav-link" id="tab-stats-{{name}}" data-toggle="tab"
+ href="#tab-content-stats-{{name}}" role="tab"
+ aria-controls="tab-content-stats-{{name}}" aria-selected="true">
+ {% trans "Statistics" %}
+ </a>
+ </li>{% endif %}
</ul>
<div class="tab-content">
@@ -38,4 +46,10 @@
id="tab-content-map-{{name}}" role="tabpanel"
aria-labelledby="tab-map-{{name}}">
</div>{% endif %}
+ {% if current_model.STATISTIC_MODALITIES %}
+ <div class="tab-pane"
+ id="tab-content-stats-{{name}}" role="tabpanel"
+ aria-labelledby="tab-stats-{{name}}">
+ {% include "blocks/DataTables-stats.html" %}
+ </div>{% endif %}
</div>
diff --git a/ishtar_common/templates/blocks/DataTables.html b/ishtar_common/templates/blocks/DataTables.html
index a20a151a9..01aa7519d 100644
--- a/ishtar_common/templates/blocks/DataTables.html
+++ b/ishtar_common/templates/blocks/DataTables.html
@@ -67,6 +67,12 @@ $("#tab-map-{{name}}").click(function(){
map_submit_search();
});
{% endif %}
+{% if current_model.STATISTIC_MODALITIES %}
+$("#tab-stats-{{name}}").click(function(){
+ current_tab = "stats";
+ stats_submit_search();
+});
+{% endif %}
var query_vars = new Array({{col_idx|safe}});
@@ -74,65 +80,17 @@ var selItems_{{sname}} = new Array();
{% if gallery %}
gallery_submit_search = function(image_page){
- if (image_page) {
- current_image_page = image_page;
- } else {
- current_image_page = 1;
- }
- $('.modal-progress').modal('show');
- var data = search_get_query_data(query_vars, "{{name}}");
- var nb_select = jQuery("#id_{{name}}-length_image").val();
- if (!nb_select) nb_select = 10;
-
- var url = "{{source}}json-image?length=" + nb_select + "&submited=1&" + data;
- $.getJSON(url, function(data) {
- var timestamp = Math.floor(Date.now() / 1000);
- var gallery_id = "gallery-" + timestamp;
- $("#tab-content-gallery-{{name}}").html(
- render_gallery(data, "{{name}}", nb_select, gallery_id));
- $("#id_{{name}}-length_image").change(gallery_submit_search);
- register_image_gallery(gallery_id);
- $('.card[data-toggle="tooltip"]').tooltip();
- if ($('.modal-progress').length > 0){
- $('.modal-progress').modal('hide');
- }
- });
- return false;
+ return _gallery_submit_search(image_page, query_vars, "{{name}}", "{{source}}");
};
{% endif %}
{% if use_map %}
map_submit_search = function(){
- var modal_base_text = $('.modal-progress .modal-header').html();
- $('.modal-progress .modal-header').html("{% trans 'Fetching data...' %}");
- $('.modal-progress').modal('show');
- var data = search_get_query_data(query_vars, "{{name}}");
- var nb_select = jQuery("#id_{{name}}-length_map").val();
- if (!nb_select) nb_select = 10;
-
- var url = "{{source}}json-map?length=" + nb_select + "&submited=1&" + data;
- var use_map_limit = false;
- if(data.indexOf("no_limit=true") == -1){
- url += "&limit=" + current_map_limit;
- use_map_limit = true;
- }
- $.getJSON(url, function(data) {
- var timestamp = Math.floor(Date.now() / 1000);
- var map_id = "map-" + timestamp;
- $('.modal-progress .modal-header').html("{% trans 'Render map...' %}");
-
- var html = render_map(map_id, use_map_limit);
- $("#tab-content-map-{{name}}").html(html);
- $("#id_{{name}}-length_map").change(map_submit_search);
- if ($('.modal-progress').length > 0){
- $('.modal-progress').modal('hide');
- $('.modal-progress .modal-header').html(modal_base_text);
- }
- register_map(map_id, data);
- });
-
- return false;
+ return _map_submit_search(query_vars, "{{name}}", "{{source}}");
};
{% endif %}
+stats_submit_search = function(){
+ return _stats_submit_search(query_vars, "{{name}}", "{{source}}");
+};
datatable_submit_search = function(not_submited){
var data = search_get_query_data(query_vars, "{{name}}");
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 145c56ca4..5b32a5fce 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -1207,19 +1207,29 @@ def _get_data_from_query_old(items, query_table_cols, request,
def _get_json_stats(items, stats_sum_variable, stats_modality_1,
stats_modality_2):
- q = items.values(stats_modality_1, stats_modality_2)
+ if stats_modality_2:
+ q = items.values(stats_modality_1, stats_modality_2)
+ else:
+ q = items.values(stats_modality_1)
if stats_sum_variable == 'pk':
q = q.annotate(sum=Count('pk'))
else:
q = q.annotate(sum=Sum(stats_sum_variable))
data = []
- for values in q.order_by(stats_modality_1, stats_modality_2).all():
- modality_1 = values[stats_modality_1]
- if not data or data[-1][0] != modality_1:
- data.append([modality_1, []])
- data[-1][1].append(
- (values[stats_modality_2], values["sum"])
- )
+ if stats_modality_2 and stats_modality_2 != stats_modality_1:
+ q = q.order_by(stats_modality_1, stats_modality_2)
+ for values in q.all():
+ modality_1 = values[stats_modality_1]
+ if not data or data[-1][0] != modality_1:
+ data.append([modality_1, []])
+ data[-1][1].append(
+ (values[stats_modality_2], values["sum"])
+ )
+ else:
+ q = q.order_by(stats_modality_1)
+ for values in q.all():
+ modality_1 = values[stats_modality_1]
+ data.append([modality_1, values["sum"]])
data = json.dumps({"data": data})
return HttpResponse(data, content_type='application/json')
@@ -1634,9 +1644,8 @@ def get_item(model, func_name, default_name, extra_request_keys=None,
if not stats_modality_1 or \
stats_modality_1 not in model.STATISTIC_MODALITIES:
stats_modality_1 = model.STATISTIC_MODALITIES[0]
- if not stats_modality_2 or \
- stats_modality_2 not in model.STATISTIC_MODALITIES:
- stats_modality_2 = model.STATISTIC_MODALITIES[1]
+ if stats_modality_2 not in model.STATISTIC_MODALITIES:
+ stats_modality_2 = None
stats_sum_variable = request_items.get('stats_sum_variable', None)
stats_sum_variable_keys = list(model.STATISTIC_SUM_VARIABLE.keys())
if not stats_sum_variable or \