Merge pull request #3470 from drej82/master

Add percentile ranks metric support
This commit is contained in:
Spencer 2015-04-03 10:20:52 -07:00
commit e4d45e6e75
7 changed files with 112 additions and 12 deletions

View file

@ -8,14 +8,16 @@ define(function (require) {
require('modules')
.get('kibana')
.directive('percentList', function ($parse) {
.directive('valuesList', function ($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function ($scope, $el, attrs, ngModelController) {
var $setModel = $parse(attrs.ngModel).assign;
var $repeater = $el.closest('[ng-repeat]');
var $listGetter = $parse(attrs.percentList);
var $listGetter = $parse(attrs.valuesList);
var $minValue = $parse(attrs.valuesListMin);
var $maxValue = $parse(attrs.valuesListMax);
var handlers = {
up: change(add, 1),
@ -42,7 +44,7 @@ define(function (require) {
}
function $get(dir) {
return $repeater[dir]().find('[percent-list]');
return $repeater[dir]().find('[values-list]');
}
function go(dir) {
@ -122,8 +124,8 @@ define(function (require) {
if (isNaN(num)) return INVALID;
var list = $listGetter($scope);
var min = list[$scope.$index - 1] || 0;
var max = list[$scope.$index + 1] || 100;
var min = list[$scope.$index - 1] || $minValue($scope);
var max = list[$scope.$index + 1] || $maxValue($scope);
if (num <= min || num >= max) return INVALID;
@ -140,7 +142,7 @@ define(function (require) {
}
], function () {
var valid = parse(ngModelController.$viewValue) !== INVALID;
ngModelController.$setValidity('percentList', valid);
ngModelController.$setValidity('valuesList', valid);
});
function validate(then) {
@ -148,7 +150,7 @@ define(function (require) {
var value = parse(input);
var valid = value !== INVALID;
value = valid ? value : void 0;
ngModelController.$setValidity('percentList', valid);
ngModelController.$setValidity('valuesList', valid);
then && then(input, value);
return value;
};

View file

@ -6,7 +6,9 @@
<input
ng-model="agg.params.percents[$index]"
percent-list="agg.params.percents"
values-list="agg.params.percents"
values-list-min="0"
values-list-max="100"
input-focus
class="form-control">

View file

@ -0,0 +1,30 @@
<div class="form-group" ng-controller="agg.type.params.byName.values.controller">
<label>Values</label>
<div
ng-repeat="value in agg.params.values track by $index"
class="form-group vis-editor-agg-form-row vis-editor-agg-form-row">
<input
ng-model="agg.params.values[$index]"
values-list="agg.params.values"
values-list-min="0"
input-focus
class="form-control">
<button type="button" ng-click="remove($index, 1)" class="btn btn-danger btn-xs">
<i class="fa fa-times"></i>
</button>
</div>
<input ng-model="validLength" name="validLength" required type="hidden">
<p ng-show="aggForm.validLength.$invalid" class="text-danger text-center">
You must specify at least one value
</p>
<button
ng-click="add()"
type="button"
class="sidebar-item-button primary">
<i class="fa fa-plus"></i> Add value
</button>
</div>

View file

@ -11,7 +11,8 @@ define(function (require) {
Private(require('components/agg_types/metrics/max')),
Private(require('components/agg_types/metrics/std_deviation')),
Private(require('components/agg_types/metrics/cardinality')),
Private(require('components/agg_types/metrics/percentiles'))
Private(require('components/agg_types/metrics/percentiles')),
Private(require('components/agg_types/metrics/percentileranks'))
],
buckets: [
Private(require('components/agg_types/buckets/date_histogram')),

View file

@ -0,0 +1,63 @@
define(function (require) {
return function AggTypeMetricPercentileRanksProvider(Private) {
var _ = require('lodash');
var MetricAggType = Private(require('components/agg_types/metrics/_metric_agg_type'));
var getResponseAggConfig = Private(require('components/agg_types/metrics/_get_response_agg_config'));
require('components/agg_types/controls/_values_list');
var valuesEditor = require('text!components/agg_types/controls/values.html');
var valueProps = {
makeLabel: function () {
return 'Percentile rank ' + this.key + ' of "' + this.fieldDisplayName() + '"';
}
};
return new MetricAggType({
name: 'percentile_ranks',
title: 'Percentile Ranks',
makeLabel: function (agg) {
return 'Percentile ranks of ' + agg.fieldDisplayName();
},
params: [
{
name: 'field',
filterFieldTypes: 'number'
},
{
name: 'values',
editor: valuesEditor,
default: [10],
controller: function ($scope) {
$scope.remove = function (index) {
$scope.agg.params.values.splice(index, 1);
};
$scope.add = function () {
$scope.agg.params.values.push(_.last($scope.agg.params.values) + 1);
};
$scope.$watchCollection('agg.params.values', function (values) {
$scope.validLength = _.size(values) || null;
});
}
}
],
getResponseAggs: function (agg) {
var ValueAggConfig = getResponseAggConfig(agg, valueProps);
return agg.params.values.map(function (value) {
return new ValueAggConfig(value);
});
},
getValue: function (agg, bucket) {
// values for 1, 5, and 10 will come back as 1.0, 5.0, and 10.0 so we
// parse the keys and respond with the value that matches
return _.find(bucket[agg.parentId].values, function (value, key) {
return agg.key === parseFloat(key);
});
}
});
};
});

View file

@ -6,7 +6,7 @@ define(function (require) {
var getResponseAggConfig = Private(require('components/agg_types/metrics/_get_response_agg_config'));
var ordinalSuffix = require('utils/ordinal_suffix');
require('components/agg_types/controls/_percent_list');
require('components/agg_types/controls/_values_list');
var percentEditor = require('text!components/agg_types/controls/percents.html');
var valueProps = {

View file

@ -4,7 +4,7 @@ define(function (require) {
var _ = require('lodash');
var simulateKeys = require('test_utils/simulate_keys');
require('components/agg_types/controls/_percent_list');
require('components/agg_types/controls/_values_list');
var $el;
var $scope;
@ -20,7 +20,9 @@ define(function (require) {
$('<input>')
.attr('ng-model', 'vals[$index]')
.attr('ng-repeat', 'val in vals')
.attr('percent-list', 'vals')
.attr('values-list', 'vals')
.attr('values-list-min', '0')
.attr('values-list-max', '100')
);
compile = function (vals) {
$scope.vals = vals || [];