Przeglądaj źródła

HUE-2173 [search] Nested tree widget with dimension 1

Romain Rigaux 9 lat temu
rodzic
commit
eec86f3c76

+ 23 - 0
apps/search/src/search/models.py

@@ -830,6 +830,10 @@ def augment_solr_response(response, collection, query):
               _c = range_pair(facet['field'], name, selected_values.get(facet['id'], []), val, 1, collection_facet)
               _c = range_pair(facet['field'], name, selected_values.get(facet['id'], []), val, 1, collection_facet)
               extraSeries.append({'counts': _c, 'label': name})
               extraSeries.append({'counts': _c, 'label': name})
             counts = []
             counts = []
+        elif collection_facet['properties'].get('isOldPivot'):
+          count = response['facets'][name]
+          _convert_nested_to_augmented_pivot_nd(facet['id'], count, selected_values)
+          dimension = 1
         elif not collection_facet['properties']['facets'] or collection_facet['properties']['facets'][0]['aggregate'] not in ('count', 'unique'):
         elif not collection_facet['properties']['facets'] or collection_facet['properties']['facets'][0]['aggregate'] not in ('count', 'unique'):
           # Single dimension or dimension 2 with analytics
           # Single dimension or dimension 2 with analytics
           dimension = 1
           dimension = 1
@@ -1002,6 +1006,25 @@ def _augment_pivot_nd(facet_id, counts, selected_values, fields='', values=''):
     c['fq_fields'] = fq_fields
     c['fq_fields'] = fq_fields
     c['fq_values'] = fq_values
     c['fq_values'] = fq_values
 
 
+# {u'buckets': [{u'count': 4, u'val': u'electronics'}, {u'count': 3, u'val': u'memory'}, {u'count': 1, u'val': u'music'}, {u'count': 0, u'val': u'camera'}, {u'count': 0, u'val': u'connector'}, {u'count': 0, u'val': u'copier'}, {u'count': 0, u'val': u'currency'}, {u'count': 0, u'val': u'electronics and computer1'}, {u'count': 0, u'val': u'electronics and stuff2'}, {u'count': 0, u'val': u'graphics card'}]}
+
+def _convert_nested_to_augmented_pivot_nd(facet_id, counts, selected_values, fields='', values=''):  
+  for c in counts['buckets']:
+    c['field'] = 'cat' # Hack
+    fq_fields = (fields if fields else []) + [c['field']]
+    fq_values = (values if values else []) + [smart_str(c['val'])]
+    c['value'] = c.pop('val')
+
+    if 'pivot' in c:
+      _augment_pivot_nd(facet_id, c['pivot'], selected_values, fq_fields, fq_values)
+
+    fq_filter = selected_values.get(facet_id, [])
+    _selected_values = [f['value'] for f in fq_filter]
+    c['selected'] = fq_values in _selected_values
+    c['exclude'] = False
+    c['fq_fields'] = fq_fields
+    c['fq_values'] = fq_values
+
 
 
 def augment_solr_exception(response, collection):
 def augment_solr_exception(response, collection):
   response.update(
   response.update(

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

@@ -970,7 +970,7 @@ var Collection = function (vm, collection) {
     else if (self.template.fieldsModalType() == 'map-widget') {
     else if (self.template.fieldsModalType() == 'map-widget') {
       return vm.availableStringFields();
       return vm.availableStringFields();
     }
     }
-    else if (self.template.fieldsModalType() == 'tree-widget' || self.template.fieldsModalType() == 'heatmap-widget') {
+    else if (self.template.fieldsModalType() == 'tree-widget' || self.template.fieldsModalType() == 'tree2-widget' || self.template.fieldsModalType() == 'heatmap-widget') {
       return vm.availablePivotFields();
       return vm.availablePivotFields();
     }
     }
     else {
     else {
@@ -1360,12 +1360,13 @@ var SearchViewModel = function (collection_json, query_json, initial_json) {
   self.draggablePie = ko.observable(bareWidgetBuilder("Pie Chart", "pie-widget")); // Deprecated
   self.draggablePie = ko.observable(bareWidgetBuilder("Pie Chart", "pie-widget")); // Deprecated
   self.draggablePie2 = ko.observable(bareWidgetBuilder("Pie Chart", "pie2-widget"));
   self.draggablePie2 = ko.observable(bareWidgetBuilder("Pie Chart", "pie2-widget"));
   self.draggableFilter = ko.observable(bareWidgetBuilder("Filter Bar", "filter-widget"));
   self.draggableFilter = ko.observable(bareWidgetBuilder("Filter Bar", "filter-widget"));
-  self.draggableTree = ko.observable(bareWidgetBuilder("Tree", "tree-widget"));
+  self.draggableTree = ko.observable(bareWidgetBuilder("Tree", "tree-widget")); // Deprecated
   self.draggableHeatmap = ko.observable(bareWidgetBuilder("Heatmap", "heatmap-widget"));
   self.draggableHeatmap = ko.observable(bareWidgetBuilder("Heatmap", "heatmap-widget"));
   self.draggableCounter = ko.observable(bareWidgetBuilder("Counter", "hit-widget"));
   self.draggableCounter = ko.observable(bareWidgetBuilder("Counter", "hit-widget"));
   self.draggableBucket = ko.observable(bareWidgetBuilder("Chart", "bucket-widget"));
   self.draggableBucket = ko.observable(bareWidgetBuilder("Chart", "bucket-widget"));
   self.draggableTimeline = ko.observable(bareWidgetBuilder("Timeline", "timeline-widget"));
   self.draggableTimeline = ko.observable(bareWidgetBuilder("Timeline", "timeline-widget"));
   self.draggableGradienMap = ko.observable(bareWidgetBuilder("Gradient Map", "gradient-map-widget"));
   self.draggableGradienMap = ko.observable(bareWidgetBuilder("Gradient Map", "gradient-map-widget"));
+  self.draggableTree2 = ko.observable(bareWidgetBuilder("Tree", "tree2-widget"));
 
 
   self.availableDateFields = ko.computed(function() {
   self.availableDateFields = ko.computed(function() {
     return $.grep(self.collection.availableFacetFields(), function(field) { return DATE_TYPES.indexOf(field.type()) != -1; });
     return $.grep(self.collection.availableFacetFields(), function(field) { return DATE_TYPES.indexOf(field.type()) != -1; });

+ 42 - 2
apps/search/src/search/templates/common_search.mako

@@ -253,7 +253,7 @@ from django.utils.translation import ugettext as _
                        <i class="hcha hcha-line-chart"></i>
                        <i class="hcha hcha-line-chart"></i>
          </a>
          </a>
     </div>
     </div>
-    <div data-bind="css: { 'draggable-widget': true, 'disabled': false },
+    <div data-bind="visible: $root.isLatest(), css: { 'draggable-widget': true, 'disabled': false },
                     draggable: {data: draggableTree(), isEnabled: true,
                     draggable: {data: draggableTree(), isEnabled: true,
                     options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
                     options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
                               'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
                               'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
@@ -262,6 +262,15 @@ from django.utils.translation import ugettext as _
                        <i class="fa fa-sitemap fa-rotate-270"></i>
                        <i class="fa fa-sitemap fa-rotate-270"></i>
          </a>
          </a>
     </div>
     </div>
+    <div data-bind="visible: $root.isLatest(), css: { 'draggable-widget': true, 'disabled': false },
+                    draggable: {data: draggableTree2(), isEnabled: true,
+                    options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
+                              'stop': function(event, ui){$('.card-body').slideDown('fast', function(){$(window).scrollTop(lastWindowScrollPosition)});}}}"
+         title="${_('Tree')}" rel="tooltip" data-placement="top">
+         <a data-bind="style: { cursor: $root.availableDraggableChart() ? 'move' : 'default' }">
+                       <i class="fa fa-sitemap fa-rotate-270"></i>
+         </a>
+    </div>
     <div data-bind="visible: ! $root.isLatest(),
     <div data-bind="visible: ! $root.isLatest(),
                     css: { 'draggable-widget': true, 'disabled': false },
                     css: { 'draggable-widget': true, 'disabled': false },
                     draggable: {data: draggableHeatmap(), isEnabled: true,
                     draggable: {data: draggableHeatmap(), isEnabled: true,
@@ -1521,7 +1530,6 @@ ${ dashboard.layout_skeleton() }
 
 
 <script type="text/html" id="pie2-widget">
 <script type="text/html" id="pie2-widget">
   <!-- ko if: $root.getFacetFromQuery(id()).has_data() -->
   <!-- ko if: $root.getFacetFromQuery(id()).has_data() -->
-
   <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
   <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
     <div data-bind="with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
     <div data-bind="with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
       <span data-bind="template: { name: 'facet-toggle2' }"></span>
       <span data-bind="template: { name: 'facet-toggle2' }"></span>
@@ -1553,6 +1561,7 @@ ${ dashboard.layout_skeleton() }
     </div>
     </div>
   </div>
   </div>
   <!-- /ko -->
   <!-- /ko -->
+
   <div class="widget-spinner" data-bind="visible: isLoading()">
   <div class="widget-spinner" data-bind="visible: isLoading()">
     <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
     <!--[if !IE]> --><i class="fa fa-spinner fa-spin"></i><!-- <![endif]-->
     <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
     <!--[if IE]><img src="${ static('desktop/art/spinner.gif') }" /><![endif]-->
@@ -1629,6 +1638,37 @@ ${ dashboard.layout_skeleton() }
 </script>
 </script>
 
 
 
 
+<script type="text/html" id="tree2-widget">
+  <!-- ko if: $root.getFacetFromQuery(id()).has_data() -->
+  <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
+    <div class="responsive-facet-toggle-section" data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())">
+      <span data-bind="template: { name: 'facet-toggle2' }"></span>
+    </div>
+
+    <div data-bind="with: $root.collection.getFacetById($parent.id())">
+      <!-- ko if: properties.scope() == 'tree' -->
+        <div data-bind="partitionChart: {datum: {counts: $parent.counts(), widget_id: $parent.id(), label: $parent.label()},
+          fqs: $root.query.fqs,
+          tooltip: '${ _ko('Click to zoom, double click to select') }',
+          transformer: partitionChartDataTransformer,
+          onStateChange: function(state){ },
+          onClick: function(d) {
+            $root.query.togglePivotFacet({facet: d.obj, widget_id: id()});
+          },
+          onComplete: function(){ viewModel.getWidgetById($parent.id()).isLoading(false) } }"
+        />
+      <!-- /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('desktop/art/spinner.gif') }" /><![endif]-->
+  </div>
+</script>
+
+
 <script type="text/html" id="heatmap-widget">
 <script type="text/html" id="heatmap-widget">
   <!-- ko if: $root.getFacetFromQuery(id()).has_data() -->
   <!-- ko if: $root.getFacetFromQuery(id()).has_data() -->
   <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
   <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">

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

@@ -542,7 +542,7 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
   if widget_type in ('tree-widget', 'heatmap-widget', 'map-widget'):
   if widget_type in ('tree-widget', 'heatmap-widget', 'map-widget'):
     facet_type = 'pivot'
     facet_type = 'pivot'
   elif widget_type == 'hit-widget':
   elif widget_type == 'hit-widget':
-    facet_type = 'function'
+    facet_type = 'function'    
   elif widget_type == 'gradient-map-widget':
   elif widget_type == 'gradient-map-widget':
     facet_type = 'nested'
     facet_type = 'nested'
     properties['facets'] = []
     properties['facets'] = []
@@ -562,13 +562,16 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
     else:
     else:
       facet_type = 'field'
       facet_type = 'field'
 
 
-    if widget_type == 'bucket-widget' or widget_type == 'pie2-widget' or widget_type == 'timeline-widget':
+    if widget_type in ('bucket-widget', 'pie2-widget', 'timeline-widget', 'tree2-widget'):
       facet_type = 'nested'
       facet_type = 'nested'
       properties['facets_form'] = {'field': '', 'mincount': 1, 'limit': 10, 'aggregate': 'count'}
       properties['facets_form'] = {'field': '', 'mincount': 1, 'limit': 10, 'aggregate': 'count'}
       properties['facets'] = []
       properties['facets'] = []
       if widget_type == 'pie2-widget':
       if widget_type == 'pie2-widget':
         properties['scope'] = 'stack'
         properties['scope'] = 'stack'
         properties['timelineChartType'] = 'bar'
         properties['timelineChartType'] = 'bar'
+      elif widget_type == 'tree2-widget':
+        properties['scope'] = 'tree'
+        properties['isOldPivot'] = True 
       else:
       else:
         properties['scope'] = 'stack'
         properties['scope'] = 'stack'
         properties['timelineChartType'] = 'bar'
         properties['timelineChartType'] = 'bar'