Browse Source

HUE-2173 [dashboard] Port timeline and gradient map widgets to recursive nested facets

Romain Rigaux 8 years ago
parent
commit
34eb533

+ 1 - 1
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -1339,7 +1339,7 @@
         }
       });
       _el.on("slideStop", function (e) {
-        viewModel.search();
+        searchViewModel.search();
       });
     },
     update: function (element, valueAccessor) {

+ 17 - 9
desktop/libs/dashboard/src/dashboard/api.py

@@ -378,13 +378,6 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
   elif widget_type == 'document-widget':
     properties['uuid'] = facet_field
     properties['subfacet'] = {}
-  elif widget_type == 'gradient-map-widget':
-    facet_type = 'nested'
-    properties['facets'] = []
-    properties['domain'] = {'blockParent': [], 'blockChildren': []}
-    properties['facets_form'] = NESTED_FACET_FORM
-    properties['scope'] = 'world'
-    properties['limit'] = 100
   else:
     api = get_engine(user, collection)
     range_properties = _new_range_facet(api, collection, facet_field, widget_type)
@@ -398,7 +391,7 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
     else:
       facet_type = 'field'
 
-    if widget_type in ('bucket-widget', 'pie2-widget', 'timeline-widget', 'tree2-widget', 'text-facet-widget', 'hit-widget'):
+    if widget_type in ('bucket-widget', 'pie2-widget', 'timeline-widget', 'tree2-widget', 'text-facet-widget', 'hit-widget', 'gradient-map-widget'):
       if widget_type == 'text-facet-widget':
         properties['type'] = facet_type
 
@@ -406,7 +399,22 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
       facet = NESTED_FACET_FORM.copy()
       facet['field'] = facet_field
       facet['limit'] = 10
-      properties['canRange'] = False
+
+      if range_properties:
+        facet.update(range_properties)
+        facet['initial_gap'] = properties['gap']
+        facet['initial_start'] = properties['start']
+        facet['initial_end'] = properties['end']
+        facet['stacked'] = False
+        facet['type'] = 'range'
+      else:
+        facet['canRange'] = False
+        facet['type'] = facet_type
+
+      if widget_type == 'gradient-map-widget':
+        properties['scope'] = 'world'
+        facet['limit'] = 100
+
       properties['facets'] = [facet]
       properties['domain'] = {'blockParent': [], 'blockChildren': []}
 

+ 2 - 0
desktop/libs/dashboard/src/dashboard/models.py

@@ -40,6 +40,8 @@ NESTED_FACET_FORM = {
     'mincount': 1,
     'limit': 5,
     'sort': 'desc',
+    'canRange': False,
+    'isDate': False,
     'aggregate': {'function': 'unique', 'formula': '', 'plain_formula': '', 'percentiles': [{'value': 50}]}
 }
 

+ 6 - 6
desktop/libs/dashboard/src/dashboard/static/dashboard/js/search.ko.js

@@ -1471,12 +1471,12 @@ var Collection = function (vm, collection) {
   self.toggleRangeFacet2 = function (facet_field, event) {
     vm.query.removeFilter(ko.mapping.fromJS({'id': facet_field.id})); // Reset filter query
 
-    if (facet_field.properties.type() == 'field') {
-       facet_field.properties.type('range');
-     } else if (facet_field.properties.type() == 'range') {
-       facet_field.properties.type('range-up')
-     } else if (facet_field.properties.type() == 'range-up') {
-       facet_field.properties.type('field')
+    if (facet_field.type() == 'field') {
+       facet_field.type('range');
+     } else if (facet_field.type() == 'range') {
+       facet_field.type('range-up')
+     } else if (facet_field.type() == 'range-up') {
+       facet_field.type('field')
      }
 
     vm.search();

+ 35 - 39
desktop/libs/dashboard/src/dashboard/templates/common_search.mako

@@ -570,34 +570,6 @@ ${ dashboard.layout_skeleton(suffix='search') }
 
 <script type="text/html" id="facet-toggle2">
   <div class="pull-left margin-right-20">
-  
-  ## TODO toggle3 for nested facet probably / compat for toggle2
-  
-##   <!-- ko if: $root.isEditing -->
-##     <!-- ko if: properties.canRange() && typeof properties.type != "undefined" -->
-##     <div class="facet-field-cnt">
-##       <span class="facet-field-label facet-field-label-fixed-width">${ _('Type') }</span>
-##       <a href="javascript: void(0)" title="${ _('Toggle how to group the values') }" data-bind="click: $root.collection.toggleRangeFacet2">
-##         <i class="fa" data-bind="css: { 'fa-arrows-h': properties.type() == 'range', 'fa-circle': properties.type() == 'field', 'fa-level-up': properties.type() == 'range-up' }, attr: { title: properties.type() == 'field' ? 'Range' : properties.type() == 'range-up' ? 'Range and up' : 'Term' }"></i>
-##         <span data-bind="visible: properties.type() == 'range'">${_('range')}</span>
-##         <span data-bind="visible: properties.type() == 'range-up'">${_('range & up')}</span>
-##         <span data-bind="visible: properties.type() == 'field'">${_('field')}</span>
-##       </a>
-##     </div>
-##     <!-- /ko -->
-##  
-##     <!-- ko if: type() == 'range' || type() == 'range-up' || (type() == 'nested' && typeof properties.min != "undefined") -->
-##       <!-- ko ifnot: properties.isDate() -->
-##         <div class="slider-cnt" data-bind="slider: {start: properties.min, end: properties.max, gap: properties.initial_gap, min: properties.initial_start, max: properties.initial_end, properties: properties, labels: SLIDER_LABELS}"></div>
-##       <!-- /ko -->
-##       <!-- ko if: properties.isDate() && $root.collection.timeFilter && $root.collection.timeFilter.field && $root.collection.timeFilter.field() != field() -->
-##         <div data-bind="daterangepicker: {start: properties.start, end: properties.end, gap: properties.initial_gap, relatedgap: properties.gap, min: properties.min, max: properties.max}"></div>
-##       <!-- /ko -->
-##     <!-- /ko -->
-
-
-##   <!-- /ko -->
-##   </div>
 
   <!-- ko if: $root.isEditing -->
 
@@ -1282,6 +1254,7 @@ ${ dashboard.layout_skeleton(suffix='search') }
     <!-- ko with: $root.collection.getFacetById($parent.id()) -->
     <div style="margin-bottom: 20px">
       <span data-bind="template: { name: 'facet-toggle2' }"></span>
+      <div class="clearfix"></div>
     </div>
 
     <div style="padding-bottom: 10px; text-align: right; padding-right: 20px">
@@ -1861,6 +1834,7 @@ ${ dashboard.layout_skeleton(suffix='search') }
     <!-- ko with: $root.collection.getFacetById($parent.id()) -->
     <div style="margin-bottom: 20px">
       <span data-bind="template: { name: 'facet-toggle2' }"></span>
+      <div class="clearfix"></div>
     </div>
 
     <span data-bind="template: { name: 'data-grid' }"></span>
@@ -2060,14 +2034,12 @@ ${ dashboard.layout_skeleton(suffix='search') }
 
 
 <script type="text/html" id="metric-form">
-  ## Facet measure has a slightly different format
-  <!-- ko with: typeof properties != "undefined" ? properties.aggregate : aggregate -->
 
     <!-- ko if: $root.isEditing -->
+
     <div>
-      ##<!-- ko if: $data.function() != 'field' -->
-        <select data-bind="options: metrics, optionsText: 'label', optionsValue: 'value', value: $data.function, disable: ($parents[1].widgetType() == 'text-facet-widget' && $index() == 0)" class="input-small"></select>
-      ##<!-- /ko -->
+          <!-- ko with: aggregate -->
+      <select data-bind="options: metrics, optionsText: 'label', optionsValue: 'value', value: $data.function, disable: ($parents[1].widgetType() == 'text-facet-widget' && $index() == 0 && $parent.type)" class="input-small"></select>
 
       <!-- ko if: $data.function() == 'percentile' -->
         <!-- ko foreach: percentiles() -->
@@ -2089,6 +2061,8 @@ ${ dashboard.layout_skeleton(suffix='search') }
       <input data-bind="value: formula, visible: $parent.field() == 'formula', valueUpdate: 'afterkeydown'"></input>
       <input data-bind="value: plain_formula" type="hidden"></input>
 
+
+
       <!-- ko if: $data.function() != 'field' && $parents[1].widgetType() != 'hit-widget' -->
       <div class="facet-field-cnt">
         <span class="facet-field-label facet-field-label-fixed-width">${ _('Sorting') }</span>
@@ -2100,7 +2074,7 @@ ${ dashboard.layout_skeleton(suffix='search') }
         </a>
       </div>
 
-        <div class="facet-field-cnt" data-bind="visible: $data.function() == 'count'">
+        <div class="facet-field-cnt" data-bind="visible: $data.function() == 'count' && !$parent.canRange()">
           <span class="spinedit-cnt">
             <span class="facet-field-label">
               ${ _('Limit') }
@@ -2118,19 +2092,41 @@ ${ dashboard.layout_skeleton(suffix='search') }
           </span>
         </div>
       <!-- /ko -->
+        <!-- /ko -->
+        
+
+    <!-- ko if: canRange() -->
+    <div class="facet-field-cnt">
+      <span class="facet-field-label facet-field-label-fixed-width">${ _('Type') }</span>
+      <a href="javascript: void(0)" title="${ _('Toggle how to group the values') }" data-bind="click: $root.collection.toggleRangeFacet2">
+        <i class="fa" data-bind="css: { 'fa-arrows-h': type() == 'range', 'fa-circle': type() == 'field', 'fa-level-up': type() == 'range-up' }, attr: { title: type() == 'field' ? 'Range' : type() == 'range-up' ? 'Range and up' : 'Term' }"></i>
+        <span data-bind="visible: type() == 'range'">${_('range')}</span>
+        <span data-bind="visible: type() == 'range-up'">${_('range & up')}</span>
+        <span data-bind="visible: type() == 'field'">${_('field')}</span>
+      </a>
+    </div>
+  
+      <!-- ko ifnot: isDate() -->
+        <div class="slider-cnt" data-bind="slider: {start: min, end: max, gap: initial_gap, min: initial_start, max: initial_end, properties: $data, labels: SLIDER_LABELS}"></div>
+      <!-- /ko -->
+      <!-- ko if: isDate() && $root.collection.timeFilter && $root.collection.timeFilter.field && $root.collection.timeFilter.field() != field() -->
+        <div data-bind="daterangepicker: {start: start, end: end, gap: initial_gap, relatedgap: gap, min: min, max: max}"></div>
+      <!-- /ko -->
+        <!-- /ko -->
     </div>
-    <!-- /ko -->
+
+    <!-- /ko -->  
 
     <!-- ko if: !$root.isEditing() -->
     <div class="content" style="border: 1px solid #d8d8d8;">
-      <div data-bind="text: getPrettyMetric($data)" class="muted"></div>
-      <!-- ko if: $data.function() != 'field' && $data.metrics -->
-      <i class="fa" data-bind="css: { 'fa-long-arrow-down': $parent.sort() == 'desc', 'fa-long-arrow-up': $parent.sort() == 'asc' }"></i>
+      <div data-bind="text: getPrettyMetric(aggregate)" class="muted"></div>
+      <!-- ko if: aggregate.function() != 'field' && aggregate.metrics -->
+      <i class="fa" data-bind="css: { 'fa-long-arrow-down': sort() == 'desc', 'fa-long-arrow-up': sort() == 'asc' }"></i>
       <!-- /ko -->
     </div>
     <!-- /ko -->
 
-  <!-- /ko -->
+
 </script>
 
 

+ 24 - 11
desktop/libs/libsolr/src/libsolr/api.py

@@ -158,12 +158,7 @@ class SolrApi(object):
 #               'sort': sort,
 #           }
 # 
-#           if facet['properties']['domain'].get('blockParent') or facet['properties']['domain'].get('blockChildren'):
-#             _f['domain'] = {}
-#             if facet['properties']['domain'].get('blockParent'):
-#               _f['domain']['blockParent'] = ' OR '.join(facet['properties']['domain']['blockParent'])
-#             if facet['properties']['domain'].get('blockChildren'):
-#               _f['domain']['blockChildren'] = ' OR '.join(facet['properties']['domain']['blockChildren'])
+
 # 
 #           if 'start' in facet['properties'] and not facet['properties'].get('type') == 'field':
 #             _f.update({
@@ -189,7 +184,7 @@ class SolrApi(object):
 
           _f = {}
           if facet['properties']['facets']:
-            self._n_facet_dimension(facet, _f, facet['properties']['facets'], 1)
+            self._n_facet_dimension(facet, _f, facet['properties']['facets'], 1, timeFilter)
             if facet['widgetType'] == 'text-facet-widget':
               _fname = _f['facet'].keys()[0]
               _f['sort'] = {_fname: facet['properties']['sort']}
@@ -277,7 +272,7 @@ class SolrApi(object):
     return self._get_json(response)
 
 
-  def _n_facet_dimension(self, widget, _f, facets, dim):
+  def _n_facet_dimension(self, widget, _f, facets, dim, timeFilter):
     facet = facets[0]
     f_name = 'dim_%02d:%s' % (dim, facet['field'])
 
@@ -307,14 +302,32 @@ class SolrApi(object):
           #'prefix': '' # Forbidden on numeric fields
       }
 
+      if 'start' in facet and not facet.get('type') == 'field':
+        _f[f_name].update({
+            'type': 'range',
+            'start': facet['start'],
+            'end': facet['end'],
+            'gap': facet['gap']
+        })
+#         if timeFilter and timeFilter['time_field'] == facet['field'] and (widget['id'] not in timeFilter['time_filter_overrides']): # or facet['widgetType'] != 'bucket-widget'):
+#           _f.update(self._get_time_filter_query(timeFilter, facet))
+
+      if facet.get('domain'):
+        if facet['domain'].get('blockParent') or facet['domain'].get('blockChildren'):
+          _f['domain'] = {}
+          if facet['domain'].get('blockParent'):
+            _f['domain']['blockParent'] = ' OR '.join(facet['domain']['blockParent'])
+          if facet['domain'].get('blockChildren'):
+            _f['domain']['blockChildren'] = ' OR '.join(facet['domain']['blockChildren'])
+
       if widget['widgetType'] == 'tree2-widget' and facets[-1]['aggregate']['function'] != 'count':
         _f['subcount'] = self._get_aggregate_function(facets[-1])
 
       if len(facets) > 1: # Get n+1 dimension
         if facets[1]['aggregate']['function'] == 'count':
-          self._n_facet_dimension(widget, _f[f_name], facets[1:], dim + 1)
+          self._n_facet_dimension(widget, _f[f_name], facets[1:], dim + 1, timeFilter)
         else:
-          self._n_facet_dimension(widget, _f[f_name], facets[1:], dim)
+          self._n_facet_dimension(widget, _f[f_name], facets[1:], dim, timeFilter)
     else:
       agg_function = self._get_aggregate_function(facet)
       _f['facet'] = {
@@ -325,7 +338,7 @@ class SolrApi(object):
           agg_function = self._get_aggregate_function(_f_agg)
           _f['facet']['agg_%02d_%02d:%s' % (dim, i, agg_function)] = agg_function
         else:
-          self._n_facet_dimension(widget, _f, facets[i:], dim + 1) # Get n+1 dimension
+          self._n_facet_dimension(widget, _f, facets[i:], dim + 1, timeFilter) # Get n+1 dimension
           break