forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add percentiles panel, only support elasticsearch 1.1 or above.
new file: app/panels/percentiles/editor.html new file: app/panels/percentiles/module.html new file: app/panels/percentiles/module.js modified: config.js
- Loading branch information
Showing
4 changed files
with
303 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<div class="row-fluid"> | ||
<h5>Details</h5> | ||
<div class="editor-option"> | ||
<label class="small">Featured Stat</label> | ||
<select ng-change="set_refresh(true)" class="input-small" ng-model="panel.mode" ng-options="f for f in modes"></select> | ||
</div> | ||
<div class="editor-option"> | ||
<label class="small">Field <tip>This field must contain a numeric value</tip></label> | ||
<input ng-change="set_refresh(true)" placeholder="Start typing" bs-typeahead="fields.list" type="text" class="input-large" ng-model="panel.field"> | ||
</div> | ||
<div class="editor-option"> | ||
<label class="small">Unit</label> | ||
<input type="text" class="input-large" ng-model="panel.unit"> | ||
</div> | ||
|
||
<h5>Columns</h5> | ||
<div class="editor-option" ng-repeat="stat in modes"> | ||
<label class="small">{{stat}}</label><input type="checkbox" ng-model="panel.show[stat]" ng-checked="panel.show[stat]"> | ||
</div> | ||
|
||
<h5>Formating</h5> | ||
<div class="editor-option"> | ||
<label class="small">Format</label> | ||
<select ng-change="set_refresh(true)" class="input-small" ng-model="panel.format" ng-options="f for f in ['number','float','money','bytes']"></select> | ||
</div> | ||
<div class="editor-option"> | ||
<label class="small">Font Size</label> | ||
<select class="input-mini" 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="editor-option"> | ||
<label class="small">Display Breakdowns</label> | ||
<select class="input-mini" ng-model="panel.display_breakdown" ng-options="f for f in ['yes', 'no']"></select></span> | ||
</div> | ||
<div class="editor-option"> | ||
<label class="small">Query column name</label> | ||
<input type="text" class="input-large" ng-model="panel.label_name"> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<div ng-controller="percentiles" ng-init="init()"> | ||
<style> | ||
table.stats-table th, table.stats-table td { | ||
text-align: right; | ||
} | ||
|
||
table.stats-table th:first-child, table.stats-table td:first-child { | ||
text-align: left !important; | ||
} | ||
|
||
|
||
</style> | ||
|
||
<h1 ng-style="panel.style" style="text-align: center; line-height: .6em">{{data.value|formatstats:panel.format}} <small style="font-size: .5em; line-height: 0;">{{panel.unit}} ({{panel.mode}})</small></h1> | ||
<table ng-show="panel.display_breakdown == 'yes'" cellspacing="0" class="table-hover table table-condensed stats-table" style="margin-top: 38px;"> | ||
<tbody> | ||
<thead> | ||
<tr> | ||
<th><a href="" ng-click="set_sort('label')" ng-class="{'icon-chevron-down': panel.sort_field == 'label' && panel.sort_reverse == true, 'icon-chevron-up': panel.sort_field == 'label' && panel.sort_reverse == false}"> {{panel.label_name}} </a></th> | ||
<th ng-repeat="stat in modes" ng-show="panel.show[stat]"> | ||
<a href="" | ||
ng-click="set_sort(stat)" | ||
ng-class="{'icon-chevron-down': panel.sort_field == stat && panel.sort_reverse == true, 'icon-chevron-up': panel.sort_field == stat && panel.sort_reverse == false}"> | ||
{{stat}}% | ||
</a> | ||
</th> | ||
</tr> | ||
</thead> | ||
<tr ng-repeat="item in data.rows | orderBy:(panel.sort_field == 'label' ? 'label' : 'value.'+panel.sort_field):panel.sort_reverse"> | ||
<td><i class="icon-circle" ng-style="{color:item.color}"></i> {{item.label}}</td> | ||
<td ng-repeat="stat in modes" ng-show="panel.show[stat]">{{item.value[stat]|formatstats:panel.format}} {{panel.unit}}</td> | ||
|
||
<!--<td style="text-align: right;">{{item.value|formatstats:panel.format}} {{panel.unit}}</td>--> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
/* | ||
## Percentiles Module | ||
### Parameters | ||
* format :: The format of the value returned. (Default: number) | ||
* style :: The font size of the main number to be displayed. | ||
* mode :: The aggergate value to use for display | ||
* spyable :: Dislay the 'eye' icon that show the last elasticsearch query | ||
*/ | ||
define([ | ||
'angular', | ||
'app', | ||
'lodash', | ||
'jquery', | ||
'kbn', | ||
'numeral', | ||
'config' | ||
], function ( | ||
angular, | ||
app, | ||
_, | ||
$, | ||
kbn, | ||
numeral, | ||
config | ||
) { | ||
|
||
'use strict'; | ||
|
||
var module = angular.module('kibana.panels.percentiles', []); | ||
app.useModule(module); | ||
|
||
module.controller('percentiles', function ($scope, querySrv, dashboard, filterSrv, $http) { | ||
|
||
$scope.panelMeta = { | ||
modals : [ | ||
{ | ||
description: "Inspect", | ||
icon: "icon-info-sign", | ||
partial: "app/partials/inspector.html", | ||
show: $scope.panel.spyable | ||
} | ||
], | ||
editorTabs : [ | ||
{title:'Queries', src:'app/partials/querySelect.html'} | ||
], | ||
status: 'Beta', | ||
description: 'A percentiles panel for displaying aggregations using the Elastic Search percentiles aggregation query.' | ||
}; | ||
|
||
$scope.modes = ['50.0','75.0','90.0','95.0','99.0']; | ||
|
||
var defaults = { | ||
queries : { | ||
mode : 'all', | ||
ids : [] | ||
}, | ||
style : { "font-size": '24pt'}, | ||
format: 'number', | ||
mode: 'count', | ||
display_breakdown: 'yes', | ||
sort_field: '', | ||
sort_reverse: false, | ||
label_name: 'Query', | ||
value_name: 'Value', | ||
spyable : true, | ||
show: { | ||
'50.0': true, | ||
'75.0': true, | ||
'90.0': true, | ||
'95.0': true, | ||
'99.0': true, | ||
} | ||
}; | ||
|
||
_.defaults($scope.panel, defaults); | ||
|
||
$scope.init = function () { | ||
$scope.ready = false; | ||
$scope.$on('refresh', function () { | ||
$scope.get_data(); | ||
}); | ||
$scope.get_data(); | ||
}; | ||
|
||
$scope.set_sort = function(field) { | ||
console.log(field); | ||
if($scope.panel.sort_field === field && $scope.panel.sort_reverse === false) { | ||
$scope.panel.sort_reverse = true; | ||
} else if($scope.panel.sort_field === field && $scope.panel.sort_reverse === true) { | ||
$scope.panel.sort_field = ''; | ||
$scope.panel.sort_reverse = false; | ||
} else { | ||
$scope.panel.sort_field = field; | ||
$scope.panel.sort_reverse = false; | ||
} | ||
}; | ||
|
||
$scope.get_data = function () { | ||
if(dashboard.indices.length === 0) { | ||
return; | ||
} | ||
|
||
$scope.panelMeta.loading = true; | ||
|
||
var request, | ||
results, | ||
boolQuery, | ||
queries; | ||
|
||
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries); | ||
queries = querySrv.getQueryObjs($scope.panel.queries.ids); | ||
|
||
// This could probably be changed to a BoolFilter | ||
boolQuery = $scope.ejs.BoolQuery(); | ||
_.each(queries,function(q) { | ||
boolQuery = boolQuery.should(querySrv.toEjsObj(q)); | ||
}); | ||
|
||
request = { | ||
'stats': { | ||
'filter': JSON.parse($scope.ejs.QueryFilter( | ||
$scope.ejs.FilteredQuery( | ||
boolQuery, | ||
filterSrv.getBoolFilter(filterSrv.ids()) | ||
) | ||
).toString(), true), | ||
'aggs': { | ||
'stats': { | ||
'percentiles': { | ||
'field': $scope.panel.field, | ||
'percents': $scope.modes | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
$.each(queries, function (i, q) { | ||
var query = $scope.ejs.BoolQuery(); | ||
query.should(querySrv.toEjsObj(q)); | ||
var qname = 'stats_'+i; | ||
var aggsquery = {}; | ||
aggsquery[qname] = { | ||
'percentiles': { | ||
'field': $scope.panel.field, | ||
'percents': $scope.modes | ||
} | ||
}; | ||
request[qname] = { | ||
'filter': JSON.parse($scope.ejs.QueryFilter( | ||
$scope.ejs.FilteredQuery( | ||
query, | ||
filterSrv.getBoolFilter(filterSrv.ids()) | ||
) | ||
).toString(), true), | ||
'aggs': aggsquery | ||
}; | ||
}); | ||
// Populate the inspector panel | ||
$scope.inspector = angular.toJson({aggs:request},true); | ||
|
||
results = $http({ | ||
url: config.elasticsearch + '/' + dashboard.indices + '/_search?size=0', | ||
method: "POST", | ||
data: { aggs: request } | ||
}); | ||
|
||
results.then(function(results) { | ||
$scope.panelMeta.loading = false; | ||
var value = results.data.aggregations.stats['doc_count']; | ||
|
||
var rows = queries.map(function (q, i) { | ||
var alias = q.alias || q.query; | ||
var obj = _.clone(q); | ||
obj.label = alias; | ||
obj.Label = alias.toLowerCase(); //sort field | ||
obj.value = results.data.aggregations['stats_'+i]['stats_'+i]; | ||
obj.Value = results.data.aggregations['stats_'+i]['stats_'+i]; //sort field | ||
return obj; | ||
}); | ||
|
||
$scope.data = { | ||
value: value, | ||
rows: rows | ||
}; | ||
|
||
$scope.$emit('render'); | ||
}); | ||
}; | ||
|
||
$scope.set_refresh = function (state) { | ||
$scope.refresh = state; | ||
}; | ||
|
||
$scope.close_edit = function() { | ||
if($scope.refresh) { | ||
$scope.get_data(); | ||
} | ||
$scope.refresh = false; | ||
$scope.$emit('render'); | ||
}; | ||
|
||
}); | ||
|
||
module.filter('formatstats', function(){ | ||
return function (value,format) { | ||
switch (format) { | ||
case 'money': | ||
value = numeral(value).format('$0,0.00'); | ||
break; | ||
case 'bytes': | ||
value = numeral(value).format('0.00b'); | ||
break; | ||
case 'float': | ||
value = numeral(value).format('0.000'); | ||
break; | ||
default: | ||
value = numeral(value).format('0,0'); | ||
} | ||
return value; | ||
}; | ||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,7 @@ function (Settings) { | |
'query', | ||
'terms', | ||
'stats', | ||
'percentiles', | ||
'sparklines' | ||
] | ||
}); | ||
|