mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Linted, moved shared functions to kbn object
This commit is contained in:
parent
7c9f14ad5e
commit
5a3028f784
58
Gruntfile.js
Normal file
58
Gruntfile.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = function (grunt) {
|
||||||
|
|
||||||
|
var post = ['src/client.js','src/post.js'];
|
||||||
|
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
meta: {
|
||||||
|
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
|
||||||
|
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
|
||||||
|
'<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
|
||||||
|
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
|
||||||
|
' Licensed <%= pkg.license %> */\n\n'
|
||||||
|
},
|
||||||
|
jshint: {
|
||||||
|
files: ['Gruntfile.js', 'js/*.js', 'panels/*/*.js' ],
|
||||||
|
options: {
|
||||||
|
bitwise: true,
|
||||||
|
curly: true,
|
||||||
|
eqeqeq: true,
|
||||||
|
immed: true,
|
||||||
|
indent: 2,
|
||||||
|
latedef: true,
|
||||||
|
newcap: true,
|
||||||
|
noarg: true,
|
||||||
|
sub: true,
|
||||||
|
undef: true,
|
||||||
|
boss: true,
|
||||||
|
eqnull: true,
|
||||||
|
globalstrict: true,
|
||||||
|
devel: true,
|
||||||
|
node: true,
|
||||||
|
globals: {
|
||||||
|
'$LAB': false,
|
||||||
|
'_': false,
|
||||||
|
'$': false,
|
||||||
|
'kbn' : false,
|
||||||
|
window: false,
|
||||||
|
document: false,
|
||||||
|
exports: true,
|
||||||
|
module: false,
|
||||||
|
config: false,
|
||||||
|
moment: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// load plugins
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
|
|
||||||
|
|
||||||
|
// Default task.
|
||||||
|
grunt.registerTask('default', ['jshint']);
|
||||||
|
|
||||||
|
};
|
@ -1,13 +1,28 @@
|
|||||||
function get_object_fields(obj) {
|
// Wrap this all up in a 'kbn' object so I don't have a billion globals
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
// Save a reference to this
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// Save a reference to the old versionof this
|
||||||
|
var wasKbn = self.kbn;
|
||||||
|
|
||||||
|
// Create a safe refernce to the kbn object, for use below
|
||||||
|
var kbn = function(obj) { return new wrapper(obj); };
|
||||||
|
|
||||||
|
// Create a global object for accessing these functions
|
||||||
|
self.kbn = kbn;
|
||||||
|
|
||||||
|
kbn.get_object_fields = function(obj) {
|
||||||
var field_array = [];
|
var field_array = [];
|
||||||
obj = flatten_json(obj._source)
|
obj = kbn.flatten_json(obj._source)
|
||||||
for (field in obj) {
|
for (field in obj) {
|
||||||
field_array.push(field);
|
field_array.push(field);
|
||||||
}
|
}
|
||||||
return field_array.sort();
|
return field_array.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_all_fields(data) {
|
kbn.get_all_fields = function(data) {
|
||||||
var fields = [];
|
var fields = [];
|
||||||
_.each(data,function(hit) {
|
_.each(data,function(hit) {
|
||||||
fields = _.uniq(fields.concat(_.keys(hit)))
|
fields = _.uniq(fields.concat(_.keys(hit)))
|
||||||
@ -15,18 +30,18 @@ function get_all_fields(data) {
|
|||||||
// Remove stupid angular key
|
// Remove stupid angular key
|
||||||
fields = _.without(fields,'$$hashKey')
|
fields = _.without(fields,'$$hashKey')
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
function has_field(obj,field) {
|
kbn.has_field = function(obj,field) {
|
||||||
var obj_fields = get_object_fields(obj);
|
var obj_fields = get_object_fields(obj);
|
||||||
if (_.inArray(obj_fields,field) < 0) {
|
if (_.inArray(obj_fields,field) < 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_related_fields(docs,field) {
|
kbn.get_related_fields = function(docs,field) {
|
||||||
var field_array = []
|
var field_array = []
|
||||||
_.each(docs, function(doc) {
|
_.each(docs, function(doc) {
|
||||||
var keys = _.keys(doc)
|
var keys = _.keys(doc)
|
||||||
@ -35,9 +50,9 @@ function get_related_fields(docs,field) {
|
|||||||
})
|
})
|
||||||
var counts = _.countBy(_.without(field_array,field),function(field){return field;});
|
var counts = _.countBy(_.without(field_array,field),function(field){return field;});
|
||||||
return counts;
|
return counts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function recurse_field_dots(object,field) {
|
kbn.recurse_field_dots = function(object,field) {
|
||||||
var value = null;
|
var value = null;
|
||||||
if (typeof object[field] != 'undefined')
|
if (typeof object[field] != 'undefined')
|
||||||
value = object[field];
|
value = object[field];
|
||||||
@ -48,12 +63,12 @@ function recurse_field_dots(object,field) {
|
|||||||
object[nested[1]],nested[2]);
|
object[nested[1]],nested[2]);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probably useless now, leaving for cases where you might not want
|
// Probably useless now, leaving for cases where you might not want
|
||||||
// a flat dot notated data structure
|
// a flat dot notated data structure
|
||||||
function get_field_value(object,field,opt) {
|
kbn.get_field_value = function(object,field,opt) {
|
||||||
var value = recurse_field_dots(object['_source'],field);
|
var value = kbn.recurse_field_dots(object['_source'],field);
|
||||||
|
|
||||||
if(value === null)
|
if(value === null)
|
||||||
return ''
|
return ''
|
||||||
@ -79,26 +94,17 @@ function get_field_value(object,field,opt) {
|
|||||||
return JSON.stringify(value,null,4)
|
return JSON.stringify(value,null,4)
|
||||||
|
|
||||||
return (value != null) ? value.toString() : '';
|
return (value != null) ? value.toString() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function top_field_values(docs,field,count) {
|
kbn.top_field_values = function(docs,field,count) {
|
||||||
var counts = _.countBy(_.pluck(docs,field),function(field){
|
var counts = _.countBy(_.pluck(docs,field),function(field){
|
||||||
return _.isUndefined(field) ? '' : field;
|
return _.isUndefined(field) ? '' : field;
|
||||||
});
|
});
|
||||||
return _.pairs(counts).sort(function(a, b) {
|
return _.pairs(counts).sort(function(a, b) {
|
||||||
return a[1] - b[1]
|
return a[1] - b[1]
|
||||||
}).reverse().slice(0,count)
|
}).reverse().slice(0,count)
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_to_query(original,field,value,negate) {
|
|
||||||
var not = negate ? "-" : "";
|
|
||||||
if(value !== '')
|
|
||||||
var query = field + ":" + "\"" + addslashes(value.toString()) + "\"";
|
|
||||||
else
|
|
||||||
var query = "_missing_:" + field;
|
|
||||||
var glue = original != "" ? " AND " : "";
|
|
||||||
return original + glue + not + query;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Calculate a graph interval
|
* Calculate a graph interval
|
||||||
*
|
*
|
||||||
@ -108,19 +114,15 @@ function add_to_query(original,field,value,negate) {
|
|||||||
* user_interval:: User specified histogram interval
|
* user_interval:: User specified histogram interval
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function calculate_interval(from,to,size,user_interval) {
|
kbn.calculate_interval = function(from,to,size,user_interval) {
|
||||||
if(_.isObject(from))
|
if(_.isObject(from))
|
||||||
from = from.valueOf();
|
from = from.valueOf();
|
||||||
if(_.isObject(to))
|
if(_.isObject(to))
|
||||||
to = to.valueOf();
|
to = to.valueOf();
|
||||||
return user_interval == 0 ? round_interval((to - from)/size) : user_interval;
|
return user_interval == 0 ? kbn.round_interval((to - from)/size) : user_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_bar_count(from,to,interval) {
|
kbn.round_interval = function(interval) {
|
||||||
return (to - from)/interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
function round_interval (interval) {
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
// 0.5s
|
// 0.5s
|
||||||
case (interval <= 500): return 100; // 0.1s
|
case (interval <= 500): return 100; // 0.1s
|
||||||
@ -156,9 +158,9 @@ function round_interval (interval) {
|
|||||||
case (interval < 3628800000): return 2592000000; // 30d
|
case (interval < 3628800000): return 2592000000; // 30d
|
||||||
default: return 31536000000; // 1y
|
default: return 31536000000; // 1y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function secondsToHms(seconds){
|
kbn.secondsToHms = function(seconds){
|
||||||
var numyears = Math.floor(seconds / 31536000);
|
var numyears = Math.floor(seconds / 31536000);
|
||||||
if(numyears){
|
if(numyears){
|
||||||
return numyears + 'y';
|
return numyears + 'y';
|
||||||
@ -180,71 +182,22 @@ function secondsToHms(seconds){
|
|||||||
return numseconds + 's';
|
return numseconds + 's';
|
||||||
}
|
}
|
||||||
return 'less then a second'; //'just now' //or other string you like;
|
return 'less then a second'; //'just now' //or other string you like;
|
||||||
}
|
}
|
||||||
|
|
||||||
function to_percent(number,outof) {
|
kbn.to_percent = function(number,outof) {
|
||||||
return Math.round((number/outof)*10000)/100 + "%";
|
return Math.round((number/outof)*10000)/100 + "%";
|
||||||
}
|
}
|
||||||
|
|
||||||
function addslashes(str) {
|
kbn.addslashes = function(str) {
|
||||||
str = str.replace(/\\/g, '\\\\');
|
str = str.replace(/\\/g, '\\\\');
|
||||||
str = str.replace(/\'/g, '\\\'');
|
str = str.replace(/\'/g, '\\\'');
|
||||||
str = str.replace(/\"/g, '\\"');
|
str = str.replace(/\"/g, '\\"');
|
||||||
str = str.replace(/\0/g, '\\0');
|
str = str.replace(/\0/g, '\\0');
|
||||||
return str;
|
return str;
|
||||||
}
|
|
||||||
|
|
||||||
// Create an ISO8601 compliant timestamp for ES
|
|
||||||
//function ISODateString(unixtime) {
|
|
||||||
//var d = new Date(parseInt(unixtime));
|
|
||||||
function ISODateString(d) {
|
|
||||||
if(is_int(d)) {
|
|
||||||
d = new Date(parseInt(d));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pad(n) {
|
// histogram & trends
|
||||||
return n < 10 ? '0' + n : n
|
kbn.interval_to_seconds = function(string) {
|
||||||
}
|
|
||||||
return d.getFullYear() + '-' +
|
|
||||||
pad(d.getMonth() + 1) + '-' +
|
|
||||||
pad(d.getDate()) + 'T' +
|
|
||||||
pad(d.getHours()) + ':' +
|
|
||||||
pad(d.getMinutes()) + ':' +
|
|
||||||
pad(d.getSeconds());
|
|
||||||
}
|
|
||||||
|
|
||||||
function pickDateString(d) {
|
|
||||||
return dateFormat(d,'yyyy-mm-dd HH:MM:ss')
|
|
||||||
}
|
|
||||||
|
|
||||||
function prettyDateString(d) {
|
|
||||||
d = new Date(parseInt(d));
|
|
||||||
d = utc_date_obj(d);
|
|
||||||
return dateFormat(d,window.time_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
function utc_date_obj(d) {
|
|
||||||
return new Date(
|
|
||||||
d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(),
|
|
||||||
d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(),
|
|
||||||
d.getUTCMilliseconds());
|
|
||||||
}
|
|
||||||
|
|
||||||
function local_date_obj(d) {
|
|
||||||
return new Date(Date.UTC(
|
|
||||||
d.getFullYear(), d.getMonth(), d.getDate(),
|
|
||||||
d.getHours(), d.getMinutes(), d.getSeconds()));
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_int(value) {
|
|
||||||
if ((parseFloat(value) == parseInt(value)) && !isNaN(value)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function interval_to_seconds(string) {
|
|
||||||
var matches = string.match(/(\d+)([Mwdhmsy])/);
|
var matches = string.match(/(\d+)([Mwdhmsy])/);
|
||||||
switch (matches[2]) {
|
switch (matches[2]) {
|
||||||
case 'y': return matches[1]*31536000;;
|
case 'y': return matches[1]*31536000;;
|
||||||
@ -255,13 +208,15 @@ function interval_to_seconds(string) {
|
|||||||
case 'm': return matches[1]*60;;
|
case 'm': return matches[1]*60;;
|
||||||
case 's': return matches[1];
|
case 's': return matches[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function time_ago(string) {
|
// This should go away, moment.js can do this
|
||||||
return new Date(new Date().getTime() - (interval_to_seconds(string)*1000))
|
kbn.time_ago = function(string) {
|
||||||
}
|
return new Date(new Date().getTime() - (kbn.interval_to_seconds(string)*1000))
|
||||||
|
}
|
||||||
|
|
||||||
function flatten_json(object,root,array) {
|
// LOL. hahahahaha. DIE.
|
||||||
|
kbn.flatten_json = function(object,root,array) {
|
||||||
if (typeof array === 'undefined')
|
if (typeof array === 'undefined')
|
||||||
var array = {};
|
var array = {};
|
||||||
if (typeof root === 'undefined')
|
if (typeof root === 'undefined')
|
||||||
@ -287,16 +242,16 @@ function flatten_json(object,root,array) {
|
|||||||
array[rootname] = typeof obj === 'undefined' ? null : obj;
|
array[rootname] = typeof obj === 'undefined' ? null : obj;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
flatten_json(obj,rootname,array)
|
kbn.flatten_json(obj,rootname,array)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
array[rootname] = typeof obj === 'undefined' ? null : obj;
|
array[rootname] = typeof obj === 'undefined' ? null : obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sortObj(array);
|
return kbn.sortObj(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
function xmlEnt(value) {
|
kbn.xmlEnt = function(value) {
|
||||||
if(_.isString(value)) {
|
if(_.isString(value)) {
|
||||||
var stg1 = value.replace(/</g, '<')
|
var stg1 = value.replace(/</g, '<')
|
||||||
.replace(/>/g, '>')
|
.replace(/>/g, '>')
|
||||||
@ -307,13 +262,13 @@ function xmlEnt(value) {
|
|||||||
.replace(/ /g, ' ')
|
.replace(/ /g, ' ')
|
||||||
.replace(/<del>/g, '<del>')
|
.replace(/<del>/g, '<del>')
|
||||||
.replace(/<\/del>/g, '</del>');
|
.replace(/<\/del>/g, '</del>');
|
||||||
return stg1
|
return stg1;
|
||||||
} else {
|
} else {
|
||||||
return value
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function sortObj(arr) {
|
kbn.sortObj = function(arr) {
|
||||||
// Setup Arrays
|
// Setup Arrays
|
||||||
var sortedKeys = new Array();
|
var sortedKeys = new Array();
|
||||||
var sortedObj = {};
|
var sortedObj = {};
|
||||||
@ -329,84 +284,12 @@ function sortObj(arr) {
|
|||||||
sortedObj[sortedKeys[i]] = arr[sortedKeys[i]];
|
sortedObj[sortedKeys[i]] = arr[sortedKeys[i]];
|
||||||
}
|
}
|
||||||
return sortedObj;
|
return sortedObj;
|
||||||
}
|
}
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
// WTF. Has to be a better way to do this. Hi Tyler.
|
/*
|
||||||
function int_to_tz(offset) {
|
UNDERSCORE.js Mixins
|
||||||
var hour = offset / 1000 / 3600
|
*/
|
||||||
var str = ""
|
|
||||||
if (hour == 0) {
|
|
||||||
str = "+0000"
|
|
||||||
}
|
|
||||||
if (hour < 0) {
|
|
||||||
if (hour > -10)
|
|
||||||
str = "-0" + (hour * -100)
|
|
||||||
else
|
|
||||||
str = "-" + (hour * -100)
|
|
||||||
}
|
|
||||||
if (hour > 0) {
|
|
||||||
if (hour < 10)
|
|
||||||
str = "+0" + (hour * 100)
|
|
||||||
else
|
|
||||||
str = "+" + (hour * 100)
|
|
||||||
}
|
|
||||||
str = str.substring(0,3) + ":" + str.substring(3);
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets #hash, thus refreshing results
|
|
||||||
function setHash(json) {
|
|
||||||
window.location.hash = encodeURIComponent(Base64.encode(JSON.stringify(json)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add commas to numbers
|
|
||||||
function addCommas(nStr) {
|
|
||||||
nStr += '';
|
|
||||||
var x = nStr.split('.');
|
|
||||||
var x1 = x[0];
|
|
||||||
var x2 = x.length > 1 ? '.' + x[1] : '';
|
|
||||||
var rgx = /(\d+)(\d{3})/;
|
|
||||||
while (rgx.test(x1)) {
|
|
||||||
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
|
||||||
}
|
|
||||||
return x1 + x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split up log spaceless strings
|
|
||||||
// Str = string to split
|
|
||||||
// num = number of letters between <wbr> tags
|
|
||||||
function wbr(str, num) {
|
|
||||||
str = htmlEntities(str);
|
|
||||||
return str.replace(
|
|
||||||
RegExp("(@?\\w{" + num + "}|[:;,])([\\w\"'])([\\w@]*)", "g"),
|
|
||||||
function (all, text, char, trailer) {
|
|
||||||
if (/@KIBANA_\w+_(START|END)@/.test(all)) {
|
|
||||||
return text + char + trailer;
|
|
||||||
} else {
|
|
||||||
return text + "<del>​</del>" + char + trailer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function htmlEntities(str) {
|
|
||||||
return String(str).replace(
|
|
||||||
/&/g, '&').replace(
|
|
||||||
/</g, '<').replace(
|
|
||||||
/>/g, '>').replace(
|
|
||||||
/"/g, '"');
|
|
||||||
}
|
|
||||||
|
|
||||||
function bucket_round(start,num,dir) {
|
|
||||||
var resto = start%num;
|
|
||||||
if (resto <= (num/2) || dir === 'down') {
|
|
||||||
// Down
|
|
||||||
return start-resto;
|
|
||||||
} else {
|
|
||||||
// Up
|
|
||||||
return start+num-resto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_.mixin({
|
_.mixin({
|
||||||
move: function (array, fromIndex, toIndex) {
|
move: function (array, fromIndex, toIndex) {
|
||||||
|
@ -77,6 +77,6 @@ angular.module('kibana.directives', [])
|
|||||||
fn(scope, {$event:event});
|
fn(scope, {$event:event});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
@ -243,7 +243,8 @@ angular.module('kibana.services', [])
|
|||||||
query: '*',
|
query: '*',
|
||||||
alias: '',
|
alias: '',
|
||||||
color: colorAt(_id),
|
color: colorAt(_id),
|
||||||
id: _id
|
id: _id,
|
||||||
|
type: 'lucene'
|
||||||
};
|
};
|
||||||
_.defaults(query,_query);
|
_.defaults(query,_query);
|
||||||
self.list[_id] = query;
|
self.list[_id] = query;
|
||||||
@ -386,7 +387,7 @@ angular.module('kibana.services', [])
|
|||||||
.from(filter.from)
|
.from(filter.from)
|
||||||
.to(filter.to);
|
.to(filter.to);
|
||||||
case 'querystring':
|
case 'querystring':
|
||||||
return ejs.QueryFilter(ejs.QueryStringQuery(filter.query));
|
return ejs.QueryFilter(ejs.QueryStringQuery(filter.query)).cache(true);
|
||||||
case 'terms':
|
case 'terms':
|
||||||
return ejs.TermsFilter(filter.field,filter.value);
|
return ejs.TermsFilter(filter.field,filter.value);
|
||||||
case 'exists':
|
case 'exists':
|
||||||
|
14
package.json
Normal file
14
package.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"author": {
|
||||||
|
"name": "Rashid Khan",
|
||||||
|
"company": "Elasticsearch BV"
|
||||||
|
},
|
||||||
|
"name": "kibana",
|
||||||
|
"version": "3.0.0m3pre",
|
||||||
|
"devDependencies": {
|
||||||
|
"grunt": "~0.4.0",
|
||||||
|
"grunt-contrib": "~0.7.0",
|
||||||
|
"grunt-contrib-jshint": "~0.6.0"
|
||||||
|
},
|
||||||
|
"license": "Apache License"
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Derivequeries
|
## Derivequeries
|
||||||
@ -14,6 +16,8 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.derivequeries', [])
|
angular.module('kibana.derivequeries', [])
|
||||||
.controller('derivequeries', function($scope, $rootScope, query, fields, dashboard, filterSrv) {
|
.controller('derivequeries', function($scope, $rootScope, query, fields, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -33,19 +37,19 @@ angular.module('kibana.derivequeries', [])
|
|||||||
exclude : [],
|
exclude : [],
|
||||||
history : [],
|
history : [],
|
||||||
remember: 10 // max: 100, angular strap can't take a variable for items param
|
remember: 10 // max: 100, angular strap can't take a variable for items param
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d);
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.panel.fields = fields.list
|
$scope.panel.fields = fields.list;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.get_data = function() {
|
$scope.get_data = function() {
|
||||||
update_history($scope.panel.query);
|
update_history($scope.panel.query);
|
||||||
|
|
||||||
// Make sure we have everything for the request to complete
|
// Make sure we have everything for the request to complete
|
||||||
if(dashboard.indices.length == 0) {
|
if(dashboard.indices.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.panel.loading = true;
|
$scope.panel.loading = true;
|
||||||
@ -53,15 +57,15 @@ angular.module('kibana.derivequeries', [])
|
|||||||
|
|
||||||
// Terms mode
|
// Terms mode
|
||||||
request = request
|
request = request
|
||||||
.facet(ejs.TermsFacet('query')
|
.facet($scope.ejs.TermsFacet('query')
|
||||||
.field($scope.panel.field)
|
.field($scope.panel.field)
|
||||||
.size($scope.panel['size'])
|
.size($scope.panel.size)
|
||||||
.exclude($scope.panel.exclude)
|
.exclude($scope.panel.exclude)
|
||||||
.facetFilter(ejs.QueryFilter(
|
.facetFilter($scope.ejs.QueryFilter(
|
||||||
ejs.FilteredQuery(
|
$scope.ejs.FilteredQuery(
|
||||||
ejs.QueryStringQuery($scope.panel.query || '*'),
|
$scope.ejs.QueryStringQuery($scope.panel.query || '*'),
|
||||||
filterSrv.getBoolFilter(filterSrv.ids)
|
filterSrv.getBoolFilter(filterSrv.ids)
|
||||||
)))).size(0)
|
)))).size(0);
|
||||||
|
|
||||||
$scope.populate_modal(request);
|
$scope.populate_modal(request);
|
||||||
|
|
||||||
@ -70,19 +74,20 @@ angular.module('kibana.derivequeries', [])
|
|||||||
// Populate scope when we have results
|
// Populate scope when we have results
|
||||||
results.then(function(results) {
|
results.then(function(results) {
|
||||||
$scope.panel.loading = false;
|
$scope.panel.loading = false;
|
||||||
var data = [];
|
var suffix,
|
||||||
|
data = [];
|
||||||
if ($scope.panel.query === '' || $scope.panel.mode === 'terms only') {
|
if ($scope.panel.query === '' || $scope.panel.mode === 'terms only') {
|
||||||
var suffix = '';
|
suffix = '';
|
||||||
} else if ($scope.panel.mode === 'AND') {
|
} else if ($scope.panel.mode === 'AND') {
|
||||||
var suffix = ' AND (' + $scope.panel.query + ')';
|
suffix = ' AND (' + $scope.panel.query + ')';
|
||||||
} else if ($scope.panel.mode === 'OR') {
|
} else if ($scope.panel.mode === 'OR') {
|
||||||
var suffix = ' OR (' + $scope.panel.query + ')';
|
suffix = ' OR (' + $scope.panel.query + ')';
|
||||||
}
|
}
|
||||||
var ids = [];
|
var ids = [];
|
||||||
_.each(results.facets.query.terms, function(v) {
|
_.each(results.facets.query.terms, function(v) {
|
||||||
var _q = $scope.panel.field+':"'+v.term+'"'+suffix;
|
var _q = $scope.panel.field+':"'+v.term+'"'+suffix;
|
||||||
// if it isn't in the list, remove it
|
// if it isn't in the list, remove it
|
||||||
var _iq = query.findQuery(_q)
|
var _iq = query.findQuery(_q);
|
||||||
if(!_iq) {
|
if(!_iq) {
|
||||||
ids.push(query.set({query:_q}));
|
ids.push(query.set({query:_q}));
|
||||||
} else {
|
} else {
|
||||||
@ -90,22 +95,23 @@ angular.module('kibana.derivequeries', [])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
_.each(_.difference($scope.panel.ids,ids),function(id){
|
_.each(_.difference($scope.panel.ids,ids),function(id){
|
||||||
query.remove(id)
|
query.remove(id);
|
||||||
})
|
});
|
||||||
$scope.panel.ids = ids;
|
$scope.panel.ids = ids;
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_refresh = function (state) {
|
$scope.set_refresh = function (state) {
|
||||||
$scope.refresh = state;
|
$scope.refresh = state;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.close_edit = function() {
|
$scope.close_edit = function() {
|
||||||
if($scope.refresh)
|
if($scope.refresh) {
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
$scope.refresh = false;
|
|
||||||
}
|
}
|
||||||
|
$scope.refresh = false;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.populate_modal = function(request) {
|
$scope.populate_modal = function(request) {
|
||||||
$scope.modal = {
|
$scope.modal = {
|
||||||
@ -114,18 +120,18 @@ angular.module('kibana.derivequeries', [])
|
|||||||
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
||||||
angular.toJson(JSON.parse(request.toString()),true)+
|
angular.toJson(JSON.parse(request.toString()),true)+
|
||||||
"'</pre>",
|
"'</pre>",
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
var update_history = function(query) {
|
var update_history = function(query) {
|
||||||
query = _.isArray(query) ? query : [query];
|
query = _.isArray(query) ? query : [query];
|
||||||
if($scope.panel.remember > 0) {
|
if($scope.panel.remember > 0) {
|
||||||
$scope.panel.history = _.union(query.reverse(),$scope.panel.history)
|
$scope.panel.history = _.union(query.reverse(),$scope.panel.history);
|
||||||
var _length = $scope.panel.history.length
|
var _length = $scope.panel.history.length;
|
||||||
if(_length > $scope.panel.remember) {
|
if(_length > $scope.panel.remember) {
|
||||||
$scope.panel.history = $scope.panel.history.slice(0,$scope.panel.remember)
|
$scope.panel.history = $scope.panel.history.slice(0,$scope.panel.remember);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Fields
|
## Fields
|
||||||
@ -17,6 +20,9 @@
|
|||||||
* fields :: an object containing the sort order, existing fields and selected fields
|
* fields :: an object containing the sort order, existing fields and selected fields
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.fields', [])
|
angular.module('kibana.fields', [])
|
||||||
.controller('fields', function($scope, eventBus, $timeout, dashboard, query, filterSrv) {
|
.controller('fields', function($scope, eventBus, $timeout, dashboard, query, filterSrv) {
|
||||||
|
|
||||||
@ -27,7 +33,7 @@ angular.module('kibana.fields', [])
|
|||||||
style : {},
|
style : {},
|
||||||
arrange : 'vertical',
|
arrange : 'vertical',
|
||||||
micropanel_position : 'right',
|
micropanel_position : 'right',
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d);
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
@ -35,7 +41,7 @@ angular.module('kibana.fields', [])
|
|||||||
$scope.fields = [];
|
$scope.fields = [];
|
||||||
eventBus.register($scope,'fields', function(event, fields) {
|
eventBus.register($scope,'fields', function(event, fields) {
|
||||||
$scope.panel.sort = _.clone(fields.sort);
|
$scope.panel.sort = _.clone(fields.sort);
|
||||||
$scope.fields = fields.all,
|
$scope.fields = fields.all;
|
||||||
$scope.active = _.clone(fields.active);
|
$scope.active = _.clone(fields.active);
|
||||||
});
|
});
|
||||||
eventBus.register($scope,'table_documents', function(event, docs) {
|
eventBus.register($scope,'table_documents', function(event, docs) {
|
||||||
@ -46,57 +52,57 @@ angular.module('kibana.fields', [])
|
|||||||
eventBus.register($scope,"get_fields", function(event,id) {
|
eventBus.register($scope,"get_fields", function(event,id) {
|
||||||
eventBus.broadcast($scope.$id,$scope.panel.group,"selected_fields",$scope.active);
|
eventBus.broadcast($scope.$id,$scope.panel.group,"selected_fields",$scope.active);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.reload_list = function () {
|
$scope.reload_list = function () {
|
||||||
var temp = _.clone($scope.fields);
|
var temp = _.clone($scope.fields);
|
||||||
$scope.fields = []
|
$scope.fields = [];
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$scope.fields = temp;
|
$scope.fields = temp;
|
||||||
},10)
|
},10);
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.toggle_micropanel = function(field) {
|
$scope.toggle_micropanel = function(field) {
|
||||||
$scope.micropanel = {
|
$scope.micropanel = {
|
||||||
field: field,
|
field: field,
|
||||||
values : top_field_values($scope.docs,field,10),
|
values : kbn.top_field_values($scope.docs,field,10),
|
||||||
related : get_related_fields($scope.docs,field),
|
related : kbn.get_related_fields($scope.docs,field),
|
||||||
count: _.countBy($scope.docs,function(doc){
|
count: _.countBy($scope.docs,function(doc){return _.contains(_.keys(doc),field);})['true']
|
||||||
return _.contains(_.keys(doc),field)})['true'],
|
};
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
$scope.toggle_sort = function() {
|
$scope.toggle_sort = function() {
|
||||||
$scope.panel.sort[1] = $scope.panel.sort[1] == 'asc' ? 'desc' : 'asc';
|
$scope.panel.sort[1] = $scope.panel.sort[1] === 'asc' ? 'desc' : 'asc';
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.toggle_field = function(field) {
|
$scope.toggle_field = function(field) {
|
||||||
if (_.indexOf($scope.active,field) > -1)
|
if (_.indexOf($scope.active,field) > -1) {
|
||||||
$scope.active = _.without($scope.active,field)
|
$scope.active = _.without($scope.active,field);
|
||||||
else
|
} else {
|
||||||
$scope.active.push(field)
|
$scope.active.push(field);
|
||||||
eventBus.broadcast($scope.$id,$scope.panel.group,"selected_fields",$scope.active)
|
|
||||||
}
|
}
|
||||||
|
eventBus.broadcast($scope.$id,$scope.panel.group,"selected_fields",$scope.active);
|
||||||
|
};
|
||||||
|
|
||||||
$scope.build_search = function(field,value,mandate) {
|
$scope.build_search = function(field,value,mandate) {
|
||||||
var query;
|
var query;
|
||||||
if(_.isArray(value)) {
|
if(_.isArray(value)) {
|
||||||
query = field+":(" + _.map(value,function(v){return "\""+v+"\""}).join(",") + ")";
|
query = field+":(" + _.map(value,function(v){return "\""+v+"\"";}).join(",") + ")";
|
||||||
} else {
|
} else {
|
||||||
query = field+":"+angular.toJson(value);
|
query = field+":"+angular.toJson(value);
|
||||||
}
|
}
|
||||||
filterSrv.set({type:'querystring',query:query,mandate:mandate})
|
filterSrv.set({type:'querystring',query:query,mandate:mandate});
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.fieldExists = function(field,mandate) {
|
$scope.fieldExists = function(field,mandate) {
|
||||||
filterSrv.set({type:'exists',field:field,mandate:mandate})
|
filterSrv.set({type:'exists',field:field,mandate:mandate});
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.is_active = function(field) {
|
$scope.is_active = function(field) {
|
||||||
return _.indexOf($scope.active,field) > -1 ? ['label','label-info'] : '';
|
return _.indexOf($scope.active,field) > -1 ? ['label','label-info'] : '';
|
||||||
}
|
};
|
||||||
|
|
||||||
})
|
});
|
@ -1,3 +1,5 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## filtering
|
## filtering
|
||||||
@ -8,39 +10,41 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.filtering', [])
|
angular.module('kibana.filtering', [])
|
||||||
.controller('filtering', function($scope, filterSrv, $rootScope, dashboard) {
|
.controller('filtering', function($scope, filterSrv, $rootScope, dashboard) {
|
||||||
|
|
||||||
// Set and populate defaults
|
// Set and populate defaults
|
||||||
var _d = {
|
var _d = {
|
||||||
status : "Experimental"
|
status : "Experimental"
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d);
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.filterSrv = filterSrv
|
$scope.filterSrv = filterSrv;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.remove = function(id) {
|
$scope.remove = function(id) {
|
||||||
filterSrv.remove(id);
|
filterSrv.remove(id);
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.toggle = function(id) {
|
$scope.toggle = function(id) {
|
||||||
filterSrv.list[id].active = !filterSrv.list[id].active;
|
filterSrv.list[id].active = !filterSrv.list[id].active;
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.refresh = function(query) {
|
$scope.refresh = function(query) {
|
||||||
$rootScope.$broadcast('refresh')
|
$rootScope.$broadcast('refresh');
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.render = function(query) {
|
$scope.render = function(query) {
|
||||||
$rootScope.$broadcast('render')
|
$rootScope.$broadcast('render');
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.show_key = function(key) {
|
$scope.show_key = function(key) {
|
||||||
return !_.contains(['type','id','alias','mandate','active','editing'],key)
|
return !_.contains(['type','id','alias','mandate','active','editing'],key);
|
||||||
}
|
};
|
||||||
|
|
||||||
});
|
});
|
@ -1,3 +1,6 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Histogram
|
## Histogram
|
||||||
@ -35,6 +38,8 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.histogram', [])
|
angular.module('kibana.histogram', [])
|
||||||
.controller('histogram', function($scope, eventBus, query, dashboard, filterSrv) {
|
.controller('histogram', function($scope, eventBus, query, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -63,8 +68,8 @@ angular.module('kibana.histogram', [])
|
|||||||
'y-axis' : true,
|
'y-axis' : true,
|
||||||
percentage : false,
|
percentage : false,
|
||||||
interactive : true,
|
interactive : true,
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d)
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
|
|
||||||
@ -72,49 +77,51 @@ angular.module('kibana.histogram', [])
|
|||||||
|
|
||||||
$scope.$on('refresh',function(){
|
$scope.$on('refresh',function(){
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
})
|
});
|
||||||
|
|
||||||
$scope.get_data()
|
$scope.get_data();
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.get_data = function(segment,query_id) {
|
$scope.get_data = function(segment,query_id) {
|
||||||
delete $scope.panel.error
|
delete $scope.panel.error;
|
||||||
|
|
||||||
// Make sure we have everything for the request to complete
|
// Make sure we have everything for the request to complete
|
||||||
if(dashboard.indices.length == 0) {
|
if(dashboard.indices.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _range = $scope.range = filterSrv.timeRange('min');
|
var _range = $scope.range = filterSrv.timeRange('min');
|
||||||
|
|
||||||
if ($scope.panel.auto_int)
|
if ($scope.panel.auto_int) {
|
||||||
$scope.panel.interval = secondsToHms(calculate_interval(_range.from,_range.to,$scope.panel.resolution,0)/1000);
|
$scope.panel.interval = kbn.secondsToHms(
|
||||||
|
kbn.calculate_interval(_range.from,_range.to,$scope.panel.resolution,0)/1000);
|
||||||
|
}
|
||||||
|
|
||||||
$scope.panel.loading = true;
|
$scope.panel.loading = true;
|
||||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
var _segment = _.isUndefined(segment) ? 0 : segment;
|
||||||
var request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
|
var request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
|
||||||
|
|
||||||
// Build the query
|
// Build the query
|
||||||
_.each($scope.queries.ids, function(id) {
|
_.each($scope.queries.ids, function(id) {
|
||||||
var query = $scope.ejs.FilteredQuery(
|
var query = $scope.ejs.FilteredQuery(
|
||||||
ejs.QueryStringQuery($scope.queries.list[id].query || '*'),
|
$scope.ejs.QueryStringQuery($scope.queries.list[id].query || '*'),
|
||||||
filterSrv.getBoolFilter(filterSrv.ids)
|
filterSrv.getBoolFilter(filterSrv.ids)
|
||||||
)
|
);
|
||||||
|
|
||||||
var facet = $scope.ejs.DateHistogramFacet(id)
|
var facet = $scope.ejs.DateHistogramFacet(id);
|
||||||
|
|
||||||
if($scope.panel.mode === 'count') {
|
if($scope.panel.mode === 'count') {
|
||||||
facet = facet.field($scope.panel.time_field)
|
facet = facet.field($scope.panel.time_field);
|
||||||
} else {
|
} else {
|
||||||
if(_.isNull($scope.panel.value_field)) {
|
if(_.isNull($scope.panel.value_field)) {
|
||||||
$scope.panel.error = "In " + $scope.panel.mode + " mode a field must be specified";
|
$scope.panel.error = "In " + $scope.panel.mode + " mode a field must be specified";
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
facet = facet.keyField($scope.panel.time_field).valueField($scope.panel.value_field)
|
facet = facet.keyField($scope.panel.time_field).valueField($scope.panel.value_field);
|
||||||
}
|
}
|
||||||
facet = facet.interval($scope.panel.interval).facetFilter($scope.ejs.QueryFilter(query))
|
facet = facet.interval($scope.panel.interval).facetFilter($scope.ejs.QueryFilter(query));
|
||||||
request = request.facet(facet).size(0)
|
request = request.facet(facet).size(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Populate the inspector panel
|
// Populate the inspector panel
|
||||||
@ -127,7 +134,7 @@ angular.module('kibana.histogram', [])
|
|||||||
results.then(function(results) {
|
results.then(function(results) {
|
||||||
|
|
||||||
$scope.panel.loading = false;
|
$scope.panel.loading = false;
|
||||||
if(_segment == 0) {
|
if(_segment === 0) {
|
||||||
$scope.hits = 0;
|
$scope.hits = 0;
|
||||||
$scope.data = [];
|
$scope.data = [];
|
||||||
query_id = $scope.query_id = new Date().getTime();
|
query_id = $scope.query_id = new Date().getTime();
|
||||||
@ -140,37 +147,39 @@ angular.module('kibana.histogram', [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert facet ids to numbers
|
// Convert facet ids to numbers
|
||||||
var facetIds = _.map(_.keys(results.facets),function(k){return parseInt(k);})
|
var facetIds = _.map(_.keys(results.facets),function(k){return parseInt(k, 10);});
|
||||||
|
|
||||||
// Make sure we're still on the same query/queries
|
// Make sure we're still on the same query/queries
|
||||||
if($scope.query_id === query_id &&
|
if($scope.query_id === query_id &&
|
||||||
_.intersection(facetIds,query.ids).length == query.ids.length
|
_.intersection(facetIds,query.ids).length === query.ids.length
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
var data, hits;
|
||||||
|
|
||||||
_.each(query.ids, function(id) {
|
_.each(query.ids, function(id) {
|
||||||
var v = results.facets[id];
|
var v = results.facets[id];
|
||||||
|
|
||||||
// Null values at each end of the time range ensure we see entire range
|
// Null values at each end of the time range ensure we see entire range
|
||||||
if(_.isUndefined($scope.data[i]) || _segment == 0) {
|
if(_.isUndefined($scope.data[i]) || _segment === 0) {
|
||||||
var data = []
|
data = [];
|
||||||
if(filterSrv.idsByType('time').length > 0) {
|
if(filterSrv.idsByType('time').length > 0) {
|
||||||
data = [[_range.from.getTime(), null],[_range.to.getTime(), null]];
|
data = [[_range.from.getTime(), null],[_range.to.getTime(), null]];
|
||||||
}
|
}
|
||||||
var hits = 0;
|
hits = 0;
|
||||||
} else {
|
} else {
|
||||||
var data = $scope.data[i].data
|
data = $scope.data[i].data;
|
||||||
var hits = $scope.data[i].hits
|
hits = $scope.data[i].hits;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assemble segments
|
// Assemble segments
|
||||||
var segment_data = [];
|
var segment_data = [];
|
||||||
_.each(v.entries, function(v, k) {
|
_.each(v.entries, function(v, k) {
|
||||||
segment_data.push([v['time'],v[$scope.panel.mode]])
|
segment_data.push([v.time,v[$scope.panel.mode]]);
|
||||||
hits += v['count']; // The series level hits counter
|
hits += v.count; // The series level hits counter
|
||||||
$scope.hits += v['count']; // Entire dataset level hits counter
|
$scope.hits += v.count; // Entire dataset level hits counter
|
||||||
});
|
});
|
||||||
data.splice.apply(data,[1,0].concat(segment_data)) // Join histogram data
|
data.splice.apply(data,[1,0].concat(segment_data)); // Join histogram data
|
||||||
|
|
||||||
// Create the flot series object
|
// Create the flot series object
|
||||||
var series = {
|
var series = {
|
||||||
@ -181,22 +190,22 @@ angular.module('kibana.histogram', [])
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.data[i] = series.data
|
$scope.data[i] = series.data;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Tell the histogram directive to render.
|
// Tell the histogram directive to render.
|
||||||
$scope.$emit('render')
|
$scope.$emit('render');
|
||||||
|
|
||||||
// If we still have segments left, get them
|
// If we still have segments left, get them
|
||||||
if(_segment < dashboard.indices.length-1) {
|
if(_segment < dashboard.indices.length-1) {
|
||||||
$scope.get_data(_segment+1,query_id)
|
$scope.get_data(_segment+1,query_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// function $scope.zoom
|
// function $scope.zoom
|
||||||
// factor :: Zoom factor, so 0.5 = cuts timespan in half, 2 doubles timespan
|
// factor :: Zoom factor, so 0.5 = cuts timespan in half, 2 doubles timespan
|
||||||
@ -204,31 +213,31 @@ angular.module('kibana.histogram', [])
|
|||||||
var _now = Date.now();
|
var _now = Date.now();
|
||||||
var _range = filterSrv.timeRange('min');
|
var _range = filterSrv.timeRange('min');
|
||||||
var _timespan = (_range.to.valueOf() - _range.from.valueOf());
|
var _timespan = (_range.to.valueOf() - _range.from.valueOf());
|
||||||
var _center = _range.to.valueOf() - _timespan/2
|
var _center = _range.to.valueOf() - _timespan/2;
|
||||||
|
|
||||||
var _to = (_center + (_timespan*factor)/2)
|
var _to = (_center + (_timespan*factor)/2);
|
||||||
var _from = (_center - (_timespan*factor)/2)
|
var _from = (_center - (_timespan*factor)/2);
|
||||||
|
|
||||||
// If we're not already looking into the future, don't.
|
// If we're not already looking into the future, don't.
|
||||||
if(_to > Date.now() && _range.to < Date.now()) {
|
if(_to > Date.now() && _range.to < Date.now()) {
|
||||||
var _offset = _to - Date.now()
|
var _offset = _to - Date.now();
|
||||||
_from = _from - _offset
|
_from = _from - _offset;
|
||||||
_to = Date.now();
|
_to = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(factor > 1) {
|
if(factor > 1) {
|
||||||
filterSrv.removeByType('time')
|
filterSrv.removeByType('time');
|
||||||
}
|
}
|
||||||
filterSrv.set({
|
filterSrv.set({
|
||||||
type:'time',
|
type:'time',
|
||||||
from:moment.utc(_from),
|
from:moment.utc(_from),
|
||||||
to:moment.utc(_to),
|
to:moment.utc(_to),
|
||||||
field:$scope.panel.time_field
|
field:$scope.panel.time_field
|
||||||
})
|
});
|
||||||
|
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
// I really don't like this function, too much dom manip. Break out into directive?
|
// I really don't like this function, too much dom manip. Break out into directive?
|
||||||
$scope.populate_modal = function(request) {
|
$scope.populate_modal = function(request) {
|
||||||
@ -238,19 +247,20 @@ angular.module('kibana.histogram', [])
|
|||||||
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
||||||
angular.toJson(JSON.parse(request.toString()),true)+
|
angular.toJson(JSON.parse(request.toString()),true)+
|
||||||
"'</pre>",
|
"'</pre>",
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_refresh = function (state) {
|
$scope.set_refresh = function (state) {
|
||||||
$scope.refresh = state;
|
$scope.refresh = state;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.close_edit = function() {
|
$scope.close_edit = function() {
|
||||||
if($scope.refresh)
|
if($scope.refresh) {
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
|
}
|
||||||
$scope.refresh = false;
|
$scope.refresh = false;
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
}
|
};
|
||||||
|
|
||||||
})
|
})
|
||||||
.directive('histogramChart', function(dashboard, eventBus, filterSrv, $rootScope) {
|
.directive('histogramChart', function(dashboard, eventBus, filterSrv, $rootScope) {
|
||||||
@ -274,19 +284,19 @@ angular.module('kibana.histogram', [])
|
|||||||
// Populate from the query service
|
// Populate from the query service
|
||||||
try {
|
try {
|
||||||
_.each(scope.data,function(series) {
|
_.each(scope.data,function(series) {
|
||||||
series.label = series.info.alias,
|
series.label = series.info.alias;
|
||||||
series.color = series.info.color
|
series.color = series.info.color;
|
||||||
})
|
});
|
||||||
} catch(e) {return}
|
} catch(e) {return;}
|
||||||
|
|
||||||
// Set barwidth based on specified interval
|
// Set barwidth based on specified interval
|
||||||
var barwidth = interval_to_seconds(scope.panel.interval)*1000
|
var barwidth = kbn.interval_to_seconds(scope.panel.interval)*1000;
|
||||||
|
|
||||||
var scripts = $LAB.script("common/lib/panels/jquery.flot.js").wait()
|
var scripts = $LAB.script("common/lib/panels/jquery.flot.js").wait()
|
||||||
.script("common/lib/panels/jquery.flot.time.js")
|
.script("common/lib/panels/jquery.flot.time.js")
|
||||||
.script("common/lib/panels/jquery.flot.stack.js")
|
.script("common/lib/panels/jquery.flot.stack.js")
|
||||||
.script("common/lib/panels/jquery.flot.selection.js")
|
.script("common/lib/panels/jquery.flot.selection.js")
|
||||||
.script("common/lib/panels/timezone.js")
|
.script("common/lib/panels/timezone.js");
|
||||||
|
|
||||||
// Populate element. Note that jvectormap appends, does not replace.
|
// Populate element. Note that jvectormap appends, does not replace.
|
||||||
scripts.wait(function(){
|
scripts.wait(function(){
|
||||||
@ -331,33 +341,38 @@ angular.module('kibana.histogram', [])
|
|||||||
hoverable: true,
|
hoverable: true,
|
||||||
},
|
},
|
||||||
colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
|
colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
|
||||||
|
};
|
||||||
|
|
||||||
|
if(scope.panel.interactive) {
|
||||||
|
options.selection = { mode: "x", color: '#aaa' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scope.panel.interactive)
|
scope.plot = $.plot(elem, scope.data, options);
|
||||||
options.selection = { mode: "x", color: '#aaa' };
|
|
||||||
|
|
||||||
scope.plot = $.plot(elem, scope.data, options)
|
// Work around for missing legend at initialization.
|
||||||
|
if(!scope.$$phase) {
|
||||||
// Work around for missing legend at initialization
|
scope.$apply();
|
||||||
if(!scope.$$phase)
|
}
|
||||||
scope.$apply()
|
|
||||||
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
elem.text(e)
|
elem.text(e);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function time_format(interval) {
|
function time_format(interval) {
|
||||||
var _int = interval_to_seconds(interval)
|
var _int = kbn.interval_to_seconds(interval);
|
||||||
if(_int >= 2628000)
|
if(_int >= 2628000) {
|
||||||
return "%m/%y"
|
return "%m/%y";
|
||||||
if(_int >= 86400)
|
}
|
||||||
return "%m/%d/%y"
|
if(_int >= 86400) {
|
||||||
if(_int >= 60)
|
return "%m/%d/%y";
|
||||||
return "%H:%M<br>%m/%d"
|
}
|
||||||
else
|
if(_int >= 60) {
|
||||||
return "%H:%M:%S"
|
return "%H:%M<br>%m/%d";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "%H:%M:%S";
|
||||||
}
|
}
|
||||||
|
|
||||||
function tt(x, y, contents) {
|
function tt(x, y, contents) {
|
||||||
@ -396,9 +411,9 @@ angular.module('kibana.histogram', [])
|
|||||||
from : moment.utc(ranges.xaxis.from),
|
from : moment.utc(ranges.xaxis.from),
|
||||||
to : moment.utc(ranges.xaxis.to),
|
to : moment.utc(ranges.xaxis.to),
|
||||||
field : scope.panel.time_field
|
field : scope.panel.time_field
|
||||||
})
|
});
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
});
|
@ -1,3 +1,6 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Hits
|
## Hits
|
||||||
@ -15,6 +18,9 @@
|
|||||||
* lables :: Only 'pie' charts. Labels on the pie?
|
* lables :: Only 'pie' charts. Labels on the pie?
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.hits', [])
|
angular.module('kibana.hits', [])
|
||||||
.controller('hits', function($scope, query, dashboard, filterSrv) {
|
.controller('hits', function($scope, query, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -30,41 +36,41 @@ angular.module('kibana.hits', [])
|
|||||||
donut : false,
|
donut : false,
|
||||||
tilt : false,
|
tilt : false,
|
||||||
labels : true
|
labels : true
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d)
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function () {
|
$scope.init = function () {
|
||||||
$scope.hits = 0;
|
$scope.hits = 0;
|
||||||
|
|
||||||
$scope.$on('refresh',function(){
|
$scope.$on('refresh',function(){
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
})
|
});
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.get_data = function(segment,query_id) {
|
$scope.get_data = function(segment,query_id) {
|
||||||
delete $scope.panel.error
|
delete $scope.panel.error;
|
||||||
$scope.panel.loading = true;
|
$scope.panel.loading = true;
|
||||||
|
|
||||||
// Make sure we have everything for the request to complete
|
// Make sure we have everything for the request to complete
|
||||||
if(dashboard.indices.length == 0) {
|
if(dashboard.indices.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
var _segment = _.isUndefined(segment) ? 0 : segment;
|
||||||
var request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
|
var request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
|
||||||
|
|
||||||
// Build the question part of the query
|
// Build the question part of the query
|
||||||
_.each(query.ids, function(id) {
|
_.each(query.ids, function(id) {
|
||||||
var _q = $scope.ejs.FilteredQuery(
|
var _q = $scope.ejs.FilteredQuery(
|
||||||
ejs.QueryStringQuery(query.list[id].query || '*'),
|
$scope.ejs.QueryStringQuery(query.list[id].query || '*'),
|
||||||
filterSrv.getBoolFilter(filterSrv.ids));
|
filterSrv.getBoolFilter(filterSrv.ids));
|
||||||
|
|
||||||
request = request
|
request = request
|
||||||
.facet($scope.ejs.QueryFacet(id)
|
.facet($scope.ejs.QueryFacet(id)
|
||||||
.query(_q)
|
.query(_q)
|
||||||
).size(0)
|
).size(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Spy for hits panel
|
// TODO: Spy for hits panel
|
||||||
@ -76,7 +82,7 @@ angular.module('kibana.hits', [])
|
|||||||
// Populate scope when we have results
|
// Populate scope when we have results
|
||||||
results.then(function(results) {
|
results.then(function(results) {
|
||||||
$scope.panel.loading = false;
|
$scope.panel.loading = false;
|
||||||
if(_segment == 0) {
|
if(_segment === 0) {
|
||||||
$scope.hits = 0;
|
$scope.hits = 0;
|
||||||
$scope.data = [];
|
$scope.data = [];
|
||||||
query_id = $scope.query_id = new Date().getTime();
|
query_id = $scope.query_id = new Date().getTime();
|
||||||
@ -89,18 +95,18 @@ angular.module('kibana.hits', [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert facet ids to numbers
|
// Convert facet ids to numbers
|
||||||
var facetIds = _.map(_.keys(results.facets),function(k){return parseInt(k);})
|
var facetIds = _.map(_.keys(results.facets),function(k){return parseInt(k, 10);});
|
||||||
|
|
||||||
// Make sure we're still on the same query/queries
|
// Make sure we're still on the same query/queries
|
||||||
if($scope.query_id === query_id &&
|
if($scope.query_id === query_id &&
|
||||||
_.intersection(facetIds,query.ids).length == query.ids.length
|
_.intersection(facetIds,query.ids).length === query.ids.length
|
||||||
) {
|
) {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
_.each(query.ids, function(id) {
|
_.each(query.ids, function(id) {
|
||||||
var v = results.facets[id]
|
var v = results.facets[id];
|
||||||
var hits = _.isUndefined($scope.data[i]) || _segment == 0 ?
|
var hits = _.isUndefined($scope.data[i]) || _segment === 0 ?
|
||||||
v.count : $scope.data[i].hits+v.count
|
v.count : $scope.data[i].hits+v.count;
|
||||||
$scope.hits += v.count
|
$scope.hits += v.count;
|
||||||
|
|
||||||
// Create series
|
// Create series
|
||||||
$scope.data[i] = {
|
$scope.data[i] = {
|
||||||
@ -113,23 +119,25 @@ angular.module('kibana.hits', [])
|
|||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
if(_segment < dashboard.indices.length-1)
|
if(_segment < dashboard.indices.length-1) {
|
||||||
$scope.get_data(_segment+1,query_id)
|
$scope.get_data(_segment+1,query_id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_refresh = function (state) {
|
$scope.set_refresh = function (state) {
|
||||||
$scope.refresh = state;
|
$scope.refresh = state;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.close_edit = function() {
|
$scope.close_edit = function() {
|
||||||
if($scope.refresh)
|
if($scope.refresh) {
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
|
}
|
||||||
$scope.refresh = false;
|
$scope.refresh = false;
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
}
|
};
|
||||||
|
|
||||||
function set_time(time) {
|
function set_time(time) {
|
||||||
$scope.time = time;
|
$scope.time = time;
|
||||||
@ -156,20 +164,20 @@ angular.module('kibana.hits', [])
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
_.each(scope.data,function(series) {
|
_.each(scope.data,function(series) {
|
||||||
series.label = series.info.alias,
|
series.label = series.info.alias;
|
||||||
series.color = series.info.color
|
series.color = series.info.color;
|
||||||
})
|
});
|
||||||
} catch(e) {return}
|
} catch(e) {return;}
|
||||||
|
|
||||||
var scripts = $LAB.script("common/lib/panels/jquery.flot.js").wait()
|
var scripts = $LAB.script("common/lib/panels/jquery.flot.js").wait()
|
||||||
.script("common/lib/panels/jquery.flot.pie.js")
|
.script("common/lib/panels/jquery.flot.pie.js");
|
||||||
|
|
||||||
// Populate element.
|
// Populate element.
|
||||||
scripts.wait(function(){
|
scripts.wait(function(){
|
||||||
// Populate element
|
// Populate element
|
||||||
try {
|
try {
|
||||||
// Add plot to scope so we can build out own legend
|
// Add plot to scope so we can build out own legend
|
||||||
if(scope.panel.chart === 'bar')
|
if(scope.panel.chart === 'bar') {
|
||||||
scope.plot = $.plot(elem, scope.data, {
|
scope.plot = $.plot(elem, scope.data, {
|
||||||
legend: { show: false },
|
legend: { show: false },
|
||||||
series: {
|
series: {
|
||||||
@ -186,8 +194,9 @@ angular.module('kibana.hits', [])
|
|||||||
hoverable: true,
|
hoverable: true,
|
||||||
},
|
},
|
||||||
colors: query.colors
|
colors: query.colors
|
||||||
})
|
});
|
||||||
if(scope.panel.chart === 'pie')
|
}
|
||||||
|
if(scope.panel.chart === 'pie') {
|
||||||
scope.plot = $.plot(elem, scope.data, {
|
scope.plot = $.plot(elem, scope.data, {
|
||||||
legend: { show: false },
|
legend: { show: false },
|
||||||
series: {
|
series: {
|
||||||
@ -218,19 +227,20 @@ angular.module('kibana.hits', [])
|
|||||||
grid: { hoverable: true, clickable: true },
|
grid: { hoverable: true, clickable: true },
|
||||||
colors: query.colors
|
colors: query.colors
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// Compensate for the height of the legend. Gross
|
// Compensate for the height of the legend. Gross
|
||||||
elem.height(
|
elem.height(
|
||||||
(scope.panel.height || scope.row.height).replace('px','') - $("#"+scope.$id+"-legend").height())
|
(scope.panel.height || scope.row.height).replace('px','') - $("#"+scope.$id+"-legend").height());
|
||||||
|
|
||||||
// Work around for missing legend at initialization
|
// Work around for missing legend at initialization
|
||||||
if(!scope.$$phase)
|
if(!scope.$$phase) {
|
||||||
scope.$apply()
|
scope.$apply();
|
||||||
|
}
|
||||||
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
elem.text(e)
|
elem.text(e);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function tt(x, y, contents) {
|
function tt(x, y, contents) {
|
||||||
@ -256,7 +266,7 @@ angular.module('kibana.hits', [])
|
|||||||
item.datapoint[1] : item.datapoint[1][0][1];
|
item.datapoint[1] : item.datapoint[1][0][1];
|
||||||
tt(pos.pageX, pos.pageY,
|
tt(pos.pageX, pos.pageY,
|
||||||
"<div style='vertical-align:middle;border-radius:10px;display:inline-block;background:"+
|
"<div style='vertical-align:middle;border-radius:10px;display:inline-block;background:"+
|
||||||
item.series.color+";height:20px;width:20px'></div> "+value.toFixed(0))
|
item.series.color+";height:20px;width:20px'></div> "+value.toFixed(0));
|
||||||
} else {
|
} else {
|
||||||
$("#pie-tooltip").remove();
|
$("#pie-tooltip").remove();
|
||||||
}
|
}
|
||||||
@ -264,4 +274,4 @@ angular.module('kibana.hits', [])
|
|||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
});
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Map
|
## Map
|
||||||
@ -22,6 +25,8 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.map', [])
|
angular.module('kibana.map', [])
|
||||||
.controller('map', function($scope, $rootScope, query, dashboard, filterSrv) {
|
.controller('map', function($scope, $rootScope, query, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -36,37 +41,39 @@ angular.module('kibana.map', [])
|
|||||||
spyable : true,
|
spyable : true,
|
||||||
group : "default",
|
group : "default",
|
||||||
index_limit : 0
|
index_limit : 0
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d)
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.$on('refresh',function(){$scope.get_data()})
|
$scope.$on('refresh',function(){$scope.get_data();});
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.get_data = function() {
|
$scope.get_data = function() {
|
||||||
|
|
||||||
// Make sure we have everything for the request to complete
|
// Make sure we have everything for the request to complete
|
||||||
if(dashboard.indices.length == 0) {
|
if(dashboard.indices.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.panel.loading = true;
|
$scope.panel.loading = true;
|
||||||
var request = $scope.ejs.Request().indices(dashboard.indices);
|
|
||||||
|
|
||||||
var boolQuery = ejs.BoolQuery();
|
|
||||||
|
var request;
|
||||||
|
request = $scope.ejs.Request().indices(dashboard.indices);
|
||||||
|
|
||||||
|
var boolQuery = $scope.ejs.BoolQuery();
|
||||||
_.each(query.list,function(q) {
|
_.each(query.list,function(q) {
|
||||||
boolQuery = boolQuery.should(ejs.QueryStringQuery(q.query || '*'))
|
boolQuery = boolQuery.should($scope.ejs.QueryStringQuery(q.query || '*'));
|
||||||
})
|
});
|
||||||
|
|
||||||
// Then the insert into facet and make the request
|
// Then the insert into facet and make the request
|
||||||
var request = request
|
request = request
|
||||||
.facet(ejs.TermsFacet('map')
|
.facet($scope.ejs.TermsFacet('map')
|
||||||
.field($scope.panel.field)
|
.field($scope.panel.field)
|
||||||
.size($scope.panel['size'])
|
.size($scope.panel.size)
|
||||||
.exclude($scope.panel.exclude)
|
.exclude($scope.panel.exclude)
|
||||||
.facetFilter(ejs.QueryFilter(
|
.facetFilter($scope.ejs.QueryFilter(
|
||||||
ejs.FilteredQuery(
|
$scope.ejs.FilteredQuery(
|
||||||
boolQuery,
|
boolQuery,
|
||||||
filterSrv.getBoolFilter(filterSrv.ids)
|
filterSrv.getBoolFilter(filterSrv.ids)
|
||||||
)))).size(0);
|
)))).size(0);
|
||||||
@ -83,9 +90,9 @@ angular.module('kibana.map', [])
|
|||||||
_.each(results.facets.map.terms, function(v) {
|
_.each(results.facets.map.terms, function(v) {
|
||||||
$scope.data[v.term.toUpperCase()] = v.count;
|
$scope.data[v.term.toUpperCase()] = v.count;
|
||||||
});
|
});
|
||||||
$scope.$emit('render')
|
$scope.$emit('render');
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// I really don't like this function, too much dom manip. Break out into directive?
|
// I really don't like this function, too much dom manip. Break out into directive?
|
||||||
$scope.populate_modal = function(request) {
|
$scope.populate_modal = function(request) {
|
||||||
@ -95,13 +102,13 @@ angular.module('kibana.map', [])
|
|||||||
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
||||||
angular.toJson(JSON.parse(request.toString()),true)+
|
angular.toJson(JSON.parse(request.toString()),true)+
|
||||||
"'</pre>",
|
"'</pre>",
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.build_search = function(field,value) {
|
$scope.build_search = function(field,value) {
|
||||||
filterSrv.set({type:'querystring',mandate:'must',query:field+":"+value})
|
filterSrv.set({type:'querystring',mandate:'must',query:field+":"+value});
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
}
|
};
|
||||||
|
|
||||||
})
|
})
|
||||||
.directive('map', function() {
|
.directive('map', function() {
|
||||||
@ -109,7 +116,7 @@ angular.module('kibana.map', [])
|
|||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
link: function(scope, elem, attrs) {
|
link: function(scope, elem, attrs) {
|
||||||
|
|
||||||
elem.html('<center><img src="common/img/load_big.gif"></center>')
|
elem.html('<center><img src="common/img/load_big.gif"></center>');
|
||||||
|
|
||||||
// Receive render events
|
// Receive render events
|
||||||
scope.$on('render',function(){
|
scope.$on('render',function(){
|
||||||
@ -124,7 +131,7 @@ angular.module('kibana.map', [])
|
|||||||
function render_panel() {
|
function render_panel() {
|
||||||
// Using LABjs, wait until all scripts are loaded before rendering panel
|
// Using LABjs, wait until all scripts are loaded before rendering panel
|
||||||
var scripts = $LAB.script("panels/map/lib/jquery.jvectormap.min.js").wait()
|
var scripts = $LAB.script("panels/map/lib/jquery.jvectormap.min.js").wait()
|
||||||
.script("panels/map/lib/map."+scope.panel.map+".js")
|
.script("panels/map/lib/map."+scope.panel.map+".js");
|
||||||
|
|
||||||
// Populate element. Note that jvectormap appends, does not replace.
|
// Populate element. Note that jvectormap appends, does not replace.
|
||||||
scripts.wait(function(){
|
scripts.wait(function(){
|
||||||
@ -143,7 +150,7 @@ angular.module('kibana.map', [])
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
onRegionLabelShow: function(event, label, code){
|
onRegionLabelShow: function(event, label, code){
|
||||||
elem.children('.map-legend').show()
|
elem.children('.map-legend').show();
|
||||||
var count = _.isUndefined(scope.data[code]) ? 0 : scope.data[code];
|
var count = _.isUndefined(scope.data[code]) ? 0 : scope.data[code];
|
||||||
elem.children('.map-legend').text(label.text() + ": " + count);
|
elem.children('.map-legend').text(label.text() + ": " + count);
|
||||||
},
|
},
|
||||||
@ -152,13 +159,14 @@ angular.module('kibana.map', [])
|
|||||||
},
|
},
|
||||||
onRegionClick: function(event, code) {
|
onRegionClick: function(event, code) {
|
||||||
var count = _.isUndefined(scope.data[code]) ? 0 : scope.data[code];
|
var count = _.isUndefined(scope.data[code]) ? 0 : scope.data[code];
|
||||||
if (count != 0)
|
if (count !== 0) {
|
||||||
scope.build_search(scope.panel.field,code)
|
scope.build_search(scope.panel.field,code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
elem.prepend('<span class="map-legend"></span>');
|
elem.prepend('<span class="map-legend"></span>');
|
||||||
$('.map-legend').hide();
|
$('.map-legend').hide();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Pie
|
## Pie
|
||||||
@ -22,9 +24,10 @@
|
|||||||
* default_field :: LOL wat? A dumb fail over field if for some reason the query object
|
* default_field :: LOL wat? A dumb fail over field if for some reason the query object
|
||||||
doesn't have a field
|
doesn't have a field
|
||||||
* spyable :: Show the 'eye' icon that displays the last ES query for this panel
|
* spyable :: Show the 'eye' icon that displays the last ES query for this panel
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.pie', [])
|
angular.module('kibana.pie', [])
|
||||||
.controller('pie', function($scope, $rootScope, query, dashboard, filterSrv) {
|
.controller('pie', function($scope, $rootScope, query, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -42,13 +45,13 @@ angular.module('kibana.pie', [])
|
|||||||
group : "default",
|
group : "default",
|
||||||
default_field : 'DEFAULT',
|
default_field : 'DEFAULT',
|
||||||
spyable : true,
|
spyable : true,
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d)
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.$on('refresh',function(){$scope.get_data()})
|
$scope.$on('refresh',function(){$scope.get_data();});
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_mode = function(mode) {
|
$scope.set_mode = function(mode) {
|
||||||
switch(mode)
|
switch(mode)
|
||||||
@ -60,51 +63,54 @@ angular.module('kibana.pie', [])
|
|||||||
$scope.panel.query = {goal:100};
|
$scope.panel.query = {goal:100};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_refresh = function (state) {
|
$scope.set_refresh = function (state) {
|
||||||
$scope.refresh = state;
|
$scope.refresh = state;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.close_edit = function() {
|
$scope.close_edit = function() {
|
||||||
if($scope.refresh)
|
if($scope.refresh) {
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
|
}
|
||||||
$scope.refresh = false;
|
$scope.refresh = false;
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.get_data = function() {
|
$scope.get_data = function() {
|
||||||
|
|
||||||
// Make sure we have everything for the request to complete
|
// Make sure we have everything for the request to complete
|
||||||
if(dashboard.indices.length == 0) {
|
if(dashboard.indices.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.panel.loading = true;
|
$scope.panel.loading = true;
|
||||||
var request = $scope.ejs.Request().indices(dashboard.indices);
|
var request = $scope.ejs.Request().indices(dashboard.indices);
|
||||||
|
|
||||||
// This could probably be changed to a BoolFilter
|
// This could probably be changed to a BoolFilter
|
||||||
var boolQuery = ejs.BoolQuery();
|
var boolQuery = $scope.ejs.BoolQuery();
|
||||||
_.each(query.list,function(q) {
|
_.each(query.list,function(q) {
|
||||||
boolQuery = boolQuery.should(ejs.QueryStringQuery(q.query || '*'))
|
boolQuery = boolQuery.should($scope.ejs.QueryStringQuery(q.query || '*'));
|
||||||
})
|
});
|
||||||
|
|
||||||
|
var results;
|
||||||
|
|
||||||
// Terms mode
|
// Terms mode
|
||||||
if ($scope.panel.mode == "terms") {
|
if ($scope.panel.mode === "terms") {
|
||||||
request = request
|
request = request
|
||||||
.facet(ejs.TermsFacet('pie')
|
.facet($scope.ejs.TermsFacet('pie')
|
||||||
.field($scope.panel.query.field || $scope.panel.default_field)
|
.field($scope.panel.query.field || $scope.panel.default_field)
|
||||||
.size($scope.panel['size'])
|
.size($scope.panel.size)
|
||||||
.exclude($scope.panel.exclude)
|
.exclude($scope.panel.exclude)
|
||||||
.facetFilter(ejs.QueryFilter(
|
.facetFilter($scope.ejs.QueryFilter(
|
||||||
ejs.FilteredQuery(
|
$scope.ejs.FilteredQuery(
|
||||||
boolQuery,
|
boolQuery,
|
||||||
filterSrv.getBoolFilter(filterSrv.ids)
|
filterSrv.getBoolFilter(filterSrv.ids)
|
||||||
)))).size(0)
|
)))).size(0);
|
||||||
|
|
||||||
$scope.populate_modal(request);
|
$scope.populate_modal(request);
|
||||||
|
|
||||||
var results = request.doSearch();
|
results = request.doSearch();
|
||||||
|
|
||||||
// Populate scope when we have results
|
// Populate scope when we have results
|
||||||
results.then(function(results) {
|
results.then(function(results) {
|
||||||
@ -115,12 +121,7 @@ angular.module('kibana.pie', [])
|
|||||||
_.each(results.facets.pie.terms, function(v) {
|
_.each(results.facets.pie.terms, function(v) {
|
||||||
var slice = { label : v.term, data : v.count };
|
var slice = { label : v.term, data : v.count };
|
||||||
$scope.data.push();
|
$scope.data.push();
|
||||||
if(!(_.isUndefined($scope.panel.colors))
|
$scope.data.push(slice);
|
||||||
&& _.isArray($scope.panel.colors)
|
|
||||||
&& $scope.panel.colors.length > 0) {
|
|
||||||
slice.color = $scope.panel.colors[k%$scope.panel.colors.length];
|
|
||||||
}
|
|
||||||
$scope.data.push(slice)
|
|
||||||
k = k + 1;
|
k = k + 1;
|
||||||
});
|
});
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
@ -130,11 +131,11 @@ angular.module('kibana.pie', [])
|
|||||||
request = request
|
request = request
|
||||||
.query(boolQuery)
|
.query(boolQuery)
|
||||||
.filter(filterSrv.getBoolFilter(filterSrv.ids))
|
.filter(filterSrv.getBoolFilter(filterSrv.ids))
|
||||||
.size(0)
|
.size(0);
|
||||||
|
|
||||||
$scope.populate_modal(request);
|
$scope.populate_modal(request);
|
||||||
|
|
||||||
var results = request.doSearch();
|
results = request.doSearch();
|
||||||
|
|
||||||
results.then(function(results) {
|
results.then(function(results) {
|
||||||
$scope.panel.loading = false;
|
$scope.panel.loading = false;
|
||||||
@ -142,11 +143,12 @@ angular.module('kibana.pie', [])
|
|||||||
var remaining = $scope.panel.query.goal - complete;
|
var remaining = $scope.panel.query.goal - complete;
|
||||||
$scope.data = [
|
$scope.data = [
|
||||||
{ label : 'Complete', data : complete, color: '#BF6730' },
|
{ label : 'Complete', data : complete, color: '#BF6730' },
|
||||||
{ data : remaining, color: '#e2d0c4'}]
|
{ data : remaining, color: '#e2d0c4' }
|
||||||
|
];
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// I really don't like this function, too much dom manip. Break out into directive?
|
// I really don't like this function, too much dom manip. Break out into directive?
|
||||||
$scope.populate_modal = function(request) {
|
$scope.populate_modal = function(request) {
|
||||||
@ -156,8 +158,8 @@ angular.module('kibana.pie', [])
|
|||||||
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
||||||
angular.toJson(JSON.parse(request.toString()),true)+
|
angular.toJson(JSON.parse(request.toString()),true)+
|
||||||
"'</pre>",
|
"'</pre>",
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
})
|
})
|
||||||
.directive('pie', function(query, filterSrv, dashboard) {
|
.directive('pie', function(query, filterSrv, dashboard) {
|
||||||
@ -165,7 +167,7 @@ angular.module('kibana.pie', [])
|
|||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
link: function(scope, elem, attrs) {
|
link: function(scope, elem, attrs) {
|
||||||
|
|
||||||
elem.html('<center><img src="common/img/load_big.gif"></center>')
|
elem.html('<center><img src="common/img/load_big.gif"></center>');
|
||||||
|
|
||||||
// Receive render events
|
// Receive render events
|
||||||
scope.$on('render',function(){
|
scope.$on('render',function(){
|
||||||
@ -180,23 +182,25 @@ angular.module('kibana.pie', [])
|
|||||||
// Function for rendering panel
|
// Function for rendering panel
|
||||||
function render_panel() {
|
function render_panel() {
|
||||||
var scripts = $LAB.script("common/lib/panels/jquery.flot.js").wait()
|
var scripts = $LAB.script("common/lib/panels/jquery.flot.js").wait()
|
||||||
.script("common/lib/panels/jquery.flot.pie.js")
|
.script("common/lib/panels/jquery.flot.pie.js");
|
||||||
|
|
||||||
if(scope.panel.mode === 'goal')
|
var label;
|
||||||
var label = {
|
if(scope.panel.mode === 'goal') {
|
||||||
|
label = {
|
||||||
show: scope.panel.labels,
|
show: scope.panel.labels,
|
||||||
radius: 0,
|
radius: 0,
|
||||||
formatter: function(label, series){
|
formatter: function(label, series){
|
||||||
var font = parseInt(scope.row.height.replace('px',''))/8 + String('px')
|
var font = parseInt(scope.row.height.replace('px',''),10)/8 + String('px');
|
||||||
if(!(_.isUndefined(label)))
|
if(!(_.isUndefined(label))) {
|
||||||
return '<div style="font-size:'+font+';font-weight:bold;text-align:center;padding:2px;color:#fff;">'+
|
return '<div style="font-size:'+font+';font-weight:bold;text-align:center;padding:2px;color:#fff;">'+
|
||||||
Math.round(series.percent)+'%</div>';
|
Math.round(series.percent)+'%</div>';
|
||||||
else
|
} else {
|
||||||
return ''
|
return '';
|
||||||
},
|
|
||||||
}
|
}
|
||||||
else
|
},
|
||||||
var label = {
|
};
|
||||||
|
} else {
|
||||||
|
label = {
|
||||||
show: scope.panel.labels,
|
show: scope.panel.labels,
|
||||||
radius: 2/3,
|
radius: 2/3,
|
||||||
formatter: function(label, series){
|
formatter: function(label, series){
|
||||||
@ -204,6 +208,7 @@ angular.module('kibana.pie', [])
|
|||||||
label+'<br/>'+Math.round(series.percent)+'%</div>';
|
label+'<br/>'+Math.round(series.percent)+'%</div>';
|
||||||
},
|
},
|
||||||
threshold: 0.1
|
threshold: 0.1
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var pie = {
|
var pie = {
|
||||||
@ -263,7 +268,7 @@ angular.module('kibana.pie', [])
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(scope.panel.mode === 'terms') {
|
if(scope.panel.mode === 'terms') {
|
||||||
filterSrv.set({type:'terms',field:scope.panel.query.field,value:object.series.label})
|
filterSrv.set({type:'terms',field:scope.panel.query.field,value:object.series.label});
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -280,4 +285,4 @@ angular.module('kibana.pie', [])
|
|||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
});
|
@ -1,3 +1,5 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## query
|
## query
|
||||||
@ -11,6 +13,8 @@
|
|||||||
one element
|
one element
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.query', [])
|
angular.module('kibana.query', [])
|
||||||
.controller('query', function($scope, query, $rootScope) {
|
.controller('query', function($scope, query, $rootScope) {
|
||||||
|
|
||||||
@ -22,39 +26,39 @@ angular.module('kibana.query', [])
|
|||||||
group : "default",
|
group : "default",
|
||||||
history : [],
|
history : [],
|
||||||
remember: 10 // max: 100, angular strap can't take a variable for items param
|
remember: 10 // max: 100, angular strap can't take a variable for items param
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d);
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.queries = query;
|
$scope.queries = query;
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.refresh = function(query) {
|
$scope.refresh = function(query) {
|
||||||
$rootScope.$broadcast('refresh')
|
$rootScope.$broadcast('refresh');
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.render = function(query) {
|
$scope.render = function(query) {
|
||||||
$rootScope.$broadcast('render')
|
$rootScope.$broadcast('render');
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.add_query = function() {
|
$scope.add_query = function() {
|
||||||
if (_.isArray($scope.panel.query))
|
if (_.isArray($scope.panel.query)) {
|
||||||
$scope.panel.query.push("")
|
$scope.panel.query.push("");
|
||||||
else {
|
} else {
|
||||||
$scope.panel.query = new Array($scope.panel.query)
|
$scope.panel.query = new Array($scope.panel.query);
|
||||||
$scope.panel.query.push("")
|
$scope.panel.query.push("");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var update_history = function(query) {
|
var update_history = function(query) {
|
||||||
if($scope.panel.remember > 0) {
|
if($scope.panel.remember > 0) {
|
||||||
$scope.panel.history = _.union(query.reverse(),$scope.panel.history)
|
$scope.panel.history = _.union(query.reverse(),$scope.panel.history);
|
||||||
var _length = $scope.panel.history.length
|
var _length = $scope.panel.history.length;
|
||||||
if(_length > $scope.panel.remember) {
|
if(_length > $scope.panel.remember) {
|
||||||
$scope.panel.history = $scope.panel.history.slice(0,$scope.panel.remember)
|
$scope.panel.history = $scope.panel.history.slice(0,$scope.panel.remember);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
});
|
});
|
@ -1,3 +1,5 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Table
|
## Table
|
||||||
@ -22,12 +24,11 @@
|
|||||||
* table_documents :: An array containing all of the documents in the table.
|
* table_documents :: An array containing all of the documents in the table.
|
||||||
Only used by the fields panel so far.
|
Only used by the fields panel so far.
|
||||||
#### Receives
|
#### 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
|
|
||||||
* sort :: An array with 2 elements. sort[0]: field, sort[1]: direction ('asc' or 'desc')
|
|
||||||
* selected_fields :: An array of fields to show
|
* selected_fields :: An array of fields to show
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.table', [])
|
angular.module('kibana.table', [])
|
||||||
.controller('table', function($rootScope, $scope, eventBus, fields, query, dashboard, filterSrv) {
|
.controller('table', function($rootScope, $scope, eventBus, fields, query, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -48,104 +49,107 @@ angular.module('kibana.table', [])
|
|||||||
header : true,
|
header : true,
|
||||||
paging : true,
|
paging : true,
|
||||||
spyable: true
|
spyable: true
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d)
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function () {
|
$scope.init = function () {
|
||||||
|
|
||||||
$scope.set_listeners($scope.panel.group)
|
$scope.set_listeners($scope.panel.group);
|
||||||
|
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_listeners = function(group) {
|
$scope.set_listeners = function(group) {
|
||||||
$scope.$on('refresh',function(){$scope.get_data()})
|
$scope.$on('refresh',function(){$scope.get_data();});
|
||||||
eventBus.register($scope,'sort', function(event,sort){
|
eventBus.register($scope,'sort', function(event,sort){
|
||||||
$scope.panel.sort = _.clone(sort);
|
$scope.panel.sort = _.clone(sort);
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
});
|
});
|
||||||
eventBus.register($scope,'selected_fields', function(event, fields) {
|
eventBus.register($scope,'selected_fields', function(event, fields) {
|
||||||
$scope.panel.fields = _.clone(fields)
|
$scope.panel.fields = _.clone(fields);
|
||||||
});
|
});
|
||||||
eventBus.register($scope,'table_documents', function(event, docs) {
|
eventBus.register($scope,'table_documents', function(event, docs) {
|
||||||
query.list[query.ids[0]].query = docs.query;
|
query.list[query.ids[0]].query = docs.query;
|
||||||
$scope.data = docs.docs;
|
$scope.data = docs.docs;
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_sort = function(field) {
|
$scope.set_sort = function(field) {
|
||||||
if($scope.panel.sort[0] === field)
|
if($scope.panel.sort[0] === field) {
|
||||||
$scope.panel.sort[1] = $scope.panel.sort[1] == 'asc' ? 'desc' : 'asc';
|
$scope.panel.sort[1] = $scope.panel.sort[1] === 'asc' ? 'desc' : 'asc';
|
||||||
else
|
} else {
|
||||||
$scope.panel.sort[0] = field;
|
$scope.panel.sort[0] = field;
|
||||||
$scope.get_data();
|
|
||||||
}
|
}
|
||||||
|
$scope.get_data();
|
||||||
|
};
|
||||||
|
|
||||||
$scope.toggle_field = function(field) {
|
$scope.toggle_field = function(field) {
|
||||||
if (_.indexOf($scope.panel.fields,field) > -1)
|
if (_.indexOf($scope.panel.fields,field) > -1) {
|
||||||
$scope.panel.fields = _.without($scope.panel.fields,field)
|
$scope.panel.fields = _.without($scope.panel.fields,field);
|
||||||
else
|
} else {
|
||||||
$scope.panel.fields.push(field)
|
$scope.panel.fields.push(field);
|
||||||
broadcast_results();
|
|
||||||
}
|
}
|
||||||
|
broadcast_results();
|
||||||
|
};
|
||||||
|
|
||||||
$scope.toggle_highlight = function(field) {
|
$scope.toggle_highlight = function(field) {
|
||||||
if (_.indexOf($scope.panel.highlight,field) > -1)
|
if (_.indexOf($scope.panel.highlight,field) > -1) {
|
||||||
$scope.panel.highlight = _.without($scope.panel.highlight,field)
|
$scope.panel.highlight = _.without($scope.panel.highlight,field);
|
||||||
else
|
} else {
|
||||||
$scope.panel.highlight.push(field)
|
$scope.panel.highlight.push(field);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$scope.toggle_details = function(row) {
|
$scope.toggle_details = function(row) {
|
||||||
row.kibana = row.kibana || {};
|
row.kibana = row.kibana || {};
|
||||||
row.kibana.details = !row.kibana.details ? $scope.without_kibana(row) : false;
|
row.kibana.details = !row.kibana.details ? $scope.without_kibana(row) : false;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.page = function(page) {
|
$scope.page = function(page) {
|
||||||
$scope.panel.offset = page*$scope.panel.size
|
$scope.panel.offset = page*$scope.panel.size;
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.build_search = function(field,value,negate) {
|
$scope.build_search = function(field,value,negate) {
|
||||||
var query;
|
var query = field+":";
|
||||||
// This needs to be abstracted somewhere
|
// This needs to be abstracted somewhere
|
||||||
if(_.isArray(value)) {
|
if(_.isArray(value)) {
|
||||||
query = field+":(" + _.map(value,function(v){return angular.toJson(v)}).join(" AND ") + ")";
|
query = query+"(" + _.map(value,function(v){return angular.toJson(v);}).join(" AND ") + ")";
|
||||||
} else {
|
} else {
|
||||||
query = field+":"+angular.toJson(value);
|
query = query+angular.toJson(value);
|
||||||
}
|
}
|
||||||
filterSrv.set({type:'querystring',query:query,mandate:(negate ? 'mustNot':'must')})
|
filterSrv.set({type:'querystring',query:query,mandate:(negate ? 'mustNot':'must')});
|
||||||
$scope.panel.offset = 0;
|
$scope.panel.offset = 0;
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.get_data = function(segment,query_id) {
|
$scope.get_data = function(segment,query_id) {
|
||||||
$scope.panel.error = false;
|
$scope.panel.error = false;
|
||||||
|
|
||||||
// Make sure we have everything for the request to complete
|
// Make sure we have everything for the request to complete
|
||||||
if(dashboard.indices.length == 0) {
|
if(dashboard.indices.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.panel.loading = true;
|
$scope.panel.loading = true;
|
||||||
|
|
||||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
var _segment = _.isUndefined(segment) ? 0 : segment;
|
||||||
$scope.segment = _segment;
|
$scope.segment = _segment;
|
||||||
|
|
||||||
var request = $scope.ejs.Request().indices(dashboard.indices[_segment])
|
var request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
|
||||||
|
|
||||||
var boolQuery = ejs.BoolQuery();
|
var boolQuery = $scope.ejs.BoolQuery();
|
||||||
_.each(query.list,function(q) {
|
_.each(query.list,function(q) {
|
||||||
boolQuery = boolQuery.should(ejs.QueryStringQuery(q.query || '*'))
|
boolQuery = boolQuery.should($scope.ejs.QueryStringQuery(q.query || '*'));
|
||||||
})
|
});
|
||||||
|
|
||||||
request = request.query(
|
request = request.query(
|
||||||
ejs.FilteredQuery(
|
$scope.ejs.FilteredQuery(
|
||||||
boolQuery,
|
boolQuery,
|
||||||
filterSrv.getBoolFilter(filterSrv.ids)
|
filterSrv.getBoolFilter(filterSrv.ids)
|
||||||
))
|
))
|
||||||
.highlight(
|
.highlight(
|
||||||
ejs.Highlight($scope.panel.highlight)
|
$scope.ejs.Highlight($scope.panel.highlight)
|
||||||
.fragmentSize(2147483647) // Max size of a 32bit unsigned int
|
.fragmentSize(2147483647) // Max size of a 32bit unsigned int
|
||||||
.preTags('@start-highlight@')
|
.preTags('@start-highlight@')
|
||||||
.postTags('@end-highlight@')
|
.postTags('@end-highlight@')
|
||||||
@ -153,9 +157,9 @@ angular.module('kibana.table', [])
|
|||||||
.size($scope.panel.size*$scope.panel.pages)
|
.size($scope.panel.size*$scope.panel.pages)
|
||||||
.sort($scope.panel.sort[0],$scope.panel.sort[1]);
|
.sort($scope.panel.sort[0],$scope.panel.sort[1]);
|
||||||
|
|
||||||
$scope.populate_modal(request)
|
$scope.populate_modal(request);
|
||||||
|
|
||||||
var results = request.doSearch()
|
var results = request.doSearch();
|
||||||
|
|
||||||
// Populate scope when we have results
|
// Populate scope when we have results
|
||||||
results.then(function(results) {
|
results.then(function(results) {
|
||||||
@ -164,7 +168,7 @@ angular.module('kibana.table', [])
|
|||||||
if(_segment === 0) {
|
if(_segment === 0) {
|
||||||
$scope.hits = 0;
|
$scope.hits = 0;
|
||||||
$scope.data = [];
|
$scope.data = [];
|
||||||
query_id = $scope.query_id = new Date().getTime()
|
query_id = $scope.query_id = new Date().getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for error and abort if found
|
// Check for error and abort if found
|
||||||
@ -177,46 +181,46 @@ angular.module('kibana.table', [])
|
|||||||
if($scope.query_id === query_id) {
|
if($scope.query_id === query_id) {
|
||||||
$scope.data= $scope.data.concat(_.map(results.hits.hits, function(hit) {
|
$scope.data= $scope.data.concat(_.map(results.hits.hits, function(hit) {
|
||||||
return {
|
return {
|
||||||
_source : flatten_json(hit['_source']),
|
_source : kbn.flatten_json(hit._source),
|
||||||
highlight : flatten_json(hit['highlight']||{})
|
highlight : kbn.flatten_json(hit.highlight||{})
|
||||||
}
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$scope.hits += results.hits.total;
|
$scope.hits += results.hits.total;
|
||||||
|
|
||||||
// Sort the data
|
// Sort the data
|
||||||
$scope.data = _.sortBy($scope.data, function(v){
|
$scope.data = _.sortBy($scope.data, function(v){
|
||||||
return v._source[$scope.panel.sort[0]]
|
return v._source[$scope.panel.sort[0]];
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reverse if needed
|
// Reverse if needed
|
||||||
if($scope.panel.sort[1] == 'desc')
|
if($scope.panel.sort[1] === 'desc') {
|
||||||
$scope.data.reverse();
|
$scope.data.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
// Keep only what we need for the set
|
// Keep only what we need for the set
|
||||||
$scope.data = $scope.data.slice(0,$scope.panel.size * $scope.panel.pages)
|
$scope.data = $scope.data.slice(0,$scope.panel.size * $scope.panel.pages);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This breaks, use $scope.data for this
|
// This breaks, use $scope.data for this
|
||||||
$scope.all_fields = get_all_fields(_.pluck($scope.data,'_source'));
|
$scope.all_fields = kbn.get_all_fields(_.pluck($scope.data,'_source'));
|
||||||
broadcast_results();
|
broadcast_results();
|
||||||
|
|
||||||
// If we're not sorting in reverse chrono order, query every index for
|
// If we're not sorting in reverse chrono order, query every index for
|
||||||
// size*pages results
|
// size*pages results
|
||||||
// Otherwise, only get size*pages results then stop querying
|
// Otherwise, only get size*pages results then stop querying
|
||||||
if($scope.data.length < $scope.panel.size*$scope.panel.pages
|
|
||||||
//($scope.data.length < $scope.panel.size*$scope.panel.pages
|
//($scope.data.length < $scope.panel.size*$scope.panel.pages
|
||||||
// || !(($scope.panel.sort[0] === $scope.time.field) && $scope.panel.sort[1] === 'desc'))
|
// || !(($scope.panel.sort[0] === $scope.time.field) && $scope.panel.sort[1] === 'desc'))
|
||||||
&& _segment+1 < dashboard.indices.length
|
if($scope.data.length < $scope.panel.size*$scope.panel.pages &&
|
||||||
) {
|
_segment+1 < dashboard.indices.length ) {
|
||||||
$scope.get_data(_segment+1,$scope.query_id)
|
$scope.get_data(_segment+1,$scope.query_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.populate_modal = function(request) {
|
$scope.populate_modal = function(request) {
|
||||||
$scope.modal = {
|
$scope.modal = {
|
||||||
@ -225,15 +229,15 @@ angular.module('kibana.table', [])
|
|||||||
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
'curl -XGET '+config.elasticsearch+'/'+dashboard.indices+"/_search?pretty -d'\n"+
|
||||||
angular.toJson(JSON.parse(request.toString()),true)+
|
angular.toJson(JSON.parse(request.toString()),true)+
|
||||||
"'</pre>",
|
"'</pre>",
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.without_kibana = function (row) {
|
$scope.without_kibana = function (row) {
|
||||||
return {
|
return {
|
||||||
_source : row._source,
|
_source : row._source,
|
||||||
highlight : row.highlight
|
highlight : row.highlight
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
// Broadcast a list of all fields. Note that receivers of field array
|
// Broadcast a list of all fields. Note that receivers of field array
|
||||||
// events should be able to receive from multiple sources, merge, dedupe
|
// events should be able to receive from multiple sources, merge, dedupe
|
||||||
@ -254,13 +258,14 @@ angular.module('kibana.table', [])
|
|||||||
|
|
||||||
$scope.set_refresh = function (state) {
|
$scope.set_refresh = function (state) {
|
||||||
$scope.refresh = state;
|
$scope.refresh = state;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.close_edit = function() {
|
$scope.close_edit = function() {
|
||||||
if($scope.refresh)
|
if($scope.refresh) {
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
$scope.refresh = false;
|
|
||||||
}
|
}
|
||||||
|
$scope.refresh = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -273,8 +278,8 @@ angular.module('kibana.table', [])
|
|||||||
replace(/>/g, '>').
|
replace(/>/g, '>').
|
||||||
replace(/\r?\n/g, '<br/>').
|
replace(/\r?\n/g, '<br/>').
|
||||||
replace(/@start-highlight@/g, '<code class="highlight">').
|
replace(/@start-highlight@/g, '<code class="highlight">').
|
||||||
replace(/@end-highlight@/g, '</code>')
|
replace(/@end-highlight@/g, '</code>');
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
|
/*global Showdown:false */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Text
|
## Text
|
||||||
@ -11,6 +14,8 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.text', [])
|
angular.module('kibana.text', [])
|
||||||
.controller('text', function($scope, $rootScope) {
|
.controller('text', function($scope, $rootScope) {
|
||||||
|
|
||||||
@ -21,12 +26,12 @@ angular.module('kibana.text', [])
|
|||||||
mode : "markdown",
|
mode : "markdown",
|
||||||
content : "",
|
content : "",
|
||||||
style: {},
|
style: {},
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d);
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
$scope.ready = false;
|
$scope.ready = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
}).directive('markdown', function() {
|
}).directive('markdown', function() {
|
||||||
return {
|
return {
|
||||||
@ -34,10 +39,10 @@ angular.module('kibana.text', [])
|
|||||||
link: function(scope, element, attrs) {
|
link: function(scope, element, attrs) {
|
||||||
scope.$on('render', function() {
|
scope.$on('render', function() {
|
||||||
render_panel();
|
render_panel();
|
||||||
})
|
});
|
||||||
|
|
||||||
function render_panel() {
|
function render_panel() {
|
||||||
var scripts = $LAB.script("panels/text/lib/showdown.js")
|
var scripts = $LAB.script("panels/text/lib/showdown.js");
|
||||||
scripts.wait(function(){
|
scripts.wait(function(){
|
||||||
scope.ready = true;
|
scope.ready = true;
|
||||||
var converter = new Showdown.converter();
|
var converter = new Showdown.converter();
|
||||||
@ -48,18 +53,18 @@ angular.module('kibana.text', [])
|
|||||||
element.html(htmlText);
|
element.html(htmlText);
|
||||||
// For whatever reason, this fixes chrome. I don't like it, I think
|
// For whatever reason, this fixes chrome. I don't like it, I think
|
||||||
// it makes things slow?
|
// it makes things slow?
|
||||||
scope.$apply()
|
scope.$apply();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render_panel();
|
render_panel();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
})
|
})
|
||||||
.filter('newlines', function(){
|
.filter('newlines', function(){
|
||||||
return function (input) {
|
return function (input) {
|
||||||
return input.replace(/\n/g, '<br/>');
|
return input.replace(/\n/g, '<br/>');
|
||||||
}
|
};
|
||||||
})
|
})
|
||||||
.filter('striphtml', function () {
|
.filter('striphtml', function () {
|
||||||
return function(text) {
|
return function(text) {
|
||||||
@ -67,5 +72,5 @@ angular.module('kibana.text', [])
|
|||||||
.replace(/&/g, '&')
|
.replace(/&/g, '&')
|
||||||
.replace(/>/g, '>')
|
.replace(/>/g, '>')
|
||||||
.replace(/</g, '<');
|
.replace(/</g, '<');
|
||||||
}
|
};
|
||||||
});
|
});
|
@ -1,3 +1,5 @@
|
|||||||
|
/*jshint globalstrict:true */
|
||||||
|
/*global angular:true */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
## Timepicker
|
## Timepicker
|
||||||
@ -17,6 +19,8 @@
|
|||||||
* min :: The lowest interval a user may set
|
* min :: The lowest interval a user may set
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.timepicker', [])
|
angular.module('kibana.timepicker', [])
|
||||||
.controller('timepicker', function($scope, $rootScope, $timeout, timer, $http, dashboard, filterSrv) {
|
.controller('timepicker', function($scope, $rootScope, $timeout, timer, $http, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -34,8 +38,8 @@ angular.module('kibana.timepicker', [])
|
|||||||
interval: 30,
|
interval: 30,
|
||||||
min : 3
|
min : 3
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d)
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
var _groups = _.isArray($scope.panel.group) ?
|
var _groups = _.isArray($scope.panel.group) ?
|
||||||
$scope.panel.group : [$scope.panel.group];
|
$scope.panel.group : [$scope.panel.group];
|
||||||
@ -43,91 +47,91 @@ angular.module('kibana.timepicker', [])
|
|||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
// Private refresh interval that we can use for view display without causing
|
// Private refresh interval that we can use for view display without causing
|
||||||
// unnecessary refreshes during changes
|
// unnecessary refreshes during changes
|
||||||
$scope.refresh_interval = $scope.panel.refresh.interval
|
$scope.refresh_interval = $scope.panel.refresh.interval;
|
||||||
$scope.filterSrv = filterSrv;
|
$scope.filterSrv = filterSrv;
|
||||||
|
|
||||||
// Init a private time object with Date() objects depending on mode
|
// Init a private time object with Date() objects depending on mode
|
||||||
switch($scope.panel.mode) {
|
switch($scope.panel.mode) {
|
||||||
case 'absolute':
|
case 'absolute':
|
||||||
$scope.time = {
|
$scope.time = {
|
||||||
from : moment($scope.panel.time.from,'MM/DD/YYYY HH:mm:ss') || moment(time_ago($scope.panel.timespan)),
|
from : moment($scope.panel.time.from,'MM/DD/YYYY HH:mm:ss') || moment(kbn.time_ago($scope.panel.timespan)),
|
||||||
to : moment($scope.panel.time.to,'MM/DD/YYYY HH:mm:ss') || moment()
|
to : moment($scope.panel.time.to,'MM/DD/YYYY HH:mm:ss') || moment()
|
||||||
}
|
};
|
||||||
break;
|
break;
|
||||||
case 'since':
|
case 'since':
|
||||||
$scope.time = {
|
$scope.time = {
|
||||||
from : moment($scope.panel.time.from,'MM/DD/YYYY HH:mm:ss') || moment(time_ago($scope.panel.timespan)),
|
from : moment($scope.panel.time.from,'MM/DD/YYYY HH:mm:ss') || moment(kbn.time_ago($scope.panel.timespan)),
|
||||||
to : moment()
|
to : moment()
|
||||||
}
|
};
|
||||||
break;
|
break;
|
||||||
case 'relative':
|
case 'relative':
|
||||||
$scope.time = {
|
$scope.time = {
|
||||||
from : moment(time_ago($scope.panel.timespan)),
|
from : moment(kbn.time_ago($scope.panel.timespan)),
|
||||||
to : moment()
|
to : moment()
|
||||||
}
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$scope.time.field = $scope.panel.timefield;
|
$scope.time.field = $scope.panel.timefield;
|
||||||
// These 3 statements basicly do everything time_apply() does
|
// These 3 statements basicly do everything time_apply() does
|
||||||
set_timepicker($scope.time.from,$scope.time.to)
|
set_timepicker($scope.time.from,$scope.time.to);
|
||||||
update_panel()
|
update_panel();
|
||||||
set_time_filter($scope.time)
|
set_time_filter($scope.time);
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
|
|
||||||
|
|
||||||
// Start refresh timer if enabled
|
// Start refresh timer if enabled
|
||||||
if ($scope.panel.refresh.enable)
|
if ($scope.panel.refresh.enable) {
|
||||||
$scope.set_interval($scope.panel.refresh.interval);
|
$scope.set_interval($scope.panel.refresh.interval);
|
||||||
|
}
|
||||||
|
|
||||||
// In case some other panel broadcasts a time, set us to an absolute range
|
// In case some other panel broadcasts a time, set us to an absolute range
|
||||||
$scope.$on('refresh', function() {
|
$scope.$on('refresh', function() {
|
||||||
if(filterSrv.idsByType('time').length > 0) {
|
if(filterSrv.idsByType('time').length > 0) {
|
||||||
var time = filterSrv.timeRange('min')
|
var time = filterSrv.timeRange('min');
|
||||||
|
|
||||||
if($scope.time.from.diff(moment.utc(time.from),'seconds') !== 0
|
if($scope.time.from.diff(moment.utc(time.from),'seconds') !== 0 ||
|
||||||
|| $scope.time.to.diff(moment.utc(time.to),'seconds') !== 0)
|
$scope.time.to.diff(moment.utc(time.to),'seconds') !== 0)
|
||||||
{
|
{
|
||||||
console.log($scope.time.from+ " and "+ moment.utc(time.from))
|
console.log($scope.time.from+ " and "+ moment.utc(time.from));
|
||||||
console.log($scope.time.to+" and "+moment.utc(time.to))
|
console.log($scope.time.to+" and "+moment.utc(time.to));
|
||||||
|
|
||||||
$scope.set_mode('absolute');
|
$scope.set_mode('absolute');
|
||||||
|
|
||||||
// These 3 statements basicly do everything time_apply() does
|
// These 3 statements basicly do everything time_apply() does
|
||||||
set_timepicker(moment(time.from),moment(time.to))
|
set_timepicker(moment(time.from),moment(time.to));
|
||||||
$scope.time = $scope.time_calc();
|
$scope.time = $scope.time_calc();
|
||||||
update_panel()
|
update_panel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_interval = function (refresh_interval) {
|
$scope.set_interval = function (refresh_interval) {
|
||||||
$scope.panel.refresh.interval = refresh_interval
|
$scope.panel.refresh.interval = refresh_interval;
|
||||||
if(_.isNumber($scope.panel.refresh.interval)) {
|
if(_.isNumber($scope.panel.refresh.interval)) {
|
||||||
if($scope.panel.refresh.interval < $scope.panel.refresh.min) {
|
if($scope.panel.refresh.interval < $scope.panel.refresh.min) {
|
||||||
$scope.panel.refresh.interval = $scope.panel.refresh.min
|
$scope.panel.refresh.interval = $scope.panel.refresh.min;
|
||||||
timer.cancel($scope.refresh_timer)
|
timer.cancel($scope.refresh_timer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timer.cancel($scope.refresh_timer)
|
timer.cancel($scope.refresh_timer);
|
||||||
$scope.refresh()
|
$scope.refresh();
|
||||||
} else {
|
} else {
|
||||||
timer.cancel($scope.refresh_timer)
|
timer.cancel($scope.refresh_timer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$scope.refresh = function() {
|
$scope.refresh = function() {
|
||||||
if ($scope.panel.refresh.enable) {
|
if ($scope.panel.refresh.enable) {
|
||||||
timer.cancel($scope.refresh_timer)
|
timer.cancel($scope.refresh_timer);
|
||||||
$scope.refresh_timer = timer.register($timeout(function() {
|
$scope.refresh_timer = timer.register($timeout(function() {
|
||||||
$scope.refresh();
|
$scope.refresh();
|
||||||
$scope.time_apply();
|
$scope.time_apply();
|
||||||
},$scope.panel.refresh.interval*1000
|
},$scope.panel.refresh.interval*1000));
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
timer.cancel($scope.refresh_timer)
|
timer.cancel($scope.refresh_timer);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var update_panel = function() {
|
var update_panel = function() {
|
||||||
// Update panel's string representation of the time object.Don't update if
|
// Update panel's string representation of the time object.Don't update if
|
||||||
@ -141,92 +145,94 @@ angular.module('kibana.timepicker', [])
|
|||||||
} else {
|
} else {
|
||||||
delete $scope.panel.time;
|
delete $scope.panel.time;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_mode = function(mode) {
|
$scope.set_mode = function(mode) {
|
||||||
$scope.panel.mode = mode;
|
$scope.panel.mode = mode;
|
||||||
$scope.panel.refresh.enable = mode === 'absolute' ?
|
$scope.panel.refresh.enable = mode === 'absolute' ?
|
||||||
false : $scope.panel.refresh.enable
|
false : $scope.panel.refresh.enable;
|
||||||
|
|
||||||
update_panel();
|
update_panel();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.to_now = function() {
|
$scope.to_now = function() {
|
||||||
$scope.timepicker.to = {
|
$scope.timepicker.to = {
|
||||||
time : moment().format("HH:mm:ss"),
|
time : moment().format("HH:mm:ss"),
|
||||||
date : moment().format("MM/DD/YYYY")
|
date : moment().format("MM/DD/YYYY")
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.set_timespan = function(timespan) {
|
$scope.set_timespan = function(timespan) {
|
||||||
$scope.panel.timespan = timespan;
|
$scope.panel.timespan = timespan;
|
||||||
$scope.timepicker.from = {
|
$scope.timepicker.from = {
|
||||||
time : moment(time_ago(timespan)).format("HH:mm:ss"),
|
time : moment(kbn.time_ago(timespan)).format("HH:mm:ss"),
|
||||||
date : moment(time_ago(timespan)).format("MM/DD/YYYY")
|
date : moment(kbn.time_ago(timespan)).format("MM/DD/YYYY")
|
||||||
}
|
};
|
||||||
$scope.time_apply();
|
$scope.time_apply();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.close_edit = function() {
|
$scope.close_edit = function() {
|
||||||
$scope.time_apply();
|
$scope.time_apply();
|
||||||
}
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
$scope.time_calc = function(){
|
$scope.time_calc = function(){
|
||||||
|
var from,to;
|
||||||
// If time picker is defined (usually is)
|
// If time picker is defined (usually is)
|
||||||
if(!(_.isUndefined($scope.timepicker))) {
|
if(!(_.isUndefined($scope.timepicker))) {
|
||||||
var from = $scope.panel.mode === 'relative' ? moment(time_ago($scope.panel.timespan)) :
|
from = $scope.panel.mode === 'relative' ? moment(kbn.time_ago($scope.panel.timespan)) :
|
||||||
moment($scope.timepicker.from.date + " " + $scope.timepicker.from.time,'MM/DD/YYYY HH:mm:ss')
|
moment($scope.timepicker.from.date + " " + $scope.timepicker.from.time,'MM/DD/YYYY HH:mm:ss');
|
||||||
var to = $scope.panel.mode !== 'absolute' ? moment() :
|
to = $scope.panel.mode !== 'absolute' ? moment() :
|
||||||
moment($scope.timepicker.to.date + " " + $scope.timepicker.to.time,'MM/DD/YYYY HH:mm:ss')
|
moment($scope.timepicker.to.date + " " + $scope.timepicker.to.time,'MM/DD/YYYY HH:mm:ss');
|
||||||
// Otherwise (probably initialization)
|
// Otherwise (probably initialization)
|
||||||
} else {
|
} else {
|
||||||
var from = $scope.panel.mode === 'relative' ? moment(time_ago($scope.panel.timespan)) :
|
from = $scope.panel.mode === 'relative' ? moment(kbn.time_ago($scope.panel.timespan)) :
|
||||||
$scope.time.from;
|
$scope.time.from;
|
||||||
var to = $scope.panel.mode !== 'absolute' ? moment() :
|
to = $scope.panel.mode !== 'absolute' ? moment() :
|
||||||
$scope.time.to;
|
$scope.time.to;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (from.valueOf() >= to.valueOf())
|
if (from.valueOf() >= to.valueOf()) {
|
||||||
from = moment(to.valueOf() - 1000)
|
from = moment(to.valueOf() - 1000);
|
||||||
|
}
|
||||||
|
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
set_timepicker(from,to)
|
set_timepicker(from,to);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
from : from,
|
from : from,
|
||||||
to : to
|
to : to
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.time_apply = function() {
|
$scope.time_apply = function() {
|
||||||
$scope.panel.error = "";
|
$scope.panel.error = "";
|
||||||
// Update internal time object
|
// Update internal time object
|
||||||
|
|
||||||
// Remove all other time filters
|
// Remove all other time filters
|
||||||
filterSrv.removeByType('time')
|
filterSrv.removeByType('time');
|
||||||
|
|
||||||
$scope.time = $scope.time_calc();
|
$scope.time = $scope.time_calc();
|
||||||
$scope.time.field = $scope.panel.timefield
|
$scope.time.field = $scope.panel.timefield;
|
||||||
update_panel()
|
update_panel();
|
||||||
|
|
||||||
set_time_filter($scope.time)
|
set_time_filter($scope.time);
|
||||||
dashboard.refresh();
|
dashboard.refresh();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function set_time_filter(time) {
|
function set_time_filter(time) {
|
||||||
time.type = 'time'
|
time.type = 'time';
|
||||||
// Check if there's a time filter we remember, if not, set one and remember it
|
// Check if there's a time filter we remember, if not, set one and remember it
|
||||||
if(!_.isUndefined($scope.panel.filter_id) &&
|
if(!_.isUndefined($scope.panel.filter_id) &&
|
||||||
!_.isUndefined(filterSrv.list[$scope.panel.filter_id]) &&
|
!_.isUndefined(filterSrv.list[$scope.panel.filter_id]) &&
|
||||||
filterSrv.list[$scope.panel.filter_id].type == 'time')
|
filterSrv.list[$scope.panel.filter_id].type === 'time')
|
||||||
{
|
{
|
||||||
filterSrv.set(compile_time(time),$scope.panel.filter_id)
|
filterSrv.set(compile_time(time),$scope.panel.filter_id);
|
||||||
} else {
|
} else {
|
||||||
$scope.panel.filter_id = filterSrv.set(compile_time(time))
|
$scope.panel.filter_id = filterSrv.set(compile_time(time));
|
||||||
}
|
}
|
||||||
return $scope.panel.filter_id;
|
return $scope.panel.filter_id;
|
||||||
}
|
}
|
||||||
@ -234,9 +240,9 @@ angular.module('kibana.timepicker', [])
|
|||||||
// Prefer to pass around Date() objects since interacting with
|
// Prefer to pass around Date() objects since interacting with
|
||||||
// moment objects in libraries that are expecting Date()s can be tricky
|
// moment objects in libraries that are expecting Date()s can be tricky
|
||||||
function compile_time(time) {
|
function compile_time(time) {
|
||||||
time = _.clone(time)
|
time = _.clone(time);
|
||||||
time.from = time.from.toDate()
|
time.from = time.from.toDate();
|
||||||
time.to = time.to.toDate()
|
time.to = time.to.toDate();
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +257,7 @@ angular.module('kibana.timepicker', [])
|
|||||||
time : to.format("HH:mm:ss"),
|
time : to.format("HH:mm:ss"),
|
||||||
date : to.format("MM/DD/YYYY")
|
date : to.format("MM/DD/YYYY")
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
});
|
@ -18,6 +18,9 @@
|
|||||||
* query :: An Array of queries, even if its only one
|
* query :: An Array of queries, even if its only one
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.trends', [])
|
angular.module('kibana.trends', [])
|
||||||
.controller('trends', function($scope, kbnIndex, query, dashboard, filterSrv) {
|
.controller('trends', function($scope, kbnIndex, query, dashboard, filterSrv) {
|
||||||
|
|
||||||
@ -29,87 +32,87 @@ angular.module('kibana.trends', [])
|
|||||||
style : { "font-size": '14pt'},
|
style : { "font-size": '14pt'},
|
||||||
ago : '1d',
|
ago : '1d',
|
||||||
arrangement : 'vertical',
|
arrangement : 'vertical',
|
||||||
}
|
};
|
||||||
_.defaults($scope.panel,_d)
|
_.defaults($scope.panel,_d);
|
||||||
|
|
||||||
$scope.init = function () {
|
$scope.init = function () {
|
||||||
$scope.hits = 0;
|
$scope.hits = 0;
|
||||||
|
|
||||||
$scope.$on('refresh',function(){$scope.get_data()})
|
$scope.$on('refresh',function(){$scope.get_data();});
|
||||||
|
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.get_data = function(segment,query_id) {
|
$scope.get_data = function(segment,query_id) {
|
||||||
delete $scope.panel.error
|
delete $scope.panel.error;
|
||||||
$scope.panel.loading = true;
|
$scope.panel.loading = true;
|
||||||
|
|
||||||
// Make sure we have everything for the request to complete
|
// Make sure we have everything for the request to complete
|
||||||
if(dashboard.indices.length == 0) {
|
if(dashboard.indices.length === 0) {
|
||||||
return
|
return;
|
||||||
} else {
|
} else {
|
||||||
$scope.index = segment > 0 ? $scope.index : dashboard.indices;
|
$scope.index = segment > 0 ? $scope.index : dashboard.indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine a time field
|
// Determine a time field
|
||||||
var timeField = _.uniq(_.pluck(filterSrv.getByType('time'),'field'))
|
var timeField = _.uniq(_.pluck(filterSrv.getByType('time'),'field'));
|
||||||
if(timeField.length > 1) {
|
if(timeField.length > 1) {
|
||||||
$scope.panel.error = "Time field must be consistent amongst time filters"
|
$scope.panel.error = "Time field must be consistent amongst time filters";
|
||||||
return
|
return;
|
||||||
} else if(timeField.length == 0) {
|
} else if(timeField.length === 0) {
|
||||||
$scope.panel.error = "A time filter must exist for this panel to function"
|
$scope.panel.error = "A time filter must exist for this panel to function";
|
||||||
return
|
return;
|
||||||
} else {
|
} else {
|
||||||
timeField = timeField[0]
|
timeField = timeField[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.time = filterSrv.timeRange('min');
|
$scope.time = filterSrv.timeRange('min');
|
||||||
$scope.old_time = {
|
$scope.old_time = {
|
||||||
from : new Date($scope.time.from.getTime() - interval_to_seconds($scope.panel.ago)*1000),
|
from : new Date($scope.time.from.getTime() - kbn.interval_to_seconds($scope.panel.ago)*1000),
|
||||||
to : new Date($scope.time.to.getTime() - interval_to_seconds($scope.panel.ago)*1000)
|
to : new Date($scope.time.to.getTime() - kbn.interval_to_seconds($scope.panel.ago)*1000)
|
||||||
}
|
};
|
||||||
|
|
||||||
var _segment = _.isUndefined(segment) ? 0 : segment
|
var _segment = _.isUndefined(segment) ? 0 : segment;
|
||||||
var request = $scope.ejs.Request();
|
var request = $scope.ejs.Request();
|
||||||
var _ids_without_time = _.difference(filterSrv.ids,filterSrv.idsByType('time'))
|
var _ids_without_time = _.difference(filterSrv.ids,filterSrv.idsByType('time'));
|
||||||
|
|
||||||
|
|
||||||
// Build the question part of the query
|
// Build the question part of the query
|
||||||
_.each(query.ids, function(id) {
|
_.each(query.ids, function(id) {
|
||||||
var q = $scope.ejs.FilteredQuery(
|
var q = $scope.ejs.FilteredQuery(
|
||||||
ejs.QueryStringQuery(query.list[id].query || '*'),
|
$scope.ejs.QueryStringQuery(query.list[id].query || '*'),
|
||||||
filterSrv.getBoolFilter(_ids_without_time).must(
|
filterSrv.getBoolFilter(_ids_without_time).must(
|
||||||
ejs.RangeFilter(timeField)
|
$scope.ejs.RangeFilter(timeField)
|
||||||
.from($scope.time.from)
|
.from($scope.time.from)
|
||||||
.to($scope.time.to)
|
.to($scope.time.to)
|
||||||
))
|
));
|
||||||
|
|
||||||
request = request
|
request = request
|
||||||
.facet($scope.ejs.QueryFacet(id)
|
.facet($scope.ejs.QueryFacet(id)
|
||||||
.query(q)
|
.query(q)
|
||||||
).size(0)
|
).size(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// And again for the old time period
|
// And again for the old time period
|
||||||
_.each(query.ids, function(id) {
|
_.each(query.ids, function(id) {
|
||||||
var q = $scope.ejs.FilteredQuery(
|
var q = $scope.ejs.FilteredQuery(
|
||||||
ejs.QueryStringQuery(query.list[id].query || '*'),
|
$scope.ejs.QueryStringQuery(query.list[id].query || '*'),
|
||||||
filterSrv.getBoolFilter(_ids_without_time).must(
|
filterSrv.getBoolFilter(_ids_without_time).must(
|
||||||
ejs.RangeFilter(timeField)
|
$scope.ejs.RangeFilter(timeField)
|
||||||
.from($scope.old_time.from)
|
.from($scope.old_time.from)
|
||||||
.to($scope.old_time.to)
|
.to($scope.old_time.to)
|
||||||
))
|
));
|
||||||
request = request
|
request = request
|
||||||
.facet($scope.ejs.QueryFacet("old_"+id)
|
.facet($scope.ejs.QueryFacet("old_"+id)
|
||||||
.query(q)
|
.query(q)
|
||||||
).size(0)
|
).size(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Spy for trend panel
|
// TODO: Spy for trend panel
|
||||||
//$scope.populate_modal(request);
|
//$scope.populate_modal(request);
|
||||||
|
|
||||||
// If we're on the first segment we need to get our indices
|
// If we're on the first segment we need to get our indices
|
||||||
if (_segment == 0) {
|
if (_segment === 0) {
|
||||||
kbnIndex.indices(
|
kbnIndex.indices(
|
||||||
$scope.old_time.from,
|
$scope.old_time.from,
|
||||||
$scope.old_time.to,
|
$scope.old_time.to,
|
||||||
@ -117,20 +120,22 @@ angular.module('kibana.trends', [])
|
|||||||
dashboard.current.index.interval
|
dashboard.current.index.interval
|
||||||
).then(function (p) {
|
).then(function (p) {
|
||||||
$scope.index = _.union(p,$scope.index);
|
$scope.index = _.union(p,$scope.index);
|
||||||
request = request.indices($scope.index[_segment])
|
request = request.indices($scope.index[_segment]);
|
||||||
process_results(request.doSearch());
|
process_results(request.doSearch());
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
process_results(request.indices($scope.index[_segment]).doSearch());
|
process_results(request.indices($scope.index[_segment]).doSearch(),_segment,query_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Populate scope when we have results
|
// Populate scope when we have results
|
||||||
function process_results(results) {
|
var process_results = function(results,_segment,query_id) {
|
||||||
results.then(function(results) {
|
results.then(function(results) {
|
||||||
|
|
||||||
$scope.panel.loading = false;
|
$scope.panel.loading = false;
|
||||||
if(_segment == 0) {
|
if(_segment === 0) {
|
||||||
$scope.hits = {};
|
$scope.hits = {};
|
||||||
$scope.data = [];
|
$scope.data = [];
|
||||||
query_id = $scope.query_id = new Date().getTime();
|
query_id = $scope.query_id = new Date().getTime();
|
||||||
@ -143,28 +148,28 @@ angular.module('kibana.trends', [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert facet ids to numbers
|
// Convert facet ids to numbers
|
||||||
var facetIds = _.map(_.keys(results.facets),function(k){if(!isNaN(k)){return parseInt(k)}})
|
var facetIds = _.map(_.keys(results.facets),function(k){if(!isNaN(k)){return parseInt(k, 10);}});
|
||||||
|
|
||||||
// Make sure we're still on the same query/queries
|
// Make sure we're still on the same query/queries
|
||||||
if($scope.query_id === query_id &&
|
if($scope.query_id === query_id &&
|
||||||
_.intersection(facetIds,query.ids).length == query.ids.length
|
_.intersection(facetIds,query.ids).length === query.ids.length
|
||||||
) {
|
) {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
_.each(query.ids, function(id) {
|
_.each(query.ids, function(id) {
|
||||||
var v = results.facets[id]
|
var v = results.facets[id];
|
||||||
var n = results.facets[id].count
|
var n = results.facets[id].count;
|
||||||
var o = results.facets['old_'+id].count
|
var o = results.facets['old_'+id].count;
|
||||||
|
|
||||||
var hits = {
|
var hits = {
|
||||||
new : _.isUndefined($scope.data[i]) || _segment == 0 ? n : $scope.data[i].hits.new+n,
|
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
|
old : _.isUndefined($scope.data[i]) || _segment === 0 ? o : $scope.data[i].hits.old+o
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.hits.new += n;
|
$scope.hits.new += n;
|
||||||
$scope.hits.old += o;
|
$scope.hits.old += o;
|
||||||
|
|
||||||
var percent = percentage(hits.old,hits.new) == null ?
|
var percent = percentage(hits.old,hits.new) == null ?
|
||||||
'?' : Math.round(percentage(hits.old,hits.new)*100)/100
|
'?' : Math.round(percentage(hits.old,hits.new)*100)/100;
|
||||||
// Create series
|
// Create series
|
||||||
$scope.data[i] = {
|
$scope.data[i] = {
|
||||||
info: query.list[id],
|
info: query.list[id],
|
||||||
@ -178,29 +183,29 @@ angular.module('kibana.trends', [])
|
|||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
if(_segment < $scope.index.length-1)
|
if(_segment < $scope.index.length-1) {
|
||||||
$scope.get_data(_segment+1,query_id)
|
$scope.get_data(_segment+1,query_id);
|
||||||
else
|
} else {
|
||||||
$scope.trends = $scope.data
|
$scope.trends = $scope.data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function percentage(x,y) {
|
function percentage(x,y) {
|
||||||
return x == 0 ? null : 100*(y-x)/x
|
return x === 0 ? null : 100*(y-x)/x;
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.set_refresh = function (state) {
|
$scope.set_refresh = function (state) {
|
||||||
$scope.refresh = state;
|
$scope.refresh = state;
|
||||||
}
|
};
|
||||||
|
|
||||||
$scope.close_edit = function() {
|
$scope.close_edit = function() {
|
||||||
if($scope.refresh)
|
if($scope.refresh) {
|
||||||
$scope.get_data();
|
$scope.get_data();
|
||||||
|
}
|
||||||
$scope.refresh = false;
|
$scope.refresh = false;
|
||||||
$scope.$emit('render');
|
$scope.$emit('render');
|
||||||
}
|
};
|
||||||
|
|
||||||
})
|
});
|
Loading…
Reference in New Issue
Block a user