app.panels.trends.module.js Maven / Gradle / Ivy
The newest version!
/** @scratch /panels/5
*
* include::panels/trends.asciidoc[]
*/
/** @scratch /panels/trends/0
*
* == trends
* Status: *Beta*
*
* A stock-ticker style representation of how queries are moving over time. For example, if the
* time is 1:10pm, your time picker was set to "Last 10m", and the "Time Ago" parameter was set to
* "1h", the panel would show how much the query results have changed since 12:00-12:10pm
*
*/
define([
'angular',
'app',
'lodash',
'kbn'
],
function (angular, app, _, kbn) {
'use strict';
var module = angular.module('kibana.panels.trends', []);
app.useModule(module);
module.controller('trends', function($scope, kbnIndex, querySrv, dashboard, filterSrv) {
$scope.panelMeta = {
modals : [
{
description: "Inspect",
icon: "icon-info-sign",
partial: "app/partials/inspector.html",
show: $scope.panel.spyable
}
],
editorTabs : [
{title:'Queries', src:'app/partials/querySelect.html'}
],
status : "Beta",
description : "A stock-ticker style representation of how queries are moving over time. "+
"For example, if the time is 1:10pm, your time picker was set to \"Last 10m\", and the \"Time "+
"Ago\" parameter was set to '1h', the panel would show how much the query results have changed"+
" since 12:00-12:10pm"
};
// Set and populate defaults
var _d = {
/** @scratch /panels/trends/5
*
* === Parameters
*
* ago:: A date math formatted string describing the relative time period to compare the
* queries to.
*/
ago : '1d',
/** @scratch /panels/trends/5
* arrangement:: `horizontal' or `vertical'
*/
arrangement : 'vertical',
/** @scratch /panels/trends/5
* reverse:: true or false. If true, use red for positive, green for negative
*/
reverse : false,
/** @scratch /panels/trends/5
* spyable:: Set to false to disable the inspect icon
*/
spyable: true,
/** @scratch /panels/trends/5
*
* ==== Queries
* queries object:: This object describes the queries to use on this panel.
* queries.mode::: Of the queries available, which to use. Options: +all, pinned, unpinned, selected+
* queries.ids::: In +selected+ mode, which query ids are selected.
*/
queries : {
mode : 'all',
ids : []
},
style : { "font-size": '14pt'},
};
_.defaults($scope.panel,_d);
$scope.init = function () {
$scope.hits = 0;
$scope.$on('refresh', function(){$scope.get_data();});
$scope.get_data();
};
$scope.get_data = function(segment,query_id) {
delete $scope.panel.error;
$scope.panelMeta.loading = true;
// Make sure we have everything for the request to complete
if(dashboard.indices.length === 0) {
return;
} else {
$scope.index = segment > 0 ? $scope.index : dashboard.indices;
}
// Determine a time field
var timeField = _.uniq(_.pluck(filterSrv.getByType('time'),'field'));
if(timeField.length > 1) {
$scope.panel.error = "Time field must be consistent amongst time filters";
return;
} else if(timeField.length === 0) {
$scope.panel.error = "A time filter must exist for this panel to function";
return;
} else {
timeField = timeField[0];
}
// This logic can be simplified greatly with the new kbn.parseDate
$scope.time = filterSrv.timeRange('last');
$scope.old_time = {
from : new Date($scope.time.from.getTime() - kbn.interval_to_ms($scope.panel.ago)).valueOf(),
to : new Date($scope.time.to.getTime() - kbn.interval_to_ms($scope.panel.ago)).valueOf()
};
var _segment = _.isUndefined(segment) ? 0 : segment;
var request = $scope.ejs.Request();
var _ids_without_time = _.difference(filterSrv.ids,filterSrv.idsByType('time'));
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
// Build the question part of the query
_.each(queries, function(query) {
var q = $scope.ejs.FilteredQuery(
querySrv.toEjsObj(query),
filterSrv.getBoolFilter(filterSrv.ids()));
request = request
.facet($scope.ejs.QueryFacet(query.id)
.query(q)
).size(0);
});
// And again for the old time period
_.each(queries, function(query) {
var q = $scope.ejs.FilteredQuery(
querySrv.toEjsObj(query),
filterSrv.getBoolFilter(_ids_without_time).must(
$scope.ejs.RangeFilter(timeField)
.from($scope.old_time.from)
.to($scope.old_time.to)
));
request = request
.facet($scope.ejs.QueryFacet("old_"+query.id)
.query(q)
).size(0);
});
// Populate the inspector panel
$scope.inspector = request.toJSON();
// If we're on the first segment we need to get our indices
if (_segment === 0) {
kbnIndex.indices(
$scope.old_time.from,
$scope.old_time.to,
dashboard.current.index.pattern,
dashboard.current.index.interval
).then(function (p) {
$scope.index = _.union(p,$scope.index);
process_results($scope.ejs.doSearch($scope.index[_segment], request),_segment,query_id);
});
} else {
process_results($scope.ejs.doSearch($scope.index[_segment], request),_segment,query_id);
}
};
// Populate scope when we have results
var process_results = function(results,_segment,query_id) {
results.then(function(results) {
$scope.panelMeta.loading = false;
if(_segment === 0) {
$scope.hits = {};
$scope.data = [];
query_id = $scope.query_id = new Date().getTime();
}
// Check for error and abort if found
if(!(_.isUndefined(results.error))) {
$scope.panel.error = $scope.parse_error(results.error);
return;
}
// Make sure we're still on the same query/queries
if($scope.query_id === query_id) {
var i = 0;
var queries = querySrv.getQueryObjs($scope.panel.queries.ids);
_.each(queries, function(query) {
var n = results.facets[query.id].count;
var o = results.facets['old_'+query.id].count;
var hits = {
new : _.isUndefined($scope.data[i]) || _segment === 0 ? n : $scope.data[i].hits.new+n,
old : _.isUndefined($scope.data[i]) || _segment === 0 ? o : $scope.data[i].hits.old+o
};
$scope.hits.new += n;
$scope.hits.old += o;
var percent = percentage(hits.old,hits.new) == null ?
'?' : Math.round(percentage(hits.old,hits.new)*100)/100;
// Create series
$scope.data[i] = {
info: query,
hits: {
new : hits.new,
old : hits.old
},
percent: percent
};
i++;
});
$scope.$emit('render');
if(_segment < $scope.index.length-1) {
$scope.get_data(_segment+1,query_id);
} else {
$scope.trends = $scope.data;
}
}
});
};
function percentage(x,y) {
return x === 0 ? null : 100*(y-x)/x;
}
$scope.set_refresh = function (state) {
$scope.refresh = state;
};
$scope.close_edit = function() {
if($scope.refresh) {
$scope.get_data();
}
$scope.refresh = false;
$scope.$emit('render');
};
});
});
© 2015 - 2025 Weber Informatics LLC | Privacy Policy