浏览代码

HUE-1731 [search] Support dates in graph facets

Added support for dates
Improved tooltips
Enrico Berti 12 年之前
父节点
当前提交
9fc933d
共有 2 个文件被更改,包括 81 次插入70 次删除
  1. 42 8
      apps/search/src/search/templates/search.mako
  2. 39 62
      desktop/core/static/js/jquery.blueprint.js

+ 42 - 8
apps/search/src/search/templates/search.mako

@@ -17,8 +17,10 @@
 <%!
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
+from django.utils.dateparse import parse_datetime
 import urllib
 import math
+import time
 %>
 
 <%namespace name="macros" file="macros.mako" />
@@ -28,6 +30,9 @@ ${ commonheader(_('Search'), "search", user, "90px") | n,unicode }
 <link rel="stylesheet" href="/search/static/css/search.css">
 <script src="/static/ext/js/moment.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/search/static/js/search.utils.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/jquery/plugins/jquery.flot.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/jquery/plugins/jquery.flot.selection.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/static/ext/js/jquery/plugins/jquery.flot.time.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/js/jquery.blueprint.js" type="text/javascript" charset="utf-8"></script>
 
 <%
@@ -92,6 +97,7 @@ ${ commonheader(_('Search'), "search", user, "90px") | n,unicode }
     </div>
     %else:
     % if response and 'response' in response and 'docs' in response['response'] and len(response['response']['docs']) > 0 and 'normalized_facets' in response:
+      <% shown_facets = 0 %>
     <div class="span2 results">
       <ul class="facet-list">
         ## Force chart facets first
@@ -106,6 +112,7 @@ ${ commonheader(_('Search'), "search", user, "90px") | n,unicode }
                 remove_list.remove(fq)
             %>
             %if found_value != "":
+              <% shown_facets += 1 %>
               <li class="nav-header">${fld['label']}</li>
               <li><strong>${ found_value }</strong> <a href="?collection=${ current_collection }&query=${ solr_query['q'] }&fq=${'|'.join(remove_list)}${solr_query.get("sort") and '&sort=' + solr_query.get("sort") or ''}"><i class="fa fa-times"></i></a></li>
             %endif
@@ -113,6 +120,7 @@ ${ commonheader(_('Search'), "search", user, "90px") | n,unicode }
         % endfor
         % for fld in response['normalized_facets']:
           % if fld['type'] != 'chart':
+            <% shown_facets += 1 %>
             % if fld['type'] == 'date':
               <li class="nav-header facetHeader dateFacetHeader">${fld['label']}</li>
             % else:
@@ -158,7 +166,7 @@ ${ commonheader(_('Search'), "search", user, "90px") | n,unicode }
     % endif
 
     % if response and 'response' in response and 'docs' in response['response'] and len(response['response']['docs']) > 0:
-      % if response['normalized_facets']:
+      % if response['normalized_facets'] and shown_facets > 0:
       <div class="span10 results">
       % else:
       <div class="span12 results">
@@ -188,7 +196,14 @@ ${ commonheader(_('Search'), "search", user, "90px") | n,unicode }
             for group, count in macros.pairwise(fld['counts']):
               values += "['" + group + "'," + str(count) + "],"
           %>
-          <div class="chartComponent" data-values="[${values[:-1]}]" data-label="${fld['label']}" data-field="${fld['field']}"></div>
+          <div class="chartComponent" data-values="[${values[:-1]}]" data-label="${fld['label']}" data-field="${fld['field']}">
+            <!--[if lte IE 9]>
+              <img src="/static/art/spinner-big.gif" />
+            <![endif]-->
+            <!--[if !IE]> -->
+              <i class="fa fa-spinner fa-spin" style="font-size: 24px; color: #DDD"></i>
+            <!-- <![endif]-->
+          </div>
         %endif
       % endfor
 
@@ -489,33 +504,52 @@ ${ commonheader(_('Search'), "search", user, "90px") | n,unicode }
       }
     }
 
-    var _chartData = eval($(".chartComponent").data("values"));
+    var _chartData = null;
+
+    if ($(".chartComponent").length > 0){
+      _chartData = eval($(".chartComponent").data("values"));
+    }
 
     // test the content of _chartData to see if it can be rendered as chart
-    if (_chartData.length > 0) {
+    if (_chartData != null && _chartData.length > 0) {
       if ($.isArray(_chartData[0])) {
-        if ($.isNumeric(_chartData[0][0])) {
+        if ($.isNumeric(_chartData[0][0]) || _chartData[0][0].match(/[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]T/)) {
+          var _isDate = false;
+          if (_chartData[0][0].match(/[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]T/) != null){
+            _isDate = true;
+          }
           $(".chartComponent").jHueBlueprint({
             data: _chartData,
             label: $(".chartComponent").data("label"),
             type: $.jHueBlueprint.TYPES.BARCHART,
             color: $.jHueBlueprint.COLORS.BLUE,
+            isDateTime: _isDate,
             fill: true,
             enableSelection: true,
             height: 100,
             onSelect: function (range) {
-              location.href = '?collection=${ current_collection }&query=${ solr_query['q'] }&fq=' + getFq("${ solr_query['fq'] }", $(".chartComponent").data("field"), ':["' + Math.floor(range.xaxis.from) + '" TO "' + Math.ceil(range.xaxis.to) + '"]') + '${solr_query.get("sort") and '&sort=' + solr_query.get("sort") or ''}';
+              var _start = Math.floor(range.xaxis.from)
+              var _end = Math.ceil(range.xaxis.to);
+              if (_isDate){
+                _start = moment(range.xaxis.from).utc().format("YYYY-MM-DD[T]HH:mm:ss[Z]");
+                _end = moment(range.xaxis.to).utc().format("YYYY-MM-DD[T]HH:mm:ss[Z]");
+              }
+              location.href = '?collection=${ current_collection }&query=${ solr_query['q'] }&fq=' + getFq("${ solr_query['fq'] }", $(".chartComponent").data("field"), ':["' + _start + '" TO "' + _end + '"]') + '${solr_query.get("sort") and '&sort=' + solr_query.get("sort") or ''}';
             },
             onItemClick: function (pos, item) {
               if (item) {
                 $(".chartComponent").data("plotObj").highlight(item.series, item.datapoint);
-                location.href = '?collection=${ current_collection }&query=${ solr_query['q'] }&fq=' + getFq("${ solr_query['fq'] }", $(".chartComponent").data("field"), ':' + item.datapoint[0]) + '${solr_query.get("sort") and '&sort=' + solr_query.get("sort") or ''}';
+                var _point = item.datapoint[0];
+                if (_isDate){
+                  _point = '"' + moment(item.datapoint[0]).utc().format("YYYY-MM-DD[T]HH:mm:ss[Z]") + '"';
+                }
+                location.href = '?collection=${ current_collection }&query=${ solr_query['q'] }&fq=' + getFq("${ solr_query['fq'] }", $(".chartComponent").data("field"), ':' + _point) + '${solr_query.get("sort") and '&sort=' + solr_query.get("sort") or ''}';
               }
             }
           });
         }
         else {
-          $(".chartComponent").addClass("alert").text("${_('The graphical facets works just with numbers. Please choose another field.')}")
+          $(".chartComponent").addClass("alert").text("${_('The graphical facets works just with numbers or dates. Please choose another field.')}")
         }
       }
       else {

+ 39 - 62
desktop/core/static/js/jquery.blueprint.js

@@ -18,29 +18,6 @@
  * it's a layer of abstraction on top of other chart/drawing/mapping plugins
  */
 
-jQuery.cachedScripts = {};
-
-jQuery.cacheScript = function (url, callback) {
-  if (jQuery.cachedScripts != null && jQuery.cachedScripts[url] != null) {
-    callback(jQuery.cachedScripts[url]);
-  }
-  else {
-    var options = $.extend({}, {
-      dataType: "script",
-      cache: true,
-      url: url,
-      async: false,
-      complete: function (script) {
-        jQuery.cachedScripts[url] = script;
-        callback(script);
-      }
-    });
-    return jQuery.ajax(options);
-  }
-};
-
-var FLOT_LOADED, FLOT_PIE_LOADED = false;
-
 (function ($, window, document, undefined) {
   var pluginName = "jHueBlueprint",
       COLORS = {
@@ -64,6 +41,7 @@ var FLOT_LOADED, FLOT_PIE_LOADED = false;
         borderWidth: 0,
         tooltips: true,
         enableSelection: false,
+        isDateTime: false,
         onSelect: function () {
         },
         onItemClick: function () {
@@ -80,25 +58,12 @@ var FLOT_LOADED, FLOT_PIE_LOADED = false;
 
   Plugin.prototype.init = function () {
     var _this = this;
-    $.cacheScript("/static/ext/js/jquery/plugins/jquery.flot.min.js", function (script, textStatus) {
-      FLOT_LOADED = true;
-      if (_this.options.type == TYPES.PIECHART) {
-        $.cacheScript("/static/ext/js/jquery/plugins/jquery.flot.pie.min.js", function (script, textStatus) {
-          FLOT_PIE_LOADED = true;
-          flot_pie(_this);
-        });
-      }
-      else {
-        if (_this.options.enableSelection) {
-          $.cacheScript("/static/ext/js/jquery/plugins/jquery.flot.selection.min.js", function (script, textStatus) {
-            flot(_this);
-          });
-        }
-        else {
-          flot(_this);
-        }
-      }
-    });
+    if (_this.options.type == TYPES.PIECHART) {
+      flot_pie(_this);
+    }
+    else {
+      flot(_this);
+    }
   };
 
   Plugin.prototype.setOptions = function (options) {
@@ -106,24 +71,17 @@ var FLOT_LOADED, FLOT_PIE_LOADED = false;
   };
 
   function addSerie(element, serie) {
-    if (!FLOT_LOADED) {
-      window.setTimeout(function () {
-        addSerie(element, serie);
-      }, 500)
+    var _series = $(element).data("plotSeries");
+    if (_series == null) {
+      if (typeof console != "undefined") {
+        console.warn("$(elem).jHueBlueprint('add', options) requires an existing data serie to work. Use $(elem).jHueBlueprint(options) instead.");
+      }
     }
     else {
-      var _series = $(element).data("plotSeries");
-      if (_series == null) {
-        if (typeof console != "undefined") {
-          console.warn("$(elem).jHueBlueprint('add', options) requires an existing data serie to work. Use $(elem).jHueBlueprint(options) instead.");
-        }
-      }
-      else {
-        _series.push(getSerie(serie));
-        var _plot = $.plot(element, _series, { grid: { borderWidth: element.data('plugin_' + pluginName).options.borderWidth } });
-        $(element).data("plotObj", _plot);
-        $(element).data("plotSeries", _series);
-      }
+      _series.push(getSerie(serie));
+      var _plot = $.plot(element, _series, { grid: { borderWidth: element.data('plugin_' + pluginName).options.borderWidth } });
+      $(element).data("plotObj", _plot);
+      $(element).data("plotSeries", _series);
     }
   };
 
@@ -154,6 +112,11 @@ var FLOT_LOADED, FLOT_PIE_LOADED = false;
         color: COLORS.GREEN
       }
     }
+    if (_this.options.isDateTime) {
+      _options.xaxis = {
+        mode: "time"
+      }
+    }
     var _plot = $.plot(_this.element, [_serie], _options);
     $(_this.element).bind("plotselected", function (event, ranges) {
       _this.options.onSelect(ranges);
@@ -169,10 +132,14 @@ var FLOT_LOADED, FLOT_PIE_LOADED = false;
             previousPoint = item.dataIndex;
 
             $("#jHueBlueprintTooltip").remove();
-            var x = item.datapoint[0].toFixed(2),
-                y = item.datapoint[1].toFixed(2);
+            var x = item.datapoint[0],
+                y = item.datapoint[1];
 
-            showTooltip(item.pageX, item.pageY, x);
+            if (_this.options.isDateTime && typeof moment != "undefined"){
+              x = moment(x).utc().format("YYYY-MM-DD[T]HH:mm:ss[Z]");
+            }
+
+            showTooltip(item.pageX, item.pageY, "X: "+x+", Y: "+y);
           }
         } else {
           $("#jHueBlueprintTooltip").remove();
@@ -210,8 +177,18 @@ var FLOT_LOADED, FLOT_PIE_LOADED = false;
 
 
   function getSerie(options) {
+    var _chartData = options.data;
+    if (options.isDateTime){
+      var _newChartData = [];
+      for (var i=0;i<_chartData.length;i++){
+        var _tuple = _chartData[i];
+        _tuple[0] = moment(_tuple[0]).unix()*1000;
+        _newChartData.push(_tuple)
+        }
+      _chartData = _newChartData;
+    }
     var _flotSerie = {
-      data: options.data,
+      data: _chartData,
       label: options.label
     }