dataviz: add time range fields (#49248)
This commit is contained in:
parent
6fe79041bf
commit
c492cf4d02
|
@ -47,8 +47,12 @@ class ChartNgForm(forms.ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = ChartNgCell
|
||||
fields = ('title', 'statistic', 'chart_type', 'height', 'sort_order',
|
||||
'hide_null_values')
|
||||
fields = ('title', 'statistic', 'time_range','time_range_start', 'time_range_end', 'chart_type',
|
||||
'height', 'sort_order', 'hide_null_values')
|
||||
widgets = {
|
||||
'time_range_start': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||
'time_range_end': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -61,6 +65,10 @@ class ChartNgForm(forms.ModelForm):
|
|||
stat_field.queryset = stat_field.queryset.filter(Q(available=True) | Q(pk=self.instance.statistic.pk))
|
||||
|
||||
field_ids = list(self._meta.fields)
|
||||
if self.instance.statistic.service_slug == 'bijoe':
|
||||
field_ids = [
|
||||
x for x in field_ids if x not in ('time_range', 'time_range_start', 'time_range_end')
|
||||
]
|
||||
field_insert_index = field_ids.index('statistic') + 1
|
||||
for filter_ in reversed(self.instance.statistic.filters):
|
||||
filter_id = filter_['id']
|
||||
|
@ -82,6 +90,7 @@ class ChartNgForm(forms.ModelForm):
|
|||
def save(self, *args, **kwargs):
|
||||
if 'statistic' in self.changed_data:
|
||||
self.instance.filter_params.clear()
|
||||
self.instance.time_range = ''
|
||||
else:
|
||||
for filter_ in self.instance.statistic.filters:
|
||||
field = filter_['id']
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.29 on 2020-12-15 15:24
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dataviz', '0015_auto_20201202_1424'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='chartngcell',
|
||||
name='time_range',
|
||||
field=models.CharField(blank=True, choices=[('current-year', 'Current year'), ('previous-year', 'Previous year'), ('current-month', 'Current month'), ('previous-month', 'Previous month'), ('range', 'Free range')], max_length=20, verbose_name='Filtering (time)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chartngcell',
|
||||
name='time_range_end',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='To'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chartngcell',
|
||||
name='time_range_start',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='From'),
|
||||
),
|
||||
]
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
import copy
|
||||
import os
|
||||
from datetime import date
|
||||
|
||||
from django.urls import reverse
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.translation import ugettext_lazy as _, ungettext, gettext
|
||||
from django.conf import settings
|
||||
|
@ -137,11 +139,33 @@ class Statistic(models.Model):
|
|||
|
||||
@register_cell_class
|
||||
class ChartNgCell(CellBase):
|
||||
TIME_FILTERS = (
|
||||
('current-year', _('Current year')),
|
||||
('previous-year', _('Previous year')),
|
||||
('current-month', _('Current month')),
|
||||
('previous-month', _('Previous month')),
|
||||
('range', _('Free range')),
|
||||
)
|
||||
|
||||
statistic = models.ForeignKey(
|
||||
verbose_name=_('Data'), to=Statistic, blank=False, null=True, on_delete=models.SET_NULL, related_name='cells'
|
||||
)
|
||||
filter_params = JSONField(default=dict)
|
||||
title = models.CharField(_('Title'), max_length=150, blank=True)
|
||||
time_range = models.CharField(
|
||||
_('Filtering (time)'),
|
||||
max_length=20,
|
||||
blank=True,
|
||||
choices=(
|
||||
('current-year', _('Current year')),
|
||||
('previous-year', _('Previous year')),
|
||||
('current-month', _('Current month')),
|
||||
('previous-month', _('Previous month')),
|
||||
('range', _('Free range')),
|
||||
)
|
||||
)
|
||||
time_range_start = models.DateField(_('From'), null=True, blank=True)
|
||||
time_range_end = models.DateField(_('To'), null=True, blank=True)
|
||||
chart_type = models.CharField(_('Chart Type'), max_length=20, default='bar',
|
||||
choices=(
|
||||
('bar', _('Bar')),
|
||||
|
@ -215,7 +239,7 @@ class ChartNgCell(CellBase):
|
|||
def get_chart(self, width=None, height=None, raise_if_not_cached=False):
|
||||
response = requests.get(
|
||||
self.statistic.url,
|
||||
params=self.filter_params,
|
||||
params=self.get_filter_params(),
|
||||
cache_duration=300,
|
||||
remote_service='auto',
|
||||
without_user=True,
|
||||
|
@ -267,6 +291,26 @@ class ChartNgCell(CellBase):
|
|||
|
||||
return chart
|
||||
|
||||
def get_filter_params(self):
|
||||
params = self.filter_params.copy()
|
||||
now = timezone.now().date()
|
||||
if self.time_range == 'current-year':
|
||||
params['start'] = date(year=now.year, month=1, day=1)
|
||||
elif self.time_range == 'previous-year':
|
||||
params['start'] = date(year=now.year - 1, month=1, day=1)
|
||||
params['end'] = date(year=now.year, month=1, day=1)
|
||||
elif self.time_range == 'current-month':
|
||||
params['start'] = date(year=now.year, month=now.month, day=1)
|
||||
elif self.time_range == 'previous-month':
|
||||
params['start'] = date(year=now.year, month=now.month - 1, day=1)
|
||||
params['end'] = date(year=now.year, month=now.month, day=1)
|
||||
elif self.time_range == 'range':
|
||||
if self.time_range_start:
|
||||
params['start'] = self.time_range_start
|
||||
if self.time_range_end:
|
||||
params['end'] = self.time_range_end
|
||||
return params
|
||||
|
||||
def parse_response(self, response, chart):
|
||||
# normalize axis to have a fake axis when there are no dimensions and
|
||||
# always a x axis when there is a single dimension.
|
||||
|
|
|
@ -6,3 +6,19 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
start_field = $('#id_cdataviz_chartngcell-{{ cell.pk }}-time_range_start');
|
||||
end_field = $('#id_cdataviz_chartngcell-{{ cell.pk }}-time_range_end');
|
||||
$('#id_cdataviz_chartngcell-{{ cell.pk }}-time_range').change(function() {
|
||||
if(this.value == 'range') {
|
||||
start_field.parent().show();
|
||||
end_field.parent().show();
|
||||
} else {
|
||||
start_field.parent().hide();
|
||||
end_field.parent().hide();
|
||||
}
|
||||
}).change();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -2,7 +2,7 @@ import json
|
|||
|
||||
import mock
|
||||
import pytest
|
||||
from datetime import timedelta
|
||||
from datetime import timedelta, date
|
||||
from httmock import HTTMock, with_httmock, remember_called, urlmatch
|
||||
from requests.exceptions import HTTPError
|
||||
|
||||
|
@ -931,6 +931,9 @@ def test_chartng_cell_manager(app, admin_user, statistics):
|
|||
assert statistics_field.value == str(cell.statistic.pk)
|
||||
assert statistics_field.options[1][2] == 'test: eighth visualization (duration)'
|
||||
assert not 'Unavailable Stat' in resp.text
|
||||
assert 'time_range' not in resp.form.fields
|
||||
assert 'time_range_start' not in resp.form.fields
|
||||
assert 'time_range_end' not in resp.form.fields
|
||||
|
||||
cell.statistic = Statistic.objects.get(slug='unavailable-stat')
|
||||
cell.save()
|
||||
|
@ -986,6 +989,27 @@ def test_chartng_cell_manager_new_api(app, admin_user, new_api_statistics):
|
|||
cell.refresh_from_db()
|
||||
assert cell.filter_params == {'time_interval': 'month'}
|
||||
|
||||
resp.form[field_prefix + 'time_range'] = 'previous-year'
|
||||
resp = resp.form.submit().follow()
|
||||
cell.refresh_from_db()
|
||||
assert cell.time_range == 'previous-year'
|
||||
|
||||
resp.form[field_prefix + 'time_range'] = 'range'
|
||||
resp.form[field_prefix + 'time_range_start'] = '2020-10-01'
|
||||
resp.form[field_prefix + 'time_range_end'] = '2020-11-03'
|
||||
resp = resp.form.submit().follow()
|
||||
cell.refresh_from_db()
|
||||
assert cell.time_range == 'range'
|
||||
assert cell.time_range_start == date(year=2020, month=10, day=1)
|
||||
assert cell.time_range_end == date(year=2020, month=11, day=3)
|
||||
|
||||
resp.form[field_prefix + 'time_range_start'] = ''
|
||||
resp.form[field_prefix + 'time_range_end'] = ''
|
||||
resp = resp.form.submit().follow()
|
||||
cell.refresh_from_db()
|
||||
assert cell.time_range_start is None
|
||||
assert cell.time_range_end is None
|
||||
|
||||
no_filters_stat = Statistic.objects.get(slug='two-series')
|
||||
resp.form[field_prefix + 'statistic'] = no_filters_stat.pk
|
||||
resp = resp.form.submit().follow()
|
||||
|
@ -994,6 +1018,7 @@ def test_chartng_cell_manager_new_api(app, admin_user, new_api_statistics):
|
|||
assert field_prefix + 'ou' not in resp.form.fields
|
||||
cell.refresh_from_db()
|
||||
assert cell.filter_params == {}
|
||||
assert cell.time_range == ''
|
||||
|
||||
|
||||
@with_httmock(new_api_mock)
|
||||
|
@ -1198,7 +1223,7 @@ def test_dataviz_api_list_statistics(new_api_statistics, settings):
|
|||
|
||||
|
||||
@with_httmock(new_api_mock)
|
||||
def test_chartng_cell_new_api_filter_params(new_api_statistics, nocache):
|
||||
def test_chartng_cell_new_api_filter_params(new_api_statistics, nocache, freezer):
|
||||
page = Page.objects.create(title='One', slug='index')
|
||||
cell = ChartNgCell(page=page, order=1, placeholder='content')
|
||||
cell.statistic = Statistic.objects.get(slug='one-serie')
|
||||
|
@ -1215,3 +1240,30 @@ def test_chartng_cell_new_api_filter_params(new_api_statistics, nocache):
|
|||
request = new_api_mock.call['requests'][1]
|
||||
assert 'time_interval=day' in request.url
|
||||
assert 'ou=default' in request.url
|
||||
|
||||
freezer.move_to('2020-03-02 12:01')
|
||||
cell.time_range = 'previous-year'
|
||||
cell.save()
|
||||
chart = cell.get_chart()
|
||||
request = new_api_mock.call['requests'][2]
|
||||
assert 'time_interval=day' in request.url
|
||||
assert 'ou=default' in request.url
|
||||
assert 'start=2019-01-01' in request.url and 'end=2020-01-01' in request.url
|
||||
|
||||
cell.time_range = 'range'
|
||||
cell.save()
|
||||
chart = cell.get_chart()
|
||||
request = new_api_mock.call['requests'][3]
|
||||
assert 'start' not in request.url and 'end' not in request.url
|
||||
|
||||
cell.time_range_start = '2020-10-01'
|
||||
cell.save()
|
||||
chart = cell.get_chart()
|
||||
request = new_api_mock.call['requests'][4]
|
||||
assert 'start=2020-10-01' in request.url
|
||||
|
||||
cell.time_range_end = '2020-11-03'
|
||||
cell.save()
|
||||
chart = cell.get_chart()
|
||||
request = new_api_mock.call['requests'][5]
|
||||
assert 'start=2020-10-01' in request.url and 'end=2020-11-03' in request.url
|
||||
|
|
Loading…
Reference in New Issue