Преглед на файлове

HUE-2300 [search] Linking real data to Pivot 2D chart

Romain Rigaux преди 11 години
родител
ревизия
3148ce2

+ 27 - 1
apps/search/src/search/models.py

@@ -493,7 +493,7 @@ def augment_solr_response(response, collection, query):
       elif category == 'pivot':
         name = ','.join([facet['field']] + [f['field'] for f in facet['properties']['facets']])
         if 'facet_pivot' in response['facet_counts'] and name in response['facet_counts']['facet_pivot']:
-          count = response['facet_counts']['facet_pivot'][name]
+          count = _augment_pivot_2d(response['facet_counts']['facet_pivot'][name])
         else:
           count = []
         facet = {
@@ -533,6 +533,32 @@ def augment_solr_response(response, collection, query):
 
   return augmented
 
+
+def _augment_pivot_2d(counts):
+  values = set()
+  
+  for dimension in counts:
+    for pivot in dimension['pivot']:
+      values.add(pivot['value'])
+  
+  values = sorted(list(values))
+  
+  augmented = []
+  
+  for dimension in counts:
+    count = {}
+    for pivot in dimension['pivot']:
+      count[pivot['value']] = pivot['count']
+    for val in values:
+      if val in count:      
+        c = {"count": count[pivot['value']], "value": val, "cat": dimension['value']}
+      else:
+        c = {"count": 0, "value": val, "cat": dimension['value']}
+      augmented.append(c)
+      
+  return augmented
+    
+
 def augment_solr_exception(response, collection):
   response.update(
   {

+ 37 - 22
apps/search/src/search/templates/search.mako

@@ -238,8 +238,16 @@ ${ dashboard.layout_skeleton() }
     <!-- ko if: type() == 'pivot' -->
       ${ _('Limit') } <input type="text" class="input-medium" data-bind="value: properties.limit"/>
       ${ _('Mincount') } <input type="text" class="input-medium" data-bind="value: properties.mincount"/>
-      ${ _('Plot') } <input type="checkbox" data-bind="checked: properties.graph"></span>
+      ${ _('Plot') }
+      <select data-bind="selectedOptions: properties.scope" class="input-small">
+        <option value="tree">${ _("Tree") }</option>
+        <option value="stack">${ _("Stacked Bars") }</option>
+        <option value="heat">${ _("Heat Map") }</option>
+      </select>
+
+      </br>
 
+      ${ _('Add a dimension') }
       <select data-bind="options: $root.collection.template.fieldsNames, value: properties.facets_form.field, optionsCaption: ' '"></select>
       <input type="text" class="input-medium" data-bind="value: properties.facets_form.limit"/>
       <input type="text" class="input-medium" data-bind="value: properties.facets_form.mincount"/>
@@ -790,7 +798,6 @@ ${ dashboard.layout_skeleton() }
     </div>
 
     <div data-bind="with: $root.collection.getFacetById($parent.id())">
-      ${ _('Cross with') }
       <div data-bind="foreach: $data.properties.facets">
         <span data-bind="text: field"></span>
         ${ _('Limit') } <input type="text" class="input-medium" data-bind="value: limit"/>
@@ -799,28 +806,39 @@ ${ dashboard.layout_skeleton() }
           <i class="fa fa-minus"></i>
         </a>
       </div>
-    </div>
 
-    <span data-bind="text: ko.mapping.toJSON(count)"></span>
+      <!-- ko if: properties.scope() == 'tree' -->
+        TREE
+        <span data-bind="text: ko.mapping.toJSON($parent.count)"></span>
+      <!-- /ko -->
 
-    <div data-bind="barChart: {datum: {counts: count, widget_id: $parent.id(), label: label}, stacked: true,
-      isPivot: true,
-      fqs: $root.query.fqs,
-      transformer: pivotChartDataTransformer,
-      onStateChange: function(state){ },
-      onClick: function(d) {
-        if (d.obj.field != undefined) {
-          viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: d.obj.widget_id, from: d.obj.from, to: d.obj.to, cat: d.obj.field});
-        } else {
-          viewModel.query.toggleFacet({facet: d.obj, widget_id: d.obj.widget_id});
-        }
-      },
-      onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: id}) },
-      onComplete: function(){ viewModel.getWidgetById(id).isLoading(false) } }"
-    />
+      <!-- ko if: properties.scope() == 'stack' -->
+        STACK
+        <div data-bind="barChart: {datum: {counts: $parent.count, widget_id: id(), label: $parent.label}, stacked: true,
+          isPivot: true,
+          fqs: $root.query.fqs,
+          transformer: pivotChartDataTransformer,
+          onStateChange: function(state){ },
+          onClick: function(d) {
+            if (d.obj.field != undefined) {
+              viewModel.query.selectRangeFacet({count: d.obj.value, widget_id: d.obj.widget_id, from: d.obj.from, to: d.obj.to, cat: d.obj.field});
+            } else {
+              viewModel.query.toggleFacet({facet: d.obj, widget_id: d.obj.widget_id});
+            }
+          },
+          onSelectRange: function(from, to){ viewModel.collection.selectTimelineFacet({from: from, to: to, cat: field, widget_id: id}) },
+          onComplete: function(){ viewModel.getWidgetById(id()).isLoading(false) } }"
+        />
+      <!-- /ko -->
 
+      <!-- ko if: properties.scope() == 'heat' -->
+        HOT
+        <span data-bind="text: ko.mapping.toJSON($parent.count)"></span>
+      <!-- /ko -->
+    </div>    
   </div>
   <!-- /ko -->
+
   <div class="widget-spinner" data-bind="visible: isLoading()">
     <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
     <!--[if IE]><img src="/static/art/spinner.gif" /><![endif]-->
@@ -1158,9 +1176,6 @@ function barChartDataTransformer(rawDatum) {
 }
 
 function pivotChartDataTransformer(rawDatum) {
-
-  rawDatum = {"counts": [{"count": 904, "value": "Firefox", "cat": "US"}, {"count": 96, "selected": false, "value": "Explorer", "cat": "US"}, {"count": 116, "selected": false, "value": "Chrome", "cat": "US"}, {"count": 94, "value": "Firefox", "cat": "CUR"}, {"count": 6, "selected": false, "value": "Explorer", "cat": "CUR"}, {"count": 16, "selected": false, "value": "Chrome", "cat": "CUR"}]};
-
   var _datum = [];
   var _data = [];
 

+ 2 - 2
apps/search/src/search/views.py

@@ -473,8 +473,8 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
   elif widget_type == 'tree-widget':
     properties['mincount'] = 1
     properties['facets'] = []
-    properties['facets_form'] = {'field': '', 'mincount': 1, 'limit': 10}
-    properties['graph'] = False
+    properties['facets_form'] = {'field': '', 'mincount': 1, 'limit': 5}
+    properties['scope'] = 'tree'
 
   return {
     'id': facet_id,

+ 2 - 2
apps/search/static/js/search.ko.js

@@ -418,7 +418,7 @@ var Collection = function (vm, collection) {
           'mincount': facet.properties.facets_form.mincount,
       });
       facet.properties.facets_form.field = null;
-      facet.properties.facets_form.limit = 10;
+      facet.properties.facets_form.limit = 5;
       facet.properties.facets_form.mincount = 1;
     } else {
       pivot = ko.mapping.fromJS({
@@ -427,7 +427,7 @@ var Collection = function (vm, collection) {
           'mincount': facet.properties.facets_form.mincount(),
       });
       facet.properties.facets_form.field(null);
-      facet.properties.facets_form.limit(10);
+      facet.properties.facets_form.limit(5);
       facet.properties.facets_form.mincount(1);
     }
 

+ 1 - 1
desktop/libs/libsolr/src/libsolr/api.py

@@ -136,7 +136,7 @@ class SolrApi(object):
               fields += ',' + f['field']
             params += (
                 ('facet.pivot', '{!ex=%s}%s' % (fields, fields)),
-                ('f.%s.facet.limit' % facet['field'], int(facet['properties'].get('limit', 10)) + 1),
+                ('f.%s.facet.limit' % facet['field'], int(facet['properties'].get('limit', 10))),
                 ('facet.pivot.mincount', int(facet['properties']['mincount'])),
             )