Browse Source

[search] Split widgets into Tree and Heatmap

Do not show more than one dimension for heatmap
Romain Rigaux 11 năm trước cách đây
mục cha
commit
a40d6d9

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

@@ -165,24 +165,33 @@ ${ commonheader(_('Search'), "search", user, "80px") | n,unicode }
                        <i class="hcha hcha-line-chart"></i>
          </a>
     </div>
-    <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableHistogram() },
-                    draggable: {data: draggableHistogram(), isEnabled: availableDraggableHistogram,
+    <div data-bind="css: { 'draggable-widget': true, 'disabled': false },
+                    draggable: {data: draggableTree(), 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="${_('Timeline')}" rel="tooltip" data-placement="top">
-         <a data-bind="style: { cursor: $root.availableDraggableHistogram() ? 'move' : 'default' }">
-                       <i class="hcha hcha-timeline-chart"></i>
+         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="css: { 'draggable-widget': true, 'disabled': false },
-                    draggable: {data: draggableTree(), isEnabled: true,
+                    draggable: {data: draggableHeatmap(), 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="${_('Pivot')}" rel="tooltip" data-placement="top">
+         title="${_('Heatmap')}" rel="tooltip" data-placement="top">
          <a data-bind="style: { cursor: $root.availableDraggableChart() ? 'move' : 'default' }">
-                       <i class="fa fa-sitemap fa-rotate-270"></i>
+                       <i class="fa fa-th"></i>
          </a>
-   </div>
+    </div>
+    <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableHistogram() },
+                    draggable: {data: draggableHistogram(), isEnabled: availableDraggableHistogram,
+                    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="${_('Timeline')}" rel="tooltip" data-placement="top">
+         <a data-bind="style: { cursor: $root.availableDraggableHistogram() ? 'move' : 'default' }">
+                       <i class="hcha hcha-timeline-chart"></i>
+         </a>
+    </div>
     <div data-bind="css: { 'draggable-widget': true, 'disabled': !availableDraggableChart() },
                     draggable: {data: draggableMap(), isEnabled: availableDraggableChart,
                     options: {'start': function(event, ui){lastWindowScrollPosition = $(window).scrollTop();$('.card-body').slideUp('fast');},
@@ -255,21 +264,9 @@ ${ dashboard.layout_skeleton() }
         </span>
       </div>
 
-      <div class="facet-field-cnt">
-        <span class="spinedit-cnt">
-          <span class="facet-field-label facet-field-label-fixed-width">
-            ${ _('Plot') }
-          </span>
-          <select data-bind="selectedOptions: properties.scope" class="input-small">
-            <option value="stack">${ _("Bars") }</option>
-            <option value="tree">${ _("Tree") }</option>
-          </select>
-        </span>
-      </div>
-
       <br/>
 
-      <div class="facet-field-tile">
+      <div class="facet-field-tile" data-bind="visible: properties.scope() == 'tree' || properties.facets().length == 0">
         <div class="facet-field-cnt">
           <span class="facet-field-label facet-field-label-fixed-width facet-field-label-fixed-width-double facet-field-label-title">${ _('Add a dimension') }</span>
         </div>
@@ -886,6 +883,56 @@ ${ dashboard.layout_skeleton() }
         />
       <!-- /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]-->
+  </div>
+</script>
+
+
+<script type="text/html" id="heatmap-widget">
+  <!-- ko if: $root.getFacetFromQuery(id()) -->
+  <div class="row-fluid" data-bind="with: $root.getFacetFromQuery(id())">
+    <div data-bind="visible: $root.isEditing, with: $root.collection.getFacetById($parent.id())" style="margin-bottom: 20px">
+      <span data-bind="template: { name: 'facet-toggle', afterRender: function(){ $root.getWidgetById($parent.id).isLoading(false); } }">
+      </span>
+    </div>
+
+    <div data-bind="with: $root.collection.getFacetById($parent.id())">
+      <div data-bind="foreach: $data.properties.facets, visible: $root.isEditing">
+        <div class="facet-field-tile">
+          <div class="facet-field-cnt">
+            <span class="facet-field-label facet-field-label-fixed-width facet-field-label-fixed-width-double facet-field-label-title" data-bind="text: field"></span>
+          </div>
+
+          <div class="facet-field-cnt">
+            <span class="spinedit-cnt">
+              <span class="facet-field-label facet-field-label-fixed-width">
+                ${ _('Limit') }
+              </span>
+              <input type="text" class="input-medium" data-bind="spinedit: limit"/>
+            </span>
+          </div>
+
+          <div class="facet-field-cnt">
+            <span class="spinedit-cnt">
+              <span class="facet-field-label facet-field-label-fixed-width">
+                ${ _('Min Count') }
+              </span>
+              <input type="text" class="input-medium" data-bind="spinedit: mincount"/>
+              <a href="javascript: void(0)" data-bind="click: function() { $root.collection.removePivotFacetValue({'pivot_facet': $parent, 'value': $data}); }">
+                <i class="fa fa-minus"></i>
+              </a>
+            </span>
+          </div>
+        </div>
+      </div>
+      <div class="clearfix"></div>
+
       <!-- ko if: properties.scope() == 'stack' -->
         <div data-bind="barChart: {datum: {counts: $parent.count, widget_id: id(), label: $parent.label}, stacked: true,
           isPivot: true,

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

@@ -451,7 +451,7 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
     'andUp': False,  # Not used yet
   }
 
-  if widget_type == 'tree-widget':
+  if widget_type in ('tree-widget', 'heatmap-widget'):
     facet_type = 'pivot'
   else:
     solr_api = SolrApi(SOLR_URL.get(), user)
@@ -469,11 +469,11 @@ def _create_facet(collection, user, facet_id, facet_label, facet_field, widget_t
     properties['scope'] = 'world'
     properties['mincount'] = 1
     properties['limit'] = 100
-  elif widget_type == 'tree-widget':
+  elif widget_type in ('tree-widget', 'heatmap-widget'):
     properties['mincount'] = 1
     properties['facets'] = []
     properties['facets_form'] = {'field': '', 'mincount': 1, 'limit': 5}
-    properties['scope'] = 'stack'
+    properties['scope'] = 'stack' if widget_type == 'heatmap-widget' else 'tree'
 
   return {
     'id': facet_id,

+ 9 - 8
apps/search/static/js/search.ko.js

@@ -120,7 +120,7 @@ var Query = function (vm, query) {
     } else {
       $.each(self.fqs(), function (index, fq) {
         if (fq.id() == data.widget_id) {
-          var f = $.grep(fq.filter(), function(f) { return f.value() == data.facet.value; }); 
+          var f = $.grep(fq.filter(), function(f) { return f.value() == data.facet.value; });
           if (f.length > 0) {
             fq.filter.remove(f[0]);
             if (fq.filter().length == 0) {
@@ -135,13 +135,13 @@ var Query = function (vm, query) {
 
     vm.search();
   }
-  
-  self.togglePivotFacet = function (data) {
-    data.facet.cat = data.facet.fq_fields; 
+
+  self.togglePivotFacet = function (data) { alert(ko.mapping.toJSON(data));
+    data.facet.cat = data.facet.fq_fields;
     data.facet.value = data.facet.fq_values;
     self.toggleFacet(data);
   }
-  
+
   function _toggleSingleTermFacet(data, exclude) {
     var fq = getFilterByField(data.val.cat);
     var id;
@@ -152,7 +152,7 @@ var Query = function (vm, query) {
     }
     self.toggleFacet({'widget_id': id, 'facet': {'cat': data.val.cat, 'value': data.val.value}, 'exclude': exclude});
     vm.search();
-  }  
+  }
   self.addSingleTermFacet = function(data) {
     _toggleSingleTermFacet(data, false);
   }
@@ -197,7 +197,7 @@ var Query = function (vm, query) {
       vm.search();
     }
   };
-  
+
   function getFilterByField(field) {
     var _fq = null;
     $.each(self.fqs(), function (index, fq) {
@@ -590,7 +590,7 @@ var Collection = function (vm, collection) {
     else if (self.template.fieldsModalType() == 'line-widget') {
       return vm.availableNumberFields();
     }
-    else if (self.template.fieldsModalType() == 'tree-widget') {
+    else if (self.template.fieldsModalType() == 'tree-widget' || self.template.fieldsModalType() == 'heatmap-widget') {
       return vm.availablePivotFields();
     }
     else {
@@ -956,6 +956,7 @@ var SearchViewModel = function (collection_json, query_json, initial_json) {
   self.draggablePie = ko.observable(bareWidgetBuilder("Pie Chart", "pie-widget"));
   self.draggableFilter = ko.observable(bareWidgetBuilder("Filter Bar", "filter-widget"));
   self.draggableTree = ko.observable(bareWidgetBuilder("Tree", "tree-widget"));
+  self.draggableHeatmap = ko.observable(bareWidgetBuilder("Heatmap", "heatmap-widget"));
 
   self.availableDateFields = ko.computed(function() {
     return $.grep(self.collection.availableFacetFields(), function(field) { return DATE_TYPES.indexOf(field.type()) != -1; });