Просмотр исходного кода

Fixed pie legend display bug in chrome, lots of cleanup

Rashid Khan 12 лет назад
Родитель
Сommit
c407da007c

+ 24 - 3
panels/hits/editor.html

@@ -6,13 +6,34 @@
     <div class="span2"> 
     <div class="span2"> 
       <label class="small">Aggregate</label><input type="checkbox" ng-model="panel.aggregate" ng-checked="panel.aggregate">
       <label class="small">Aggregate</label><input type="checkbox" ng-model="panel.aggregate" ng-checked="panel.aggregate">
     </div>
     </div>
-    <div class="span3" ng-show="!panel.aggregate"><label class="small">Counter Style</label> 
+    <div class="span3" ng-show="!panel.aggregate">
+      <label class="small">Counter Style</label> 
       <select class="input-small" ng-model="panel.arrangement" ng-options="f for f in ['none','horizontal','vertical']"></select></span>
       <select class="input-small" ng-model="panel.arrangement" ng-options="f for f in ['none','horizontal','vertical']"></select></span>
     </div>
     </div>
-    <div class="span2" ng-show="!panel.aggregate"> 
-      <label class="small">Chart</label><input type="checkbox" ng-model="panel.chart" ng-checked="panel.chart">
+    
+  </div>
+  <h5 ng-show="!panel.aggregate">Chart Options</h5>
+    <div class="row-fluid" ng-show="!panel.aggregate">
+      <div class="span3"> 
+      <label class="small">Style</label> 
+      <select class="input-small" ng-model="panel.chart" ng-options="f for f in ['none','bar','pie']"></select></span>
+    </div>
+    <div class="row-fluid" >
+      <div class="span3" ng-show="!panel.aggregate"> 
+      <label class="small">Legend</label> 
+      <select class="input-small" ng-model="panel.counter_pos" ng-options="f for f in ['above','below']"></select></span>
+    </div>
+    <div class="span1" ng-show='panel.chart == "pie"'>
+      <label class="small"> Donut </label><input type="checkbox" ng-model="panel.donut" ng-checked="panel.donut">
+    </div>
+    <div class="span1" ng-show='panel.chart == "pie"'>
+      <label class="small"> Tilt </label><input type="checkbox" ng-model="panel.tilt" ng-checked="panel.tilt">
+    </div>
+    <div class="span1" ng-show='panel.chart == "pie"'>
+      <label class="small"> Labels </label><input type="checkbox" ng-model="panel.labels" ng-checked="panel.labels">
     </div>
     </div>
   </div>
   </div>
+  <h5>Queries</h5>    
   <div class="row-fluid">
   <div class="row-fluid">
     <div class="span3">
     <div class="span3">
       <form style="margin-bottom: 0px">
       <form style="margin-bottom: 0px">

+ 33 - 5
panels/hits/module.html

@@ -1,14 +1,42 @@
 <kibana-panel ng-controller='hits' ng-init="init()">
 <kibana-panel ng-controller='hits' ng-init="init()">
-  <div ng-show="panel.counters">
+
+  <div ng-show="panel.counters && panel.counter_pos == 'above'">
+    <!-- no chart, aggregated numbers -->    
     <p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p>
     <p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p>
+
+    <!-- vertical legend -->
     <table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'">  
     <table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'">  
       <tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in plot.getData()">
       <tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in plot.getData()">
-        <td ng-show="panel.chart" style="background:{{query.color}};width:{{panel.style['font-size']}}"></td> <td style="padding-right:10px;padding-left:10px;">{{query.label}}</td><td>{{query.hits}}</td>
+        <td style="background:{{query.color}};width:{{panel.style['font-size']}}"></td> <td style="padding-right:10px;padding-left:10px;">{{query.label}}</td><td>{{query.data[0][1]}}</td>
       </tr>
       </tr>
     </table>
     </table>
+
+    <!-- horizontal legend -->
     <div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
     <div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
-     <span ng-show='panel.chart'><div style="display:inline-block;border-radius:{{panel.style['font-size']}};background:{{query.color}};height:{{panel.style['font-size']}};width:{{panel.style['font-size']}}"></div></span> {{query.label}} ({{query.hits}}) <span ng-show="!$last">|</span>
+     <span><div style="display:inline-block;border-radius:{{panel.style['font-size']}};background:{{query.color}};height:{{panel.style['font-size']}};width:{{panel.style['font-size']}}"></div></span> {{query.label}} ({{query.data[0][1]}}) </span>
     </div><br>
     </div><br>
-  </div><div style="clear:both"></div>
-  <div ng-show='panel.chart && !panel.aggregate ' hits-chart params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
+
+  </div>
+  <div style="clear:both"></div>
+  <div ng-show='panel.chart != "none" && !panel.aggregate ' hits-chart params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
+
+  <div ng-show="panel.counters && panel.counter_pos == 'below'">
+    <!-- no chart, aggregated numbers -->    
+    <p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p>
+
+    <!-- vertical legend -->
+    <table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'">  
+      <tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in plot.getData()">
+        <tdstyle="background:{{query.color}};width:{{panel.style['font-size']}}"></td> <td style="padding-right:10px;padding-left:10px;">{{query.label}}</td><td>{{query.data[0][1]}}</td>
+      </tr>
+    </table>
+
+    <!-- horizontal legend -->
+    <div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
+     <span><div style="display:inline-block;border-radius:{{panel.style['font-size']}};background:{{query.color}};height:{{panel.style['font-size']}};width:{{panel.style['font-size']}}"></div></span> {{query.label}} ({{query.data[0][1]}}) </span>
+    </div><br>
+
+  </div>
+
+
 </kibana-panel>         
 </kibana-panel>         

+ 60 - 26
panels/hits/module.js

@@ -8,9 +8,11 @@ angular.module('kibana.hits', [])
     style   : { "font-size": '10pt'},
     style   : { "font-size": '10pt'},
     aggregate   : true,
     aggregate   : true,
     arrangement : 'vertical',
     arrangement : 'vertical',
-    chart   : true,
-    counters: true,
-    count_pos: 'above'
+    chart       : 'none',
+    counter_pos : 'above',
+    donut   : false,
+    tilt    : false,
+    labels  : true
   }
   }
   _.defaults($scope.panel,_d)
   _.defaults($scope.panel,_d)
 
 
@@ -143,31 +145,61 @@ angular.module('kibana.hits', [])
       function render_panel() {
       function render_panel() {
 
 
         var scripts = $LAB.script("common/lib/panels/jquery.flot.js")
         var scripts = $LAB.script("common/lib/panels/jquery.flot.js")
-                    
-        // Populate element. Note that jvectormap appends, does not replace.
+                          .script("common/lib/panels/jquery.flot.pie.js")
+
+        // Populate element.
         scripts.wait(function(){
         scripts.wait(function(){
           // Populate element
           // Populate element
           try {
           try {
             // Add plot to scope so we can build out own legend 
             // Add plot to scope so we can build out own legend 
-            scope.plot = $.plot(elem, scope.data, {
-              legend: { show: false },
-              series: {
-                lines:  { show: false, },
-                bars:   { show: true,  fill: 1, barWidth: 0.8, horizontal: false },
-                shadowSize: 1
-              },
-              yaxis: { show: true, min: 0, color: "#000" },
-              xaxis: { show: false },
-              grid: {
-                backgroundColor: '#fff',
-                borderWidth: 0,
-                borderColor: '#eee',
-                color: "#eee",
-                hoverable: true,
-              },
-              colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
-            })
-            
+            if(scope.panel.chart === 'bar')
+              scope.plot = $.plot(elem, scope.data, {
+                legend: { show: false },
+                series: {
+                  lines:  { show: false, },
+                  bars:   { show: true,  fill: 1, barWidth: 0.8, horizontal: false },
+                  shadowSize: 1
+                },
+                yaxis: { show: true, min: 0, color: "#000" },
+                xaxis: { show: false },
+                grid: {
+                  backgroundColor: '#fff',
+                  borderWidth: 0,
+                  borderColor: '#eee',
+                  color: "#eee",
+                  hoverable: true,
+                },
+                colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
+              })
+            if(scope.panel.chart === 'pie')
+              scope.plot = $.plot(elem, scope.data, {
+                legend: { show: false },
+                series: {
+                  pie: {
+                    innerRadius: scope.panel.donut ? 0.4 : 0,
+                    tilt: scope.panel.tilt ? 0.45 : 1,
+                    radius: 1,
+                    show: true,
+                    combine: {
+                      color: '#999',
+                      label: 'The Rest'
+                    },
+                    label: { 
+                      show: scope.panel.labels,
+                      radius: 2/3,
+                      formatter: function(label, series){
+                        return '<div ng-click="build_search(panel.query.field,\''+label+'\') "style="font-size:8pt;text-align:center;padding:2px;color:white;">'+
+                          label+'<br/>'+Math.round(series.percent)+'%</div>';
+                      },
+                      threshold: 0.1 
+                    }
+                  }
+                },
+                //grid: { hoverable: true, clickable: true },
+                grid:   { hoverable: true, clickable: true },
+                colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
+              });
+
             // Work around for missing legend at initialization
             // Work around for missing legend at initialization
             if(!scope.$$phase)
             if(!scope.$$phase)
               scope.$apply()
               scope.$apply()
@@ -198,9 +230,11 @@ angular.module('kibana.hits', [])
 
 
       elem.bind("plothover", function (event, pos, item) {
       elem.bind("plothover", function (event, pos, item) {
         if (item) {
         if (item) {
+          var value = scope.panel.chart === 'bar' ? 
+            item.datapoint[1] : item.datapoint[1][0][1];
           tt(pos.pageX, pos.pageY,
           tt(pos.pageX, pos.pageY,
-            "<div style='vertical-align:middle;border-radius:10px;display:inline-block;background:"+item.series.color+";height:20px;width:20px'></div> "+
-            item.datapoint[1].toFixed(0))
+            "<div style='vertical-align:middle;border-radius:10px;display:inline-block;background:"+
+            item.series.color+";height:20px;width:20px'></div> "+value.toFixed(0))
         } else {
         } else {
           $("#pie-tooltip").remove();
           $("#pie-tooltip").remove();
         }
         }

+ 1 - 1
panels/map/module.js

@@ -82,7 +82,7 @@ angular.module('kibana.map', [])
   $scope.build_search = function(field,value) {
   $scope.build_search = function(field,value) {
     $scope.panel.query = add_to_query($scope.panel.query,field,value,false)
     $scope.panel.query = add_to_query($scope.panel.query,field,value,false)
     $scope.get_data();
     $scope.get_data();
-    eventBus.broadcast($scope.$id,$scope.panel.group,'query',$scope.panel.query);
+    eventBus.broadcast($scope.$id,$scope.panel.group,'query',[$scope.panel.query]);
   }
   }
 
 
 })
 })

+ 1 - 36
panels/pie/editor.html

@@ -46,41 +46,6 @@
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
-  <div ng-switch-when="query">
-    <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="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>
 </div>
 </div>
 <div class="row-fluid">    
 <div class="row-fluid">    
   <div class="span1">
   <div class="span1">
@@ -97,7 +62,7 @@
   </div>
   </div>
   <div class="span2">
   <div class="span2">
     <label class="small">Mode</label> 
     <label class="small">Mode</label> 
-    <select class="input-small" ng-change="set_mode(panel.mode)" ng-model="panel.mode" ng-options="f for f in ['query','terms','goal']"></select>
+    <select class="input-small" ng-change="set_mode(panel.mode)" ng-model="panel.mode" ng-options="f for f in ['terms','goal']"></select>
   </div>
   </div>
 </div>
 </div>
 <h5>Panel Spy</h5>
 <h5>Panel Spy</h5>

+ 6 - 6
panels/pie/module.html

@@ -2,11 +2,11 @@
   <span ng-show='panel.spyable' style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
   <span ng-show='panel.spyable' style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
       <i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
       <i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
   </span>
   </span>
-  <span ng-show="panel.legend" ng-repeat='series in legend' style='padding-right:5px'>
-    <div style='white-space:nowrap;display:table-cell'>
-      <div style="display:inline-block;background:{{series.color}};height:10px;width:10px;border-radius:5px;"></div>
-      <div class='small' style='display:inline-block'>{{series.label}} ({{series.percent}}%)</div>
-    </div>
-  </span>  
+
+  <div ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
+    <span ng-show='panel.chart != "none"'><div style="display:inline-block;border-radius:5px;background:{{query.color}};height:10px;width:10px"></div></span><span class="small"> {{query.label}} ({{query.data[0][1]}}) </span></span>
+  </div><br>
+  <div style="clear:both"></div>
+
   <div pie params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
   <div pie params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
 </kibana-panel>         
 </kibana-panel>         

+ 6 - 66
panels/pie/module.js

@@ -20,16 +20,7 @@ angular.module('kibana.pie', [])
   $scope.init = function() {
   $scope.init = function() {
     eventBus.register($scope,'time', function(event,time){set_time(time)});
     eventBus.register($scope,'time', function(event,time){set_time(time)});
     eventBus.register($scope,'query', function(event, query) {
     eventBus.register($scope,'query', function(event, query) {
-      if($scope.panel.mode !== 'query') {
-        $scope.panel.query.query = query;
-        $scope.panel.query.query = _.isArray(query) ? query[0] : query;
-      } else {
-        if(_.isArray(query))
-          $scope.panel.query = _.map(query,function(q) {
-            return {query: q, label: q}}) 
-        else
-          $scope.panel.query[0] = {query: query, label: query}
-      }
+      $scope.panel.query.query = _.isArray(query) ? query[0] : query;
       $scope.get_data();
       $scope.get_data();
     });
     });
     // Now that we're all setup, request the time from our group
     // Now that we're all setup, request the time from our group
@@ -60,9 +51,6 @@ angular.module('kibana.pie', [])
     case 'terms':
     case 'terms':
       $scope.panel.query = {query:"*",field:"_all"};
       $scope.panel.query = {query:"*",field:"_all"};
       break;
       break;
-    case 'query':
-      $scope.panel.query = [{query:"*",label:"*"}];
-      break;
     case 'goal':
     case 'goal':
       $scope.panel.query = {query:"*",goal:100};
       $scope.panel.query = {query:"*",goal:100};
       break;
       break;
@@ -77,49 +65,8 @@ angular.module('kibana.pie', [])
     $scope.panel.loading = true;
     $scope.panel.loading = true;
     var request = $scope.ejs.Request().indices($scope.panel.index);
     var request = $scope.ejs.Request().indices($scope.panel.index);
 
 
-    // If we have an array, use query facet
-    if($scope.panel.mode == "query") {
-      if(!(_.isArray($scope.panel.query)))
-        $scope.panel.query = [$scope.panel.query];
-      var queries = [];
-      // Build the question part of the query
-      _.each($scope.panel.query, function(v) {
-        queries.push(ejs.FilteredQuery(
-          ejs.QueryStringQuery(v.query || '*'),
-          ejs.RangeFilter($scope.time.field)
-            .from($scope.time.from)
-            .to($scope.time.to))
-        )
-      });
-
-      // Then the insert into facet and make the request
-      _.each(queries, function(v) {
-        request = request.facet(ejs.QueryFacet(_.indexOf(queries,v))
-          .query(v)
-          .facetFilter(ejs.QueryFilter(v))
-        )
-      })
-      $scope.populate_modal(request);
-      var results = request.doSearch();
-
-      // Populate scope when we have results
-      results.then(function(results) {
-        $scope.panel.loading = false;
-        $scope.hits = results.hits.total;
-        $scope.data = [];
-        _.each(results.facets, function(v, k) {
-          var series = {};
-          var label = _.isUndefined($scope.panel.query[k].label) ? 
-            $scope.panel.query[k].query : $scope.panel.query[k].label 
-          var slice = { label : label, data : v.count }; 
-          if (!(_.isUndefined($scope.panel.query[k].color)))
-            slice.color = $scope.panel.query[k].color;
-          $scope.data.push(slice)
-        });
-        $scope.$emit('render');
-      });
-    // If we don't have an array, assume its a term facet.
-    } else if ($scope.panel.mode == "terms") {
+    // Terms mode
+    if ($scope.panel.mode == "terms") {
       request = request
       request = request
         .facet(ejs.TermsFacet('pie')
         .facet(ejs.TermsFacet('pie')
           .field($scope.panel.query.field || $scope.panel.default_field)
           .field($scope.panel.query.field || $scope.panel.default_field)
@@ -131,7 +78,6 @@ angular.module('kibana.pie', [])
               ejs.RangeFilter($scope.time.field)
               ejs.RangeFilter($scope.time.field)
                 .from($scope.time.from)
                 .from($scope.time.from)
                 .to($scope.time.to)
                 .to($scope.time.to)
-                .cache(false)
               )))).size(0)
               )))).size(0)
 
 
       $scope.populate_modal(request);
       $scope.populate_modal(request);
@@ -157,6 +103,7 @@ angular.module('kibana.pie', [])
         });
         });
         $scope.$emit('render');
         $scope.$emit('render');
       });
       });
+    // Goal mode
     } else {
     } else {
       request = request
       request = request
         .query(ejs.QueryStringQuery($scope.panel.query.query || '*'))
         .query(ejs.QueryStringQuery($scope.panel.query.query || '*'))
@@ -196,7 +143,7 @@ angular.module('kibana.pie', [])
   $scope.build_search = function(field,value) {
   $scope.build_search = function(field,value) {
     $scope.panel.query.query = add_to_query($scope.panel.query.query,field,value,false)
     $scope.panel.query.query = add_to_query($scope.panel.query.query,field,value,false)
     $scope.get_data();
     $scope.get_data();
-    eventBus.broadcast($scope.$id,$scope.panel.group,'query',$scope.panel.query.query);
+    eventBus.broadcast($scope.$id,$scope.panel.group,'query',[$scope.panel.query.query]);
   }
   }
 
 
   function set_time(time) {
   function set_time(time) {
@@ -275,14 +222,7 @@ angular.module('kibana.pie', [])
         // Populate element
         // Populate element
         if(elem.is(":visible")){
         if(elem.is(":visible")){
           scripts.wait(function(){
           scripts.wait(function(){
-            var plot = $.plot(elem, scope.data, pie);
-            scope.legend = [];
-            _.each(plot.getData(),function(series) {
-              var item = _.pick(series,'label','color','percent')
-              item.percent = parseFloat(item.percent).toFixed(1)
-              scope.legend.push(item)
-            })
-            console.log(scope.legend)
+            scope.plot = $.plot(elem, scope.data, pie);
           });
           });
         }
         }
       }
       }

+ 4 - 10
panels/stringquery/module.js

@@ -13,24 +13,18 @@ angular.module('kibana.stringquery', [])
   }
   }
   _.defaults($scope.panel,_d);
   _.defaults($scope.panel,_d);
 
 
-  var _groups = _.isArray($scope.panel.group) ? 
-    $scope.panel.group : [$scope.panel.group];
-
   $scope.init = function() {
   $scope.init = function() {
 
 
-    // I don't like this compromise. I'm not totally sure what this panel
-    // Should do if its in multi query mode and receives a query. For now, just
-    // replace the first one, though I feel like that isn't right.
+    // If we're in multi query mode, they all get wiped out if we receive a 
+    // query. Query events must be exchanged as arrays.
     eventBus.register($scope,'query',function(event,query) {
     eventBus.register($scope,'query',function(event,query) {
-      if (_.isArray($scope.panel.query))
-        $scope.panel.query[0] = query
-      else
       $scope.panel.query = query;
       $scope.panel.query = query;
     });   
     });   
   }
   }
 
 
   $scope.send_query = function(query) {
   $scope.send_query = function(query) {
-    eventBus.broadcast($scope.$id,$scope.panel.group,'query',query)
+    var _query = _.isArray(query) ? query : [query]
+    eventBus.broadcast($scope.$id,$scope.panel.group,'query',_query)
   }
   }
 
 
   $scope.add_query = function() {
   $scope.add_query = function() {