Преглед изворни кода

prettied up histogram hover, added line width options, fixed excessive refresh on string query

Rashid Khan пре 12 година
родитељ
комит
d685fddcbe

+ 62 - 56
panels/histogram/editor.html

@@ -1,61 +1,67 @@
-<div class="row-fluid" ng-controller='histogram'>
-  <div class="span3">
-    <form style="margin-bottom: 0px">
-      <h6>Label</h6>
-      <input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
-    </form>
+<div ng-controller='histogram'>
+  <div class="row-fluid">
+    <div class="span3">
+      <form style="margin-bottom: 0px">
+        <h6>Label</h6>
+        <input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
+      </form>
+    </div>
+    <div class="span8">
+      <form class="input-append" style="margin-bottom: 0px">
+        <h6>Query</h6>
+        <input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
+        <button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery=''"><i class="icon-plus"></i></button>
+      </form>
+    </div>
+    <div class="span1">
+    </div>
   </div>
-  <div class="span8">
-    <form class="input-append" style="margin-bottom: 0px">
-      <h6>Query</h6>
-      <input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
-      <button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery=''"><i class="icon-plus"></i></button>
-    </form>
+  <div class="row-fluid" ng-repeat="q in panel.query">        
+    <div class="span3">
+      <form style="margin-bottom: 0px">
+        <input type="text" style="width:70%" ng-model="q.label">
+      </form>
+    </div>
+    <div class="span8">
+      <form class="input-append" style="margin-bottom: 0px">
+        <input type="text" style="width:80%" ng-model="q.query">
+        <button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
+      </form>
+    </div>
+    <div class="span1">
+      <i class="icon-remove pointer" ng-click="remove_query(q)"></i>
+    </div>
   </div>
-  <div class="span1">
+  <div class="row-fluid">    
+    <div class="span3">
+      <label class="small">Chart Options</label> 
+      <select ng-change="$emit('render')" multiple style="width:95%" ng-model="panel.show" ng-options="f for f in ['bars','points','stack','lines','legend','x-axis','y-axis']"></select>
+    </div>
+    <div class="span2">
+      <label class="small">Line Fill</label> 
+      <select ng-change="$emit('render')" class="input-mini" ng-model="panel.fill" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"></select>
+    </div>
+    <div class="span2">
+      <label class="small">Line Width</label> 
+      <select ng-change="$emit('render')" class="input-mini" ng-model="panel.linewidth" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10]"></select>
+    </div>
+    <div class="span3">
+      <label class="small">Time correction</label> 
+      <select ng-change="$emit('render')" ng-model="panel.timezone" class='input-small' ng-options="f for f in ['browser','utc']"></select>
+    </div>
+    <div class="span2"> 
+      <label class="small">Zoom Links</label><input type="checkbox" ng-model="panel.zoomlinks" ng-checked="panel.zoomlinks">
+    </div>
   </div>
-</div>
-<div class="row-fluid" ng-repeat="q in panel.query">        
-  <div class="span3">
-    <form style="margin-bottom: 0px">
-      <input type="text" style="width:70%" ng-model="q.label">
-    </form>
-  </div>
-  <div class="span8">
-    <form class="input-append" style="margin-bottom: 0px">
-      <input type="text" style="width:80%" ng-model="q.query">
-      <button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
-    </form>
-  </div>
-  <div class="span1">
-    <i class="icon-remove pointer" ng-click="remove_query(q)"></i>
-  </div>
-</div>
-<div class="row-fluid">    
-  <div class="span3">
-    <label class="small">Chart Options</label> 
-    <select ng-change="$emit('render')" multiple style="width:95%" ng-model="panel.show" ng-options="f for f in ['bars','points','stack','lines','legend','x-axis','y-axis']"></select>
-  </div>
-  <div class="span3">
-    <label class="small">Line Fill (1 - 10)</label> 
-    <input ng-change="$emit('render')" type="number" class="input-mini" ng-model="panel.fill">
-  </div>
-  <div class="span3">
-    <label class="small">Time correction</label> 
-    <select ng-change="$emit('render')" ng-model="panel.timezone" class='input-small' ng-options="f for f in ['browser','utc']"></select>
-  </div>
-  <div class="span2"> 
-    <label class="small">Zoom Links</label><input type="checkbox" ng-model="panel.zoomlinks" ng-checked="panel.zoomlinks">
-  </div>
-</div>
-<h5>Panel Spy</h5>
-<div class="row-fluid">
-  <div class="span2"> 
-    <label class="small">Spyable</label><input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
-  </div>
-  <div class="span9 small">
-    The panel spy shows 'behind the scenes' information about a panel. It can
-    be accessed by clicking the <i class='icon-eye-open'></i> in the top right
-    of the panel.
+  <h5>Panel Spy</h5>
+  <div class="row-fluid">
+    <div class="span2"> 
+      <label class="small">Spyable</label><input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
+    </div>
+    <div class="span9 small">
+      The panel spy shows 'behind the scenes' information about a panel. It can
+      be accessed by clicking the <i class='icon-eye-open'></i> in the top right
+      of the panel.
+    </div>
   </div>
 </div>

+ 17 - 10
panels/histogram/module.js

@@ -7,6 +7,7 @@ angular.module('kibana.histogram', [])
     interval  : secondsToHms(calculate_interval($scope.from,$scope.to,40,0)/1000),
     show      : ['bars','y-axis','x-axis','legend'],
     fill      : 3,
+    linewidth : 3,
     timezone  : 'browser', // browser, utc or a standard timezone
     spyable   : true,
     zoomlinks : true,
@@ -148,7 +149,6 @@ angular.module('kibana.histogram', [])
           i++;
         });
 
-        eventBus.broadcast($scope.$id,$scope.panel.group,'hits',$scope.hits)
         $scope.$emit('render')
         if(_segment < $scope.panel.index.length-1) {
           $scope.get_data(_segment+1,query_id)
@@ -236,7 +236,12 @@ angular.module('kibana.histogram', [])
               },
               series: {
                 stack:  show.stack,
-                lines:  { show: show.lines, fill: scope.panel.fill/10 },
+                lines:  { 
+                  show: show.lines, 
+                  fill: scope.panel.fill/10, 
+                  lineWidth: scope.panel.linewidth,
+                  steps: true
+                },
                 bars:   { show: show.bars,  fill: 1, barWidth: barwidth/1.8 },
                 points: { show: show.points, fill: 1, fillColor: false},
                 shadowSize: 1
@@ -294,23 +299,25 @@ angular.module('kibana.histogram', [])
         var tooltip = $('#pie-tooltip').length ? 
           $('#pie-tooltip') : $('<div id="pie-tooltip"></div>');
         //var tooltip = $('#pie-tooltip')
-        tooltip.text(contents).css({
+        tooltip.html(contents).css({
           position: 'absolute',
           top     : y + 5,
           left    : x + 5,
-          color   : "#FFF",
-          border  : '1px solid #FFF',
-          padding : '2px',
-          'font-size': '8pt',
-          'background-color': '#000',
+          color   : "#000",
+          border  : '3px solid #000',
+          padding : '10px',
+          'font-size': '11pt',
+          'font-weight' : 'bold',
+          'background-color': '#FFF',
+          'border-radius': '10px',
         }).appendTo("body");
       }
 
       elem.bind("plothover", function (event, pos, item) {
         if (item) {
-          var percent = parseFloat(item.series.percent).toFixed(1) + "%";
           tt(pos.pageX, pos.pageY,
-            item.datapoint[1].toFixed(1) + " @ " + 
+            "<div style='vertical-align:middle;display:inline-block;background:"+item.series.color+";height:20px;width:20px'></div> "+
+            item.datapoint[1].toFixed(0) + " @ " + 
             new Date(item.datapoint[0]).format('mm/dd HH:MM:ss'));
         } else {
           $("#pie-tooltip").remove();

+ 38 - 15
panels/hits/editor.html

@@ -1,23 +1,46 @@
-  <div class="row-fluid" ng-controller="hits">
-    <div class="span2"> 
-      <label class="small">Run Query</label><input type="checkbox" ng-model="panel.run_query" ng-checked="panel.run_query">
+<div ng-controller="hits">
+  <div class="row-fluid">
+    <div class="span3"><h6>Font Size</h6> 
+      <select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['7pt','8pt','9pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
     </div>
-    <div class="span9" ng-show='!panel.run_query'>
-      With query running disabled, this panel receives its hit count from a histogram panel. If multiple queries are running this <strong>will show the total of all queries</strong>.
+    <div class="span2"> 
+      <label class="small">Aggregate Queries</label><input type="checkbox" ng-model="panel.aggregate" ng-checked="panel.aggregate">
     </div>
-    <div class="span9" ng-show='panel.run_query'>
-      This shows a simple count of how many records match your filtered query. If multiple queries are sent from a single panel the <strong>first query will be displayed</strong>
+    <div class="span3" ng-show="!panel.aggregate"><h6>Arrangement</h6> 
+      <select class="input-medium" ng-model="panel.arrangement" ng-options="f for f in ['horizontal','vertical']"></select></span>
     </div>
   </div>
-
-  <div class="row-fluid">    
-    <div class="span9" ng-show='panel.run_query'>
-      <form class="input-append">
+  <div class="row-fluid">
+    <div class="span3">
+      <form style="margin-bottom: 0px">
+        <h6>Label</h6>
+        <input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
+      </form>
+    </div>
+    <div class="span8">
+      <form class="input-append" style="margin-bottom: 0px">
         <h6>Query</h6>
-        <input type="text" style="width:85%" ng-model="panel.query">
-        <button class="btn" ng-click="get_data();"><i class="icon-search"></i></button>
+        <input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
+        <button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery=''"><i class="icon-plus"></i></button>
       </form>
     </div>
-    <div class="span3"><h6>Font Size</h6> 
-      <select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
+    <div class="span1">
+    </div>
+  </div>
+  <div class="row-fluid" ng-repeat="q in panel.query">        
+    <div class="span3">
+      <form style="margin-bottom: 0px">
+        <input type="text" style="width:70%" ng-model="q.label">
+      </form>
+    </div>
+    <div class="span8">
+      <form class="input-append" style="margin-bottom: 0px">
+        <input type="text" style="width:80%" ng-model="q.query">
+        <button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
+      </form>
+    </div>
+    <div class="span1">
+      <i class="icon-remove pointer" ng-click="remove_query(q)"></i>
+    </div>
   </div>
+</div>

+ 9 - 1
panels/hits/module.html

@@ -1,3 +1,11 @@
 <kibana-panel ng-controller='hits' ng-init="init()">
-  <p ng-style="panel.style">&#8805 {{hits}}</p>
+  <p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p>
+  <table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'">  
+    <tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in data">
+      <td style="padding-right:10px">{{query.label}}</td><td>{{query.hits}}</td>
+    </tr>
+  </table>
+  <div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in data" style="float:left; padding-left: 10px">
+    {{query.label}} {{query.hits}} <span ng-show="!$last">|</span>
+  </div>
 </kibana-panel>         

+ 79 - 25
panels/hits/module.js

@@ -5,60 +5,114 @@ angular.module('kibana.hits', [])
   var _d = {
     query   : "*",
     group   : "default",
-    style   : { "font-size": '36pt', "font-weight": "bold" },
-    run_query : false
+    style   : { "font-size": '36pt'},
+    aggregate   : true,
+    arrangement : 'vertical'
   }
   _.defaults($scope.panel,_d)
 
   $scope.init = function () {
     $scope.hits = 0;
     eventBus.register($scope,'time', function(event,time){
-      if($scope.panel.run_query)
-        set_time(time)
+      set_time(time)
     });
     eventBus.register($scope,'query', function(event, query) {
-      $scope.panel.query = _.isArray(query) ? query[0] : query;
-      if($scope.panel.run_query)
-        $scope.get_data();
+      $scope.panel.query = _.map(query,function(q) {
+        return {query: q, label: q};
+      })
+      $scope.get_data();
     });
-    eventBus.register($scope,'hits', function(event, hits) {
-      $scope.hits = hits;
-    })
     // Now that we're all setup, request the time from our group
     eventBus.broadcast($scope.$id,$scope.panel.group,'get_time')
   }
 
-  $scope.get_data = function() {
+  $scope.get_data = function(segment,query_id) {
+    delete $scope.panel.error
+    $scope.panel.loading = true;
+
     // Make sure we have everything for the request to complete
     if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time))
       return
 
-    $scope.panel.loading = true;
-    var request = $scope.ejs.Request().indices($scope.panel.index);
-
-    var results = request
-      .query(ejs.FilteredQuery(
-        ejs.QueryStringQuery($scope.panel.query || '*'),
+    var _segment = _.isUndefined(segment) ? 0 : segment
+    var request = $scope.ejs.Request().indices($scope.panel.index[_segment]);
+    
+    // Build the question part of the query
+    var queries = [];
+    _.each($scope.panel.query, function(v) {
+      queries.push($scope.ejs.FilteredQuery(
+        ejs.QueryStringQuery(v.query || '*'),
         ejs.RangeFilter($scope.time.field)
           .from($scope.time.from)
-          .to($scope.time.to)
-        )
+          .to($scope.time.to))
       )
-      .size(0)
-      .doSearch();
+    });
+
+    // Build the facet part
+    _.each(queries, function(v) {
+      request = request
+        .facet($scope.ejs.QueryFacet("query"+_.indexOf(queries,v))
+          .query(v)
+        ).size(0)
+    })
+
+    // TODO: Spy for hits panel
+    //$scope.populate_modal(request);
+
+    // Then run it
+    var results = request.doSearch();
 
     // Populate scope when we have results
     results.then(function(results) {
+
       $scope.panel.loading = false;
-      if(_.isUndefined(results)) {
-        $scope.panel.error = 'Your query was unsuccessful';
+      if(_segment == 0) {
+        $scope.hits = 0;
+        $scope.data = [];
+        query_id = $scope.query_id = new Date().getTime();
+      }
+      
+      // Check for error and abort if found
+      if(!(_.isUndefined(results.error))) {
+        $scope.panel.error = $scope.parse_error(results.error);
         return;
       }
-      $scope.panel.error =  false;
-      $scope.hits = results.hits.total;
+      if($scope.query_id === query_id) {
+        var i = 0;
+        _.each(results.facets, function(v, k) {
+          var hits = _.isUndefined($scope.data[i]) || _segment == 0 ? 
+            v.count : $scope.data[i].hits+v.count
+          $scope.hits += v.count
+
+          // Create series
+          $scope.data[i] = { 
+            label: $scope.panel.query[i].label || "query"+(parseInt(i)+1), 
+            hits: hits
+          };
+
+          i++;
+        });
+
+        if(_segment < $scope.panel.index.length-1) 
+          $scope.get_data(_segment+1,query_id)
+      
+      }
     });
   }
 
+  $scope.remove_query = function(q) {
+    $scope.panel.query = _.without($scope.panel.query,q);
+    $scope.get_data();
+  }
+
+  $scope.add_query = function(label,query) {
+    $scope.panel.query.unshift({
+      query: query,
+      label: label, 
+    });
+    $scope.get_data();
+  }
+
   function set_time(time) {
     $scope.time = time;
     $scope.panel.index = _.isUndefined(time.index) ? $scope.panel.index : time.index

+ 1 - 1
panels/stringquery/module.html

@@ -31,7 +31,7 @@
         </span>
       </form>
       <button type="submit" class="btn btn-info" ng-click="send_query(panel.query)"><i class="icon-search"></i> Search</button>
-      <button type="submit" class="btn" ng-click="send_query(panel.query);add_query();"><i class="icon-plus"></i> Add Query</button>
+      <button type="submit" class="btn" ng-click="add_query();"><i class="icon-plus"></i> Add Query</button>
   </div>
   <div ng-show="panel.multi && panel.multi_arrange == 'vertical'">
     <form>