// 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 = []; obj = kbn.flatten_json(obj._source) for (field in obj) { field_array.push(field); } return field_array.sort(); } kbn.get_all_fields = function(data) { var fields = []; _.each(data,function(hit) { fields = _.uniq(fields.concat(_.keys(hit))) }) // Remove stupid angular key fields = _.without(fields,'$$hashKey') return fields; } kbn.has_field = function(obj,field) { var obj_fields = get_object_fields(obj); if (_.inArray(obj_fields,field) < 0) { return false; } else { return true; } } kbn.get_related_fields = function(docs,field) { var field_array = [] _.each(docs, function(doc) { var keys = _.keys(doc) if(_.contains(keys,field)) field_array = field_array.concat(keys) }) var counts = _.countBy(_.without(field_array,field),function(field){return field;}); return counts; } kbn.recurse_field_dots = function(object,field) { var value = null; if (typeof object[field] != 'undefined') value = object[field]; else if (nested = field.match(/(.*?)\.(.*)/)) if(typeof object[nested[1]] != 'undefined') value = (typeof object[nested[1]][nested[2]] != 'undefined') ? object[nested[1]][nested[2]] : recurse_field_dots( object[nested[1]],nested[2]); return value; } // Probably useless now, leaving for cases where you might not want // a flat dot notated data structure kbn.get_field_value = function(object,field,opt) { var value = kbn.recurse_field_dots(object['_source'],field); if(value === null) return '' if(_.isArray(value)) if (opt == 'raw') { return value; } else { var complex = false; _.each(value, function(el, index) { if (typeof(el) == 'object') { complex = true; } }) if (complex) { return JSON.stringify(value, null, 4); } return value.toString(); } if(typeof value === 'object' && value != null) // Leaving this out for now //return opt == 'raw' ? value : JSON.stringify(value,null,4) return JSON.stringify(value,null,4) return (value != null) ? value.toString() : ''; } kbn.top_field_values = function(docs,field,count) { var counts = _.countBy(_.pluck(docs,field),function(field){ return _.isUndefined(field) ? '' : field; }); return _.pairs(counts).sort(function(a, b) { return a[1] - b[1] }).reverse().slice(0,count) } /** * Calculate a graph interval * * from:: Date object containing the start time * to:: Date object containing the finish time * size:: Calculate to approximately this many bars * user_interval:: User specified histogram interval * */ kbn.calculate_interval = function(from,to,size,user_interval) { if(_.isObject(from)) from = from.valueOf(); if(_.isObject(to)) to = to.valueOf(); return user_interval == 0 ? kbn.round_interval((to - from)/size) : user_interval; } kbn.round_interval = function(interval) { switch (true) { // 0.5s case (interval <= 500): return 100; // 0.1s // 5s case (interval <= 5000): return 1000; // 1s // 7.5s case (interval <= 7500): return 5000; // 5s // 15s case (interval <= 15000): return 10000; // 10s // 45s case (interval <= 45000): return 30000; // 30s // 3m case (interval <= 180000): return 60000; // 1m // 9m case (interval <= 450000): return 300000; // 5m // 20m case (interval <= 1200000): return 600000; // 10m // 45m case (interval <= 2700000): return 1800000; // 30m // 2h case (interval <= 7200000): return 3600000; // 1h // 6h case (interval <= 21600000): return 10800000; // 3h // 24h case (interval <= 86400000): return 43200000; // 12h // 48h case (interval <= 172800000): return 86400000; // 24h // 1w case (interval <= 604800000): return 86400000; // 24h // 3w case (interval <= 1814400000): return 604800000; // 1w // 2y case (interval < 3628800000): return 2592000000; // 30d default: return 31536000000; // 1y } } kbn.secondsToHms = function(seconds){ var numyears = Math.floor(seconds / 31536000); if(numyears){ return numyears + 'y'; } var numdays = Math.floor((seconds % 31536000) / 86400); if(numdays){ return numdays + 'd'; } var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); if(numhours){ return numhours + 'h'; } var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); if(numminutes){ return numminutes + 'm'; } var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60; if(numseconds){ return numseconds + 's'; } return 'less then a second'; //'just now' //or other string you like; } kbn.to_percent = function(number,outof) { return Math.round((number/outof)*10000)/100 + "%"; } kbn.addslashes = function(str) { str = str.replace(/\\/g, '\\\\'); str = str.replace(/\'/g, '\\\''); str = str.replace(/\"/g, '\\"'); str = str.replace(/\0/g, '\\0'); return str; } // histogram & trends kbn.interval_to_seconds = function(string) { var matches = string.match(/(\d+)([Mwdhmsy])/); switch (matches[2]) { case 'y': return matches[1]*31536000;; case 'M': return matches[1]*2592000;; case 'w': return matches[1]*604800;; case 'd': return matches[1]*86400;; case 'h': return matches[1]*3600;; case 'm': return matches[1]*60;; case 's': return matches[1]; } } // This should go away, moment.js can do this kbn.time_ago = function(string) { return new Date(new Date().getTime() - (kbn.interval_to_seconds(string)*1000)) } // LOL. hahahahaha. DIE. kbn.flatten_json = function(object,root,array) { if (typeof array === 'undefined') var array = {}; if (typeof root === 'undefined') var root = ''; for(var index in object) { var obj = object[index] var rootname = root.length == 0 ? index : root + '.' + index; if(typeof obj == 'object' ) { if(_.isArray(obj)) { if(obj.length > 0 && typeof obj[0] === 'object') { var strval = ''; for (var objidx = 0, objlen = obj.length; objidx < objlen; objidx++) { if (objidx > 0) { strval = strval + ', '; } strval = strval + JSON.stringify(obj[objidx]); } array[rootname] = strval; } else if(obj.length === 1 && _.isNumber(obj[0])) { array[rootname] = parseFloat(obj[0]); } else { array[rootname] = typeof obj === 'undefined' ? null : obj; } } else { kbn.flatten_json(obj,rootname,array) } } else { array[rootname] = typeof obj === 'undefined' ? null : obj; } } return kbn.sortObj(array); } kbn.xmlEnt = function(value) { if(_.isString(value)) { var stg1 = value.replace(//g, '>') .replace(/\r\n/g, '
') .replace(/\r/g, '
') .replace(/\n/g, '
') .replace(/\t/g, '    ') .replace(/ /g, '  ') .replace(/<del>/g, '') .replace(/<\/del>/g, ''); return stg1; } else { return value; } } kbn.sortObj = function(arr) { // Setup Arrays var sortedKeys = new Array(); var sortedObj = {}; // Separate keys and sort them for (var i in arr) { sortedKeys.push(i); } sortedKeys.sort(); // Reconstruct sorted obj based on keys for (var i in sortedKeys) { sortedObj[sortedKeys[i]] = arr[sortedKeys[i]]; } return sortedObj; } }).call(this); /* UNDERSCORE.js Mixins */ _.mixin({ move: function (array, fromIndex, toIndex) { array.splice(toIndex, 0, array.splice(fromIndex, 1)[0] ); return array; } }); _.mixin({ remove: function (array, index) { array.splice(index, 1); return array; } });