mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
commit
0dd0cfeb2e
20
common/css/bootstrap.dark.min.css
vendored
20
common/css/bootstrap.dark.min.css
vendored
@ -226,7 +226,7 @@ body {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
color: #c8c8c8;
|
||||
color: #ddd;
|
||||
background-color: #272b30;
|
||||
}
|
||||
|
||||
@ -1096,7 +1096,7 @@ input[type="color"],
|
||||
margin-bottom: 10.5px;
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
color: #c8c8c8;
|
||||
color: #fff;
|
||||
vertical-align: middle;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
@ -1129,8 +1129,8 @@ input[type="search"],
|
||||
input[type="tel"],
|
||||
input[type="color"],
|
||||
.uneditable-input {
|
||||
background-color: #222;
|
||||
border: 1px solid #333;
|
||||
background-color: #666;
|
||||
border: 1px solid #666;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
@ -1197,8 +1197,8 @@ input[type="file"] {
|
||||
|
||||
select {
|
||||
width: 220px;
|
||||
background-color: #222;
|
||||
border: 1px solid #333;
|
||||
background-color: #666;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
select[multiple],
|
||||
@ -5201,8 +5201,8 @@ input[type="submit"].btn.btn-mini {
|
||||
top: 10%;
|
||||
left: 50%;
|
||||
z-index: 1050;
|
||||
width: 560px;
|
||||
margin-left: -280px;
|
||||
width: 760px;
|
||||
margin-left: -380px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #999;
|
||||
border: 1px solid rgba(0, 0, 0, 0.3);
|
||||
@ -5228,7 +5228,7 @@ input[type="submit"].btn.btn-mini {
|
||||
}
|
||||
|
||||
.modal.fade.in {
|
||||
top: 10%;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
@ -5247,7 +5247,7 @@ input[type="submit"].btn.btn-mini {
|
||||
|
||||
.modal-body {
|
||||
position: relative;
|
||||
max-height: 400px;
|
||||
max-height: 500px;
|
||||
padding: 15px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
@ -131,6 +131,14 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.normal {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.light {
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.input-append label {
|
||||
font-size: inherit !important;
|
||||
}
|
||||
|
@ -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'],
|
||||
'column','derivequeries','trends'],
|
||||
}
|
||||
);
|
||||
|
@ -83,6 +83,85 @@ angular.module('kibana.services', [])
|
||||
return fields;
|
||||
|
||||
})
|
||||
.service('kbnIndex',function($http) {
|
||||
// returns a promise containing an array of all indices matching the index
|
||||
// pattern that exist in a given range
|
||||
this.indices = function(from,to,pattern,interval) {
|
||||
var possible = [];
|
||||
_.each(expand_range(fake_utc(from),fake_utc(to),interval),function(d){
|
||||
possible.push(d.format(pattern));
|
||||
});
|
||||
|
||||
return all_indices().then(function(p) {
|
||||
var indices = _.intersection(possible,p);
|
||||
indices.reverse();
|
||||
return indices
|
||||
})
|
||||
};
|
||||
|
||||
// returns a promise containing an array of all indices in an elasticsearch
|
||||
// cluster
|
||||
function all_indices() {
|
||||
var something = $http({
|
||||
url: config.elasticsearch + "/_aliases",
|
||||
method: "GET"
|
||||
}).error(function(data, status, headers, config) {
|
||||
// Handle error condition somehow?
|
||||
});
|
||||
|
||||
return something.then(function(p) {
|
||||
var indices = [];
|
||||
_.each(p.data, function(v,k) {
|
||||
indices.push(k)
|
||||
});
|
||||
return indices;
|
||||
});
|
||||
}
|
||||
|
||||
// this is stupid, but there is otherwise no good way to ensure that when
|
||||
// I extract the date from an object that I'm get the UTC date. Stupid js.
|
||||
// I die a little inside every time I call this function.
|
||||
// Update: I just read this again. I died a little more inside.
|
||||
// Update2: More death.
|
||||
function fake_utc(date) {
|
||||
date = moment(date).clone().toDate()
|
||||
return moment(new Date(date.getTime() + date.getTimezoneOffset() * 60000));
|
||||
}
|
||||
|
||||
// Create an array of date objects by a given interval
|
||||
function expand_range(start, end, interval) {
|
||||
if(_.contains(['hour','day','week','month','year'],interval)) {
|
||||
var range;
|
||||
start = moment(start).clone();
|
||||
range = [];
|
||||
while (start.isBefore(end)) {
|
||||
range.push(start.clone());
|
||||
switch (interval) {
|
||||
case 'hour':
|
||||
start.add('hours',1)
|
||||
break
|
||||
case 'day':
|
||||
start.add('days',1)
|
||||
break
|
||||
case 'week':
|
||||
start.add('weeks',1)
|
||||
break
|
||||
case 'month':
|
||||
start.add('months',1)
|
||||
break
|
||||
case 'year':
|
||||
start.add('years',1)
|
||||
break
|
||||
}
|
||||
}
|
||||
range.push(moment(end).clone());
|
||||
return range;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.service('timer', function($timeout) {
|
||||
// This service really just tracks a list of $timeout promises to give us a
|
||||
// method for cancelling them all when we need to
|
||||
|
@ -25,7 +25,7 @@
|
||||
<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=''"><i class="icon-plus"></i></button>
|
||||
<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">
|
||||
@ -34,7 +34,7 @@
|
||||
<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">
|
||||
<input type="text" style="width:70%" ng-model="q.label" ng-change="set_refresh(true)">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span8">
|
||||
|
@ -315,7 +315,7 @@ angular.module('kibana.histogram', [])
|
||||
color: '#ccc'
|
||||
},
|
||||
grid: {
|
||||
backgroundColor: '#272b30',
|
||||
backgroundColor: null,
|
||||
borderWidth: 0,
|
||||
borderColor: '#eee',
|
||||
color: "#eee",
|
||||
|
@ -38,7 +38,7 @@
|
||||
<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=''"><i class="icon-plus"></i></button>
|
||||
<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">
|
||||
@ -47,12 +47,12 @@
|
||||
<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">
|
||||
<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">
|
||||
<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>
|
||||
|
@ -141,6 +141,17 @@ angular.module('kibana.hits', [])
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
$scope.set_refresh = function (state) {
|
||||
$scope.refresh = state;
|
||||
}
|
||||
|
||||
$scope.close_edit = function() {
|
||||
if($scope.refresh)
|
||||
$scope.get_data();
|
||||
$scope.refresh = false;
|
||||
$scope.$emit('render');
|
||||
}
|
||||
|
||||
function set_time(time) {
|
||||
$scope.time = time;
|
||||
$scope.index = _.isUndefined(time.index) ? $scope.index : time.index
|
||||
|
@ -145,7 +145,7 @@ angular.module('kibana.map', [])
|
||||
map: scope.panel.map,
|
||||
regionStyle: {initial: {fill: '#8c8c8c'}},
|
||||
zoomOnScroll: false,
|
||||
backgroundColor: '#272b30',
|
||||
backgroundColor: null,
|
||||
series: {
|
||||
regions: [{
|
||||
values: scope.data,
|
||||
|
@ -246,14 +246,13 @@ angular.module('kibana.pie', [])
|
||||
},
|
||||
label: label,
|
||||
stroke: {
|
||||
color: '#272b30',
|
||||
width: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
//grid: { hoverable: true, clickable: true },
|
||||
grid: {
|
||||
backgroundColor: '#272b30',
|
||||
backgroundColor: null,
|
||||
hoverable: true,
|
||||
clickable: true
|
||||
},
|
||||
|
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
angular.module('kibana.timepicker', [])
|
||||
.controller('timepicker', function($scope, eventBus, $timeout, timer, $http) {
|
||||
.controller('timepicker', function($scope, eventBus, $timeout, timer, $http, kbnIndex) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
@ -89,7 +89,7 @@ angular.module('kibana.timepicker', [])
|
||||
// request one be sent by broadcasting a 'get_time' with its _id to its group
|
||||
// This panel can handle multiple groups
|
||||
eventBus.register($scope,"get_time", function(event,id) {
|
||||
eventBus.broadcast($scope.$id,id,'time',unmoment($scope.time))
|
||||
eventBus.broadcast($scope.$id,id,'time',compile_time($scope.time))
|
||||
});
|
||||
|
||||
// In case some other panel broadcasts a time, set us to an absolute range
|
||||
@ -208,13 +208,17 @@ angular.module('kibana.timepicker', [])
|
||||
// Get indices for the time period, then broadcast time range and index list
|
||||
// in a single object. Not sure if I like this.
|
||||
if($scope.panel.index_interval !== 'none') {
|
||||
indices($scope.time.from,$scope.time.to).then(function (p) {
|
||||
kbnIndex.indices($scope.time.from,
|
||||
$scope.time.to,
|
||||
$scope.panel.index,
|
||||
$scope.panel.index_interval
|
||||
).then(function (p) {
|
||||
$scope.time.index = p;
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'time',unmoment($scope.time))
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'time',compile_time($scope.time))
|
||||
});
|
||||
} else {
|
||||
$scope.time.index = [$scope.panel.index];
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'time',unmoment($scope.time))
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'time',compile_time($scope.time))
|
||||
}
|
||||
|
||||
// Update panel's string representation of the time object.Don't update if
|
||||
@ -233,10 +237,12 @@ angular.module('kibana.timepicker', [])
|
||||
|
||||
// Prefer to pass around Date() objects in the EventBus since interacting with
|
||||
// moment objects in libraries that are expecting Date()s can be tricky
|
||||
function unmoment(time) {
|
||||
function compile_time(time) {
|
||||
time = _.clone(time)
|
||||
time.from = time.from.toDate()
|
||||
time.to = time.to.toDate()
|
||||
time.interval = $scope.panel.index_interval
|
||||
time.pattern = $scope.panel.index
|
||||
return time;
|
||||
}
|
||||
|
||||
@ -254,81 +260,4 @@ angular.module('kibana.timepicker', [])
|
||||
}
|
||||
}
|
||||
|
||||
// returns a promise containing an array of all indices matching the index
|
||||
// pattern that exist in a given range
|
||||
function indices(from,to) {
|
||||
var possible = [];
|
||||
_.each(expand_range(fake_utc(from),fake_utc(to),$scope.panel.index_interval),function(d){
|
||||
possible.push(d.format($scope.panel.index));
|
||||
});
|
||||
|
||||
return all_indices().then(function(p) {
|
||||
var indices = _.intersection(possible,p);
|
||||
indices.reverse();
|
||||
return indices.length == 0 ? [$scope.panel.defaultindex] : indices;
|
||||
})
|
||||
};
|
||||
|
||||
// returns a promise containing an array of all indices in an elasticsearch
|
||||
// cluster
|
||||
function all_indices() {
|
||||
var something = $http({
|
||||
url: config.elasticsearch + "/_aliases",
|
||||
method: "GET"
|
||||
}).error(function(data, status, headers, config) {
|
||||
$scope.error = status;
|
||||
});
|
||||
|
||||
return something.then(function(p) {
|
||||
var indices = [];
|
||||
_.each(p.data, function(v,k) {
|
||||
indices.push(k)
|
||||
});
|
||||
return indices;
|
||||
});
|
||||
}
|
||||
|
||||
// this is stupid, but there is otherwise no good way to ensure that when
|
||||
// I extract the date from an object that I'm get the UTC date. Stupid js.
|
||||
// I die a little inside every time I call this function.
|
||||
// Update: I just read this again. I died a little more inside.
|
||||
// Update2: More death.
|
||||
function fake_utc(date) {
|
||||
date = date.clone().toDate()
|
||||
return moment(new Date(date.getTime() + date.getTimezoneOffset() * 60000));
|
||||
}
|
||||
|
||||
// Create an array of date objects by a given interval
|
||||
function expand_range(start, end, interval) {
|
||||
if(_.contains(['hour','day','week','month','year'],interval)) {
|
||||
var range;
|
||||
start = start.clone();
|
||||
range = [];
|
||||
while (start.isBefore(end)) {
|
||||
range.push(start.clone());
|
||||
switch (interval) {
|
||||
case 'hour':
|
||||
start.add('hours',1)
|
||||
break
|
||||
case 'day':
|
||||
start.add('days',1)
|
||||
break
|
||||
case 'week':
|
||||
start.add('weeks',1)
|
||||
break
|
||||
case 'month':
|
||||
start.add('months',1)
|
||||
break
|
||||
case 'year':
|
||||
start.add('years',1)
|
||||
break
|
||||
}
|
||||
}
|
||||
range.push(end.clone());
|
||||
return range;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
})
|
64
panels/trends/editor.html
Normal file
64
panels/trends/editor.html
Normal file
@ -0,0 +1,64 @@
|
||||
<div>
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
The trends panel will give you a percentage representation of how your query
|
||||
has moved in your current timespan compared a specified amount of time ago. For
|
||||
example, if the time is 1:10pm, your time picker was set to "Last 10m", and the
|
||||
"Time Ago" parameter was set to '1h', the panel would show how much the query
|
||||
results have changed since 12:00-12:10pm
|
||||
</div>
|
||||
</div>
|
||||
<h4>Settings</h4>
|
||||
<div class="row-fluid">
|
||||
<div class="span3" ng-hide='panel.auto_int'>
|
||||
<label class="small">Use Elasticsearch date math format here (eg 1m, 5m, 1d, 2w, 1y)</label>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<label class="small">Time Ago</label>
|
||||
<input type="text" class="input-small" ng-model="panel.ago">
|
||||
</div>
|
||||
<div class="span2">
|
||||
<label class="small">Font Size</label>
|
||||
<select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['7pt','8pt','9pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<label class="small" >List Format</label>
|
||||
<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">
|
||||
<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>
|
10
panels/trends/module.html
Normal file
10
panels/trends/module.html
Normal file
@ -0,0 +1,10 @@
|
||||
<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 data">
|
||||
<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>
|
||||
<br ng-show="panel.arrangement == 'vertical'">
|
||||
</div>
|
||||
</kibana-panel>
|
207
panels/trends/module.js
Normal file
207
panels/trends/module.js
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
|
||||
## Hits
|
||||
|
||||
A variety of representations of the hits a query matches
|
||||
|
||||
### Parameters
|
||||
* query :: An array of queries. No labels here, just an array of strings. Maybe
|
||||
there should be labels. Probably.
|
||||
* style :: A hash of css styles
|
||||
* arrangement :: How should I arrange the query results? 'horizontal' or 'vertical'
|
||||
* ago :: Date math formatted time to look back
|
||||
### Group Events
|
||||
#### Sends
|
||||
* get_time :: On panel initialization get time range to query
|
||||
#### Receives
|
||||
* time :: An object containing the time range to use and the index(es) to query
|
||||
* query :: An Array of queries, even if its only one
|
||||
|
||||
*/
|
||||
angular.module('kibana.trends', [])
|
||||
.controller('trends', function($scope, eventBus, kbnIndex) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
query : ["*"],
|
||||
group : "default",
|
||||
style : { "font-size": '14pt'},
|
||||
ago : '1d',
|
||||
arrangement : 'vertical',
|
||||
}
|
||||
_.defaults($scope.panel,_d)
|
||||
|
||||
$scope.init = function () {
|
||||
$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.get_data();
|
||||
});
|
||||
// Now that we're all setup, request the time from our group
|
||||
eventBus.broadcast($scope.$id,$scope.panel.group,'get_time')
|
||||
}
|
||||
|
||||
$scope.get_data = function(segment,query_id) {
|
||||
delete $scope.panel.error
|
||||
$scope.panel.loading = true;
|
||||
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.index) || _.isUndefined($scope.time))
|
||||
return
|
||||
|
||||
$scope.old_time = {
|
||||
from : new Date($scope.time.from.getTime() - interval_to_seconds($scope.panel.ago)*1000),
|
||||
to : new Date($scope.time.to.getTime() - interval_to_seconds($scope.panel.ago)*1000)
|
||||
}
|
||||
|
||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
||||
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 || '*'),
|
||||
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("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 || '*'),
|
||||
ejs.RangeFilter($scope.time.field)
|
||||
.from($scope.old_time.from)
|
||||
.to($scope.old_time.to))
|
||||
)
|
||||
});
|
||||
|
||||
// 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
|
||||
//$scope.populate_modal(request);
|
||||
|
||||
// If we're on the first segment we need to get our indices
|
||||
if (_segment == 0) {
|
||||
kbnIndex.indices(
|
||||
$scope.old_time.from,
|
||||
$scope.old_time.to,
|
||||
$scope.time.pattern,
|
||||
$scope.time.interval
|
||||
).then(function (p) {
|
||||
$scope.index = _.union(p,$scope.index);
|
||||
process_results(request.indices($scope.index[_segment]).doSearch());
|
||||
});
|
||||
} else {
|
||||
process_results(request.indices($scope.index[_segment]).doSearch());
|
||||
}
|
||||
|
||||
// Populate scope when we have results
|
||||
function process_results(results) {
|
||||
results.then(function(results) {
|
||||
|
||||
$scope.panel.loading = false;
|
||||
if(_segment == 0) {
|
||||
$scope.hits = {};
|
||||
$scope.data = [];
|
||||
query_id = $scope.query_id = new Date().getTime();
|
||||
}
|
||||
|
||||
// Check for error and abort if found
|
||||
if(!(_.isUndefined(results.error))) {
|
||||
$scope.panel.error = $scope.parse_error(results.error);
|
||||
return;
|
||||
}
|
||||
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
|
||||
|
||||
var hits = {
|
||||
new : _.isUndefined($scope.data[i]) || _segment == 0 ? n : $scope.data[i].hits.new+n,
|
||||
old : _.isUndefined($scope.data[i]) || _segment == 0 ? o : $scope.data[i].hits.old+o
|
||||
}
|
||||
|
||||
$scope.hits.new += n;
|
||||
$scope.hits.old += o;
|
||||
|
||||
var percent = Math.round(percentage(hits.old,hits.new)*100)/100
|
||||
// Create series
|
||||
$scope.data[i] = {
|
||||
label: $scope.panel.query[i].label || "query"+(parseInt(i)+1),
|
||||
hits: {
|
||||
new : hits.new,
|
||||
old : hits.old
|
||||
},
|
||||
percent: _.isNull(percent) ? 0 : percent
|
||||
};
|
||||
|
||||
i++;
|
||||
});
|
||||
$scope.$emit('render');
|
||||
if(_segment < $scope.index.length-1)
|
||||
$scope.get_data(_segment+1,query_id)
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function percentage(x,y) {
|
||||
return 100*(y-x)/x
|
||||
}
|
||||
|
||||
$scope.remove_query = function(q) {
|
||||
$scope.panel.query = _.without($scope.panel.query,q);
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
$scope.add_query = function(label,query) {
|
||||
$scope.panel.query.unshift({
|
||||
query: query,
|
||||
label: label,
|
||||
});
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
$scope.set_refresh = function (state) {
|
||||
$scope.refresh = state;
|
||||
}
|
||||
|
||||
$scope.close_edit = function() {
|
||||
if($scope.refresh)
|
||||
$scope.get_data();
|
||||
$scope.refresh = false;
|
||||
$scope.$emit('render');
|
||||
}
|
||||
|
||||
function set_time(time) {
|
||||
$scope.time = time;
|
||||
$scope.index = time.index || $scope.index
|
||||
$scope.get_data();
|
||||
}
|
||||
|
||||
})
|
Loading…
Reference in New Issue
Block a user