mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Refactoring query communication into service
This commit is contained in:
parent
e399c328e2
commit
0d560c24e6
9
common/css/bootstrap.light.min.css
vendored
Normal file
9
common/css/bootstrap.light.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -107,6 +107,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pointer:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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'],
|
||||
}
|
||||
);
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
7
panels/query/editor.html
Normal 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
5
panels/query/meta.html
Normal 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
51
panels/query/module.html
Normal 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
70
panels/query/module.js
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
@ -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">
|
||||
|
@ -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
|
||||
});
|
||||
|
@ -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>
|
||||
|
@ -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>
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user