api: add json view of visualization data (#26847)

This commit is contained in:
Frédéric Péters 2019-02-24 09:39:15 +01:00
parent 81a66fcbce
commit 4796c5cf2e
3 changed files with 92 additions and 0 deletions

View File

@ -30,6 +30,7 @@ urlpatterns = [
url(r'warehouse/(?P<warehouse>[^/]*)/(?P<cube>[^/]*)/save/$',
views.create_visualization, name='create-visualization'),
url(r'(?P<pk>\d+)/$', views.visualization, name='visualization'),
url(r'(?P<pk>\d+)/json/$', views.visualization_json, name='visualization-json'),
url(r'(?P<pk>\d+)/geojson/$', views.visualization_geojson, name='visualization-geojson'),
url(r'(?P<pk>\d+)/iframe/$', views.visualization_iframe, name='visualization-iframe'),
url(r'(?P<pk>\d+)/ods/$', views.visualization_ods, name='visualization-ods'),

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from collections import OrderedDict
import hashlib
import json
@ -212,9 +213,11 @@ class VisualizationsJSONView(MultipleObjectMixin, View):
path = reverse('visualization-iframe', kwargs={'pk': visualization.pk})
sig = hashlib.sha1(path + settings.SECRET_KEY).hexdigest()
path += '?signature=' + sig
data_uri = reverse('visualization-json', kwargs={'pk': visualization.pk})
data.append({
'name': visualization.name,
'path': request.build_absolute_uri(path),
'data-url': request.build_absolute_uri(data_uri),
})
response = HttpResponse(content_type='application/json')
response.write(json.dumps(data))
@ -263,6 +266,66 @@ class VisualizationGeoJSONView(generics.GenericAPIView):
return Response(geojson)
class VisualizationJSONView(generics.GenericAPIView):
permission_classes = ()
queryset = models.Visualization.objects.all()
def get(self, request, pk, format=None):
instance = self.get_object()
loop = []
all_visualizations = Visualization.from_json(instance.parameters, request=request)
for visualization in all_visualizations:
drilldowns = visualization.drilldown
if len(drilldowns) == 2:
x_labels = [x.label for x in visualization.drilldown_x.members]
y_labels = [y.label for y in visualization.drilldown_y.members]
used_x_labels = OrderedDict()
used_y_labels = OrderedDict()
default = 0
grid = {(x, y): default for x in x_labels for y in y_labels}
for row in visualization.data():
x_label = unicode(row[0]['value'])
y_label = unicode(row[1]['value'])
used_x_labels[x_label] = True
used_y_labels[y_label] = True
grid[(x_label, y_label)] = row[2]['value']
data = []
for y in used_y_labels.keys():
data.append([grid[(x, y)] for x in used_x_labels.keys()])
axis = {
'x_labels': [x.strip() for x in used_x_labels.keys()],
'y_labels': [x.strip() for x in used_y_labels.keys()]
}
elif len(drilldowns) == 1:
table = list(visualization.data())
axis_data = [x[0]['value'].strip() for x in table]
data = [x[1]['value'] for x in table]
if visualization.drilldown_x:
axis = {'x_labels': axis_data}
else:
axis = {'y_labels': axis_data}
elif len(drilldowns) == 0:
data = list(list(visualization.data())[0])[0]['value']
axis = {}
loop.append({'data': data, 'axis': axis})
if not all_visualizations.loop:
data = loop[0]['data']
axis = loop[0]['axis']
else:
axis = loop[0]['axis']
axis['loop'] = [x.label for x in all_visualizations.loop.members]
data = [x['data'] for x in loop]
return Response({
'data': data,
'axis': axis,
'format': '1',
})
warehouse = WarehouseView.as_view()
cube = CubeView.as_view()
cube_iframe = xframe_options_exempt(CubeIframeView.as_view())
@ -275,6 +338,7 @@ visualization = VisualizationView.as_view()
visualization_iframe = xframe_options_exempt(VisualizationIframeView.as_view())
visualization_geojson = VisualizationGeoJSONView.as_view()
visualization_ods = VisualizationODSView.as_view()
visualization_json = VisualizationJSONView.as_view()
cube_iframe.mellon_no_passive = True
visualization_iframe.mellon_no_passive = True

View File

@ -14,6 +14,10 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.core.urlresolvers import reverse
from bijoe.visualization.models import Visualization
from utils import login
@ -29,3 +33,26 @@ def test_superuser(app, admin):
assert len(resp.json) == 1
assert resp.json[0]['slug'] == 'statistics'
app.get('/', status=200)
def test_visualization_json_api(schema1, app, admin):
visualization = Visualization(
name='test',
parameters={
'cube': 'facts1',
'warehouse': 'schema1',
'measure': 'simple_count',
'representation': 'table',
'loop': '',
'filters': {},
'drilldown_x': 'date__yearmonth'})
visualization.save()
login(app, admin)
resp = app.get(reverse('visualization-json', kwargs={'pk': visualization.id}))
# values from test_schem1/test_yearmonth_drilldown
assert resp.json == {
'axis': {'x_labels': ['01/2017', '02/2017', '03/2017', '04/2017', '05/2017', '06/2017', '07/2017', '08/2017']},
'data': [10, 1, 1, 1, 1, 1, 1, 1],
'format': '1'
}