Refactoring query communication into service

This commit is contained in:
Rashid Khan 2013-07-11 17:05:50 -07:00
parent e399c328e2
commit 0d560c24e6
20 changed files with 333 additions and 241 deletions

9
common/css/bootstrap.light.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -107,6 +107,10 @@
cursor: pointer;
}
.pointer:hover {
color: #fff;
}
.pointer {
cursor: pointer;
}

View File

@ -91,7 +91,7 @@ function top_field_values(docs,field,count) {
}
function add_to_query(original,field,value,negate) {
var not = negate ? "NOT " : "";
var not = negate ? "-" : "";
if(value !== '')
var query = field + ":" + "\"" + addslashes(value.toString()) + "\"";
else

View File

@ -22,6 +22,6 @@ var config = new Settings(
kibana_index: "kibana-int",
modules: ['histogram','map','pie','table','stringquery','sort',
'timepicker','text','fields','hits','dashcontrol',
'column','derivequeries','trends','bettermap'],
'column','derivequeries','trends','bettermap','query'],
}
);

View File

@ -186,7 +186,89 @@ angular.module('kibana.services', [])
}
})
.service('query', function() {
.service('query', function(dashboard) {
// Create an object to hold our service state on the dashboard
dashboard.current.services.query = dashboard.current.services.query || {};
_.defaults(dashboard.current.services.query,{
idQueue : [],
list : {},
ids : [],
});
// For convenience
var _q = dashboard.current.services.query;
this.colors = [
"#7EB26D","#EAB839","#6ED0E0","#EF843C","#E24D42","#1F78C1","#BA43A9","#705DA0", //1
"#508642","#CCA300","#447EBC","#C15C17","#890F02","#0A437C","#6D1F62","#584477", //2
"#B7DBAB","#F4D598","#70DBED","#F9BA8F","#F29191","#82B5D8","#E5A8E2","#AEA2E0", //3
"#629E51","#E5AC0E","#64B0C8","#E0752D","#BF1B00","#0A50A1","#962D82","#614D93", //4
"#9AC48A","#F2C96D","#65C5DB","#F9934E","#EA6460","#5195CE","#D683CE","#806EB7", //5
"#3F6833","#967302","#2F575E","#99440A","#58140C","#052B51","#511749","#3F2B5B", //6
"#E0F9D7","#FCEACA","#CFFAFF","#F9E2D2","#FCE2DE","#BADFF4","#F9D9F9","#DEDAF7" //7
];
// Save a reference to this
this.list = dashboard.current.services.query.list;
this.ids = dashboard.current.services.query.ids;
var self = this;
var init = function() {
if (self.ids.length == 0) {
self.set({});
}
}
// This is used both for adding queries and modifying them. If an id is passed, the query at that id is updated
this.set = function(query,id) {
if(!_.isUndefined(id)) {
if(!_.isUndefined(self.list[id])) {
_.extend(self.list[id],query);
return id;
} else {
return false;
}
} else {
var _id = nextId();
var _query = {
query: '*',
alias: '',
color: colorAt(_id)
}
_.defaults(query,_query)
self.list[_id] = query;
self.ids.push(_id)
return id;
}
}
this.remove = function(id) {
if(!_.isUndefined(self.list[id])) {
delete self.list[id];
// This must happen on the full path also since _.without returns a copy
self.ids = dashboard.current.services.query.ids = _.without(self.ids,id)
_q.idQueue.unshift(id)
_q.idQueue.sort(function(a,b){return a-b});
return true;
} else {
return false;
}
}
var nextId = function() {
if(_q.idQueue.length > 0) {
return _q.idQueue.shift()
} else {
return self.ids.length;
}
}
var colorAt = function(id) {
return self.colors[id % self.colors.length]
}
init();
})
.service('dashboard', function($routeParams, $http, $rootScope, ejsResource, timer) {

View File

@ -5,13 +5,6 @@
Also note that geoJSON is <strong>long,lat NOT lat,long</strong>.
</div>
</div>
<div class="row-fluid">
<div class="span11">
<h6>Query</h6>
<input type="text" style="width:100%" ng-model="panel.query">
</div>
</div>
<div class="row-fluid">
<div class="span4">
<form>

View File

@ -22,7 +22,7 @@
*/
angular.module('kibana.bettermap', [])
.controller('bettermap', function($scope, eventBus) {
.controller('bettermap', function($scope, eventBus, query) {
// Set and populate defaults
var _d = {
@ -37,11 +37,12 @@ angular.module('kibana.bettermap', [])
_.defaults($scope.panel,_d)
$scope.init = function() {
eventBus.register($scope,'time', function(event,time){set_time(time)});
eventBus.register($scope,'query', function(event, query) {
$scope.panel.query = _.isArray(query) ? query[0] : query;
$scope.$on('refresh',function(){
$scope.get_data();
});
})
eventBus.register($scope,'time', function(event,time){set_time(time)});
// Now that we're all setup, request the time from our group
eventBus.broadcast($scope.$id,$scope.panel.group,'get_time')
@ -64,9 +65,14 @@ $scope.get_data = function(segment,query_id) {
var _segment = _.isUndefined(segment) ? 0 : segment
$scope.segment = _segment;
var boolQuery = ejs.BoolQuery();
_.each(query.list,function(q) {
boolQuery = boolQuery.should(ejs.QueryStringQuery((q.query || '*') + " AND _exists_:"+$scope.panel.field))
})
var request = $scope.ejs.Request().indices($scope.index[_segment])
.query(ejs.FilteredQuery(
ejs.QueryStringQuery(($scope.panel.query || '*') + " AND _exists_:"+$scope.panel.field),
boolQuery,
ejs.RangeFilter($scope.time.field)
.from($scope.time.from)
.to($scope.time.to)
@ -142,12 +148,6 @@ $scope.get_data = function(segment,query_id) {
$scope.get_data();
}
$scope.build_search = function(field,value) {
$scope.panel.query = add_to_query($scope.panel.query,field,value,false)
$scope.get_data();
eventBus.broadcast($scope.$id,$scope.panel.group,'query',[$scope.panel.query]);
}
})
.directive('bettermap', function() {
return {

View File

@ -14,38 +14,6 @@
<label class="small">Note</label><small> In <strong>{{panel.mode}}</strong> mode the configured field <strong>must</strong> be a numeric type</small>
</div>
</div>
<div class="row-fluid">
<div class="span3">
<form style="margin-bottom: 0px">
<label class="small">Label</label>
<input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
</form>
</div>
<div class="span8">
<label class="small">Query</label>
<form class="input-append" style="margin-bottom: 0px">
<input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
<button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery='';set_refresh(true)"><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" ng-change="set_refresh(true)">
</form>
</div>
<div class="span8">
<form style="margin-bottom: 0px">
<input type="text" style="width:80%" ng-model="q.query" ng-change="set_refresh(true)">
</form>
</div>
<div class="span1">
<i class="icon-remove pointer" ng-click="remove_query(q)"></i>
</div>
</div>
<h5>Chart Options</h5>
<div class="row-fluid" style="margin-bottom:10px;">
<div class="span1"> <label class="small">Bars</label><input type="checkbox" ng-model="panel.bars" ng-checked="panel.bars"></div>

View File

@ -42,7 +42,7 @@
*/
angular.module('kibana.histogram', [])
.controller('histogram', function($scope, eventBus) {
.controller('histogram', function($scope, eventBus,query) {
// Set and populate defaults
var _d = {
@ -72,19 +72,14 @@ angular.module('kibana.histogram', [])
_.defaults($scope.panel,_d)
$scope.init = function() {
$scope.queries = query;
eventBus.register($scope,'time', function(event,time){$scope.set_time(time)});
// Consider eliminating the check for array, this should always be an array
eventBus.register($scope,'query', function(event, query) {
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.$on('refresh',function(){
$scope.get_data();
});
})
// Now that we're all setup, request the time from our group if we don't
// have it yet
@ -92,21 +87,6 @@ angular.module('kibana.histogram', [])
eventBus.broadcast($scope.$id,$scope.panel.group,'get_time')
}
$scope.remove_query = function(q) {
$scope.panel.query = _.without($scope.panel.query,q);
$scope.get_data();
}
$scope.add_query = function(label,query) {
if(!(_.isArray($scope.panel.query)))
$scope.panel.query = new Array();
$scope.panel.query.unshift({
query: query,
label: label,
});
$scope.get_data();
}
$scope.get_data = function(segment,query_id) {
delete $scope.panel.error
// Make sure we have everything for the request to complete
@ -120,22 +100,17 @@ angular.module('kibana.histogram', [])
var _segment = _.isUndefined(segment) ? 0 : segment
var request = $scope.ejs.Request().indices($scope.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 || '*'),
// Build the query
_.each($scope.queries.ids, function(id) {
var query = $scope.ejs.FilteredQuery(
ejs.QueryStringQuery($scope.queries.list[id].query || '*'),
ejs.RangeFilter($scope.time.field)
.from($scope.time.from)
.to($scope.time.to))
.to($scope.time.to)
)
});
// Build the facet part, injecting the query in as a facet filter
_.each(queries, function(v) {
var facet = $scope.ejs.DateHistogramFacet("chart"+_.indexOf(queries,v))
var facet = $scope.ejs.DateHistogramFacet(id)
if($scope.panel.mode === 'count') {
facet = facet.field($scope.time.field)
} else {
@ -145,9 +120,9 @@ angular.module('kibana.histogram', [])
}
facet = facet.keyField($scope.time.field).valueField($scope.panel.value_field)
}
facet = facet.interval($scope.panel.interval).facetFilter($scope.ejs.QueryFilter(v))
facet = facet.interval($scope.panel.interval).facetFilter($scope.ejs.QueryFilter(query))
request = request.facet(facet).size(0)
})
});
// Populate the inspector panel
$scope.populate_modal(request);
@ -174,7 +149,7 @@ angular.module('kibana.histogram', [])
if($scope.query_id === query_id) {
var i = 0;
_.each(results.facets, function(v, k) {
_.each(results.facets, function(v, id) {
// Null values at each end of the time range ensure we see entire range
if(_.isUndefined($scope.data[i]) || _segment == 0) {
@ -197,15 +172,12 @@ angular.module('kibana.histogram', [])
// Create the flot series object
var series = {
data: {
label: $scope.panel.query[i].label || "query"+(parseInt(i)+1),
id: id,
data: data,
hits: hits
},
};
if (!(_.isUndefined($scope.panel.query[i].color)))
series.data.color = $scope.panel.query[i].color;
$scope.data[i] = series.data
i++;
@ -276,6 +248,12 @@ angular.module('kibana.histogram', [])
// Function for rendering panel
function render_panel() {
// Populate from the query service
_.each(scope.data,function(series) {
series.label = scope.queries.list[series.id].alias,
series.color = scope.queries.list[series.id].color
})
// Set barwidth based on specified interval
var barwidth = interval_to_seconds(scope.panel.interval)*1000

View File

@ -26,38 +26,4 @@
<label class="small">Labels</label><input type="checkbox" ng-model="panel.labels" ng-checked="panel.labels">
</div>
</div>
<h5>Queries</h5>
<div class="row-fluid">
<div class="span3">
<form style="margin-bottom: 0px">
<label class="small">Label</label>
<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">
<label class="small">Query</label>
<input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
<button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery='';set_refresh(true)"><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" ng-change="set_refresh(true)">
</form>
</div>
<div class="span8">
<form class="input-append" style="margin-bottom: 0px">
<input type="text" style="width:80%" ng-model="q.query" ng-change="set_refresh(true)">
<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>

View File

@ -22,7 +22,7 @@
*/
angular.module('kibana.hits', [])
.controller('hits', function($scope, eventBus) {
.controller('hits', function($scope, eventBus, query) {
// Set and populate defaults
var _d = {
@ -40,16 +40,20 @@ angular.module('kibana.hits', [])
_.defaults($scope.panel,_d)
$scope.init = function () {
$scope.queries = query;
$scope.hits = 0;
eventBus.register($scope,'time', function(event,time){
set_time(time)
});
eventBus.register($scope,'query', function(event, query) {
$scope.panel.query = _.map(query,function(q) {
return {query: q, label: q};
})
$scope.$on('refresh',function(){
console.log($scope.queries)
console.log(query)
$scope.get_data();
});
})
// Now that we're all setup, request the time from our group
eventBus.broadcast($scope.$id,$scope.panel.group,'get_time')
}
@ -66,23 +70,18 @@ angular.module('kibana.hits', [])
var request = $scope.ejs.Request().indices($scope.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 || '*'),
_.each($scope.queries.ids, function(id) {
var query = $scope.ejs.FilteredQuery(
ejs.QueryStringQuery($scope.queries.list[id].query || '*'),
ejs.RangeFilter($scope.time.field)
.from($scope.time.from)
.to($scope.time.to))
)
});
// Build the facet part
_.each(queries, function(v) {
request = request
.facet($scope.ejs.QueryFacet("query"+_.indexOf(queries,v))
.query(v)
.facet($scope.ejs.QueryFacet(id)
.query(query)
).size(0)
})
});
// TODO: Spy for hits panel
//$scope.populate_modal(request);
@ -107,14 +106,15 @@ angular.module('kibana.hits', [])
}
if($scope.query_id === query_id) {
var i = 0;
_.each(results.facets, function(v, k) {
_.each(results.facets, function(v, id) {
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),
//label: $scope.panel.query[i].label || "query"+(parseInt(i)+1),
id: id,
hits: hits,
data: [[i,hits]]
};
@ -177,6 +177,11 @@ angular.module('kibana.hits', [])
// Function for rendering panel
function render_panel() {
_.each(scope.data,function(series) {
series.label = scope.queries.list[series.id].alias,
series.color = scope.queries.list[series.id].color
})
var scripts = $LAB.script("common/lib/panels/jquery.flot.js").wait()
.script("common/lib/panels/jquery.flot.pie.js")

7
panels/query/editor.html Normal file
View File

@ -0,0 +1,7 @@
<div>
<div class="row-fluid">
<div class="span12">
No options here
</div>
</div>
</div>

5
panels/query/meta.html Normal file
View File

@ -0,0 +1,5 @@
<style>
</style>
<a class="close" ng-click="render();dismiss();" href="">×</a>
<input class="input-medium" type="text" ng-model="queries.list[id].alias" placeholder='Alias...' />
<i ng-repeat="color in queries.colors" class="pointer" ng-class="{'icon-circle-blank':queries.list[id].color == color,'icon-circle':queries.list[id].color != color}" style="color:{{color}}" ng-click="queries.list[id].color = color;render();"> </i>

51
panels/query/module.html Normal file
View File

@ -0,0 +1,51 @@
<kibana-panel ng-controller='query' ng-init="init()">
<style>
.short-query {
display:inline-block;
margin-left: 10px;
}
.begin-query {
position:absolute;
left:15px;
top:5px;
}
.end-query {
position:absolute;
right:15px;
top:5px;
}
.panel-query {
padding-left: 35px !important;
height: 31px !important;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
.form-search:hover .has-remove {
padding-left: 50px !important;
}
.remove-query {
opacity: 0;
}
.last-query {
padding-right: 45px !important;
}
.form-search:hover .remove-query {
opacity: 1;
}
</style>
<label class="small">{{panel.label}}</label>
<div ng-repeat="id in queries.ids" ng-class="{'short-query': queries.ids.length>1}">
<form class="form-search" style="position:relative" ng-submit="refresh()">
<span class="begin-query">
<i class="icon-circle pointer" data-unique="1" bs-popover="'panels/query/meta.html'" data-placement="right" style="color:{{queries.list[id].color}}"></i>
<i class="icon-remove-sign pointer remove-query" ng-show="queries.ids.length>1" ng-click="queries.remove(id);refresh()"></i>
</span>
<input class="search-query panel-query" ng-class="{'input-block-level': queries.ids.length==1,'last-query': $last,'has-remove': queries.ids.length>1}" bs-typeahead="panel.history" data-min-length=0 data-items=100 type="text" ng-model="queries.list[id].query"/>
<span class="end-query">
<i class="icon-search pointer" ng-click="refresh()" ng-show="$last"></i>
<i class="icon-plus pointer" ng-click="queries.set({})" ng-show="$last"></i>
</span
</form>
</div>
</kibana-panel>

70
panels/query/module.js Normal file
View File

@ -0,0 +1,70 @@
/*
## query
An experimental panel for the query service
### Parameters
* label :: The label to stick over the field
* query :: A string or an array of querys. String if multi is off, array if it is on
This should be fixed, it should always be an array even if its only
one element
* multi :: Allow input of multiple queries? true/false
* multi_arrange :: How to arrange multu query string panels, 'vertical' or 'horizontal'
### Group Events
#### Sends
* query :: Always broadcast as an array, even in multi: false
#### Receives
* query :: An array of queries. This is probably needs to be fixed.
*/
angular.module('kibana.query', [])
.controller('query', function($scope, eventBus, query, $rootScope) {
// Set and populate defaults
var _d = {
status : "Experimental",
label : "Search",
query : "*",
group : "default",
history : [],
remember: 10 // max: 100, angular strap can't take a variable for items param
}
_.defaults($scope.panel,_d);
$scope.queries = query;
$scope.init = function() {
}
$scope.refresh = function(query) {
console.log('refresh')
$rootScope.$broadcast('refresh')
}
$scope.render = function(query) {
console.log('render')
$rootScope.$broadcast('render')
}
$scope.add_query = function() {
if (_.isArray($scope.panel.query))
$scope.panel.query.push("")
else {
$scope.panel.query = new Array($scope.panel.query)
$scope.panel.query.push("")
}
}
var update_history = function(query) {
if($scope.panel.remember > 0) {
$scope.panel.history = _.union(query.reverse(),$scope.panel.history)
var _length = $scope.panel.history.length
if(_length > $scope.panel.remember) {
$scope.panel.history = $scope.panel.history.slice(0,$scope.panel.remember)
}
}
}
});

View File

@ -1,12 +1,3 @@
<div class="row-fluid">
<div style="width:90%">
<form class="input-append">
<h6>Query</h6>
<input type="text" style="width:90%" ng-model="panel.query">
<button class="btn" ng-click="get_data();"><i class="icon-search"></i></button>
</form>
</div>
</div>
<div class="row-fluid">
<div class="span4">
<form class="input-append">

View File

@ -29,7 +29,7 @@
*/
angular.module('kibana.table', [])
.controller('table', function($scope, eventBus, fields) {
.controller('table', function($rootScope, $scope, eventBus, fields, query) {
// Set and populate defaults
var _d = {
@ -60,15 +60,11 @@ angular.module('kibana.table', [])
}
$scope.set_listeners = function(group) {
$scope.$on('refresh',function(){$scope.get_data()})
eventBus.register($scope,'time',function(event,time) {
$scope.panel.offset = 0;
set_time(time)
});
eventBus.register($scope,'query',function(event,query) {
$scope.panel.offset = 0;
$scope.panel.query = _.isArray(query) ? query[0] : query;
$scope.get_data();
});
eventBus.register($scope,'sort', function(event,sort){
$scope.panel.sort = _.clone(sort);
$scope.get_data();
@ -77,7 +73,7 @@ angular.module('kibana.table', [])
$scope.panel.fields = _.clone(fields)
});
eventBus.register($scope,'table_documents', function(event, docs) {
$scope.panel.query = docs.query;
query.list[query.ids[0]].query = docs.query;
$scope.data = docs.docs;
});
}
@ -116,10 +112,11 @@ angular.module('kibana.table', [])
}
$scope.build_search = function(field,value,negate) {
$scope.panel.query = add_to_query($scope.panel.query,field,value,negate)
_.each(query.list,function(q) {
q.query = add_to_query(q.query,field,value,negate);
})
$scope.panel.offset = 0;
$scope.get_data();
eventBus.broadcast($scope.$id,$scope.panel.group,'query',[$scope.panel.query]);
$rootScope.$broadcast('refresh')
}
$scope.get_data = function(segment,query_id) {
@ -135,8 +132,15 @@ angular.module('kibana.table', [])
$scope.segment = _segment;
var request = $scope.ejs.Request().indices($scope.index[_segment])
.query(ejs.FilteredQuery(
ejs.QueryStringQuery($scope.panel.query || '*'),
var boolQuery = ejs.BoolQuery();
_.each(query.list,function(q) {
boolQuery = boolQuery.should(ejs.QueryStringQuery(q.query || '*'))
})
request = request.query(
ejs.FilteredQuery(
boolQuery,
ejs.RangeFilter($scope.time.field)
.from($scope.time.from)
.to($scope.time.to)
@ -244,7 +248,7 @@ angular.module('kibana.table', [])
});
eventBus.broadcast($scope.$id,$scope.panel.group,"table_documents",
{
query: $scope.panel.query,
query: query.list[query.ids[0]].query,
docs : _.pluck($scope.data,'_source'),
index: $scope.index
});

View File

@ -26,36 +26,4 @@
<select class="input-small" ng-model="panel.arrangement" ng-options="f for f in ['horizontal','vertical']"></select></span>
</div>
</div>
<h5>Queries</h5>
<div class="row-fluid">
<div class="span3">
<form style="margin-bottom: 0px">
<label class="small">Label</label>
<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">
<label class="small">Query</label>
<input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
<button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery='';set_refresh(true)"><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" ng-change="set_refresh(true)">
</form>
</div>
<div class="span8">
<input type="text" style="width:80%" ng-model="q.query" ng-change="set_refresh(true)">
</div>
<div class="span1">
<i class="icon-remove pointer" ng-click="remove_query(q)"></i>
</div>
</div>
</div>

View File

@ -1,10 +1,11 @@
<kibana-panel ng-controller='trends' ng-init="init()">
<div ng-style="panel.style" style="line-height:{{panel.style['font-size']}};display:inline-block;padding-right: 5px;" ng-repeat="query in trends">
<i class="icon-circle" style="color:{{query.info.color}}"></i>
<span ng-class="{'text-success': query.hits.new >= query.hits.old, 'text-error': query.hits.old > query.hits.new}" class='strong'>
<i class='large' ng-class="{'icon-caret-up': query.hits.new >= query.hits.old, 'icon-caret-down': query.hits.old > query.hits.new}"></i> {{query.percent}}%
</span>
<span class="tiny pointer light" bs-tooltip="'Then: '+query.hits.old+', Now: '+query.hits.new">({{query.label}})</span>
<span class="tiny pointer light" bs-tooltip="'Then: '+query.hits.old+', Now: '+query.hits.new" ng-show="query.label != ''">({{query.info.alias}})</span>
<br ng-show="panel.arrangement == 'vertical'">
</div>
</kibana-panel>

View File

@ -19,7 +19,7 @@
*/
angular.module('kibana.trends', [])
.controller('trends', function($scope, eventBus, kbnIndex) {
.controller('trends', function($scope, eventBus, kbnIndex, query) {
// Set and populate defaults
var _d = {
@ -64,43 +64,32 @@ angular.module('kibana.trends', [])
var request = $scope.ejs.Request();
// Build the question part of the query
var queries = [];
_.each($scope.panel.query, function(v) {
queries.push($scope.ejs.FilteredQuery(
ejs.QueryStringQuery(v.query || '*'),
_.each(query.ids, function(id) {
var q = $scope.ejs.FilteredQuery(
ejs.QueryStringQuery(query.list[id].query || '*'),
ejs.RangeFilter($scope.time.field)
.from($scope.time.from)
.to($scope.time.to))
)
request = request
.facet($scope.ejs.QueryFacet(id)
.query(q)
).size(0)
});
// Build the facet part
_.each(queries, function(v) {
request = request
.facet($scope.ejs.QueryFacet("new"+_.indexOf(queries,v))
.query(v)
).size(0)
})
var queries = [];
_.each($scope.panel.query, function(v) {
queries.push($scope.ejs.FilteredQuery(
ejs.QueryStringQuery(v.query || '*'),
// And again for the old time period
_.each(query.ids, function(id) {
var q = $scope.ejs.FilteredQuery(
ejs.QueryStringQuery(query.list[id].query || '*'),
ejs.RangeFilter($scope.time.field)
.from($scope.old_time.from)
.to($scope.old_time.to))
)
request = request
.facet($scope.ejs.QueryFacet("old_"+id)
.query(q)
).size(0)
});
// Build the facet part
_.each(queries, function(v) {
request = request
.facet($scope.ejs.QueryFacet("old"+_.indexOf(queries,v))
.query(v)
).size(0)
})
// TODO: Spy for hits panel
// TODO: Spy for trend panel
//$scope.populate_modal(request);
// If we're on the first segment we need to get our indices
@ -121,6 +110,7 @@ angular.module('kibana.trends', [])
// Populate scope when we have results
function process_results(results) {
results.then(function(results) {
console.log(results)
$scope.panel.loading = false;
if(_segment == 0) {
@ -136,9 +126,9 @@ angular.module('kibana.trends', [])
}
if($scope.query_id === query_id) {
var i = 0;
_.each($scope.panel.query, function(k) {
var n = results.facets['new'+i].count
var o = results.facets['old'+i].count
_.each(query.ids, function(id) {
var n = results.facets[id].count
var o = results.facets['old_'+id].count
var hits = {
new : _.isUndefined($scope.data[i]) || _segment == 0 ? n : $scope.data[i].hits.new+n,
@ -152,7 +142,7 @@ angular.module('kibana.trends', [])
'?' : Math.round(percentage(hits.old,hits.new)*100)/100
// Create series
$scope.data[i] = {
label: $scope.panel.query[i].label || "query"+(parseInt(i)+1),
info: query.list[id],
hits: {
new : hits.new,
old : hits.old