Merge pull request #4940 from w33ble/clickable-metrics

Fix clickable legend filtering with multiple metrics
This commit is contained in:
Spencer 2015-09-21 13:45:56 -07:00
commit 6ee65f453a
5 changed files with 93 additions and 72 deletions

View file

@ -16,7 +16,7 @@ define(function () {
}
/**
* Returns an array of the aggConfigResult and parents up te branch
* Returns an array of the aggConfigResult and parents up the branch
* @returns {array} Array of aggConfigResults
*/
AggConfigResult.prototype.getPath = function () {

View file

@ -14,61 +14,79 @@ describe('getPoint', function () {
getPoint = Private(require('ui/agg_response/point_series/_get_point'));
}));
it('properly unwraps and scales values without a series', function () {
var row = [ { value: 1 }, { value: 2 }, { value: 3 } ];
var xAspect = { i: 0 };
var seriesAspect = null;
var yScale = 5;
var yAspect = { i: 1 };
var zAspect = { i: 2 };
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect, zAspect);
describe('Without series aspect', function () {
var seriesAspect;
var xAspect;
var yAspect;
var yScale;
expect(point)
.to.have.property('x', 1)
.and.have.property('y', 10)
.and.have.property('z', 3)
.and.have.property('aggConfigResult', row[1])
.and.not.have.property('series');
beforeEach(function () {
seriesAspect = null;
xAspect = { i: 0 };
yAspect = { i: 1 };
yScale = 5;
});
it('properly unwraps and scales values', function () {
var row = [ { value: 1 }, { value: 2 }, { value: 3 } ];
var zAspect = { i: 2 };
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect, zAspect);
expect(point)
.to.have.property('x', 1)
.and.have.property('y', 10)
.and.have.property('z', 3)
.and.have.property('aggConfigResult', row[1])
.and.not.have.property('series');
});
it('ignores points with a y value of NaN', function () {
var row = [ { value: 1 }, { value: 'NaN' }];
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect);
expect(point).to.be(void 0);
});
});
it('properly unwraps and scales values with a series', function () {
var row = [ { value: 1 }, { value: 2 }, { value: 3 }];
var xAspect = { i: 0 };
var seriesAspect = { i: 1, agg: identFormatted };
var yScale = null;
var yAspect = { i: 2 };
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect);
describe('With series aspect', function () {
var row;
var xAspect;
var yAspect;
var yScale;
expect(point)
.to.have.property('x', 1)
.and.have.property('series', 2)
.and.have.property('y', 3)
.and.have.property('aggConfigResult', row[2]);
beforeEach(function () {
row = [ { value: 1 }, { value: 2 }, { value: 3 }];
xAspect = { i: 0 };
yAspect = { i: 2 };
yScale = null;
});
it('properly unwraps and scales values', function () {
var seriesAspect = { i: 1, agg: identFormatted };
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect);
expect(point)
.to.have.property('x', 1)
.and.have.property('series', 2)
.and.have.property('y', 3)
.and.have.property('aggConfigResult', row[2]);
});
it('properly formats series values', function () {
var seriesAspect = { i: 1, agg: truthFormatted };
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect);
expect(point)
.to.have.property('x', 1)
.and.have.property('series', true)
.and.have.property('y', 3)
.and.have.property('aggConfigResult', row[2]);
});
it ('adds the aggConfig to the points', function () {
var seriesAspect = { i: 1, agg: truthFormatted};
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect);
expect(point).to.have.property('aggConfig', truthFormatted);
});
});
it('properly formats series values', function () {
var row = [ { value: 1 }, { value: 2 }, { value: 3 } ];
var xAspect = { i: 0 };
var seriesAspect = { i: 1, agg: truthFormatted };
var yScale = null;
var yAspect = { i: 2 };
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect);
expect(point)
.to.have.property('x', 1)
.and.have.property('series', true)
.and.have.property('y', 3)
.and.have.property('aggConfigResult', row[2]);
});
it('ignores points with a y value of NaN', function () {
var row = [ { value: 1 }, { value: 'NaN' }];
var xAspect = { i: 0 };
var seriesAspect = null;
var yScale = 5;
var yAspect = { i: 1 };
var point = getPoint(xAspect, seriesAspect, yScale, row, yAspect);
expect(point).to.be(void 0);
});
});

View file

@ -26,6 +26,7 @@ define(function (require) {
}
if (series) {
point.aggConfig = series.agg;
point.series = series.agg.fieldFormatter()(unwrap(row[series.i]));
}

View file

@ -12,7 +12,6 @@ define(function (require) {
var series = _(rows)
.transform(function (series, row) {
if (!multiY) {
var point = partGetPoint(row, aspects.y, aspects.z);
if (point) addToSiri(series, point, point.series);

View file

@ -3,6 +3,17 @@ define(function (require) {
var dedupFilters = require('./lib/dedupFilters');
var uniqFilters = require('./lib/uniqFilters');
// given an object or array of objects, return the value of the passed param
// if the param is missing, return undefined
function findByParam(values, param) {
if (_.isArray(values)) { // point series chart
var index = _.findIndex(values, param);
if (index === -1) return;
return values[index][param];
}
return values[param]; // pie chart
}
return function (Notifier) {
return function ($state) {
return function (event) {
@ -17,32 +28,24 @@ define(function (require) {
if (event.point.orig) {
aggConfigResult = event.point.orig.aggConfigResult;
} else if (event.point.values) {
aggConfigResult = findAggConfig(event.point.values);
aggConfigResult = findByParam(event.point.values, 'aggConfigResult');
} else {
aggConfigResult = event.point.aggConfigResult;
}
function findAggConfig(values) {
if (_.isArray(values)) { // point series chart
var index = _.findIndex(values, 'aggConfigResult');
return values[index].aggConfigResult;
}
return values.aggConfigResult; // pie chart
}
function findLabel(obj) {
// TODO: find out if there is always a fieldFormatter
var formatter = obj.aggConfig.fieldFormatter();
return formatter(obj.key) === event.label;
}
if (aggConfigResult) {
var isLegendLabel = !!event.point.values;
var results = _.filter(aggConfigResult.getPath(), { type: 'bucket' });
var aggBuckets = _.filter(aggConfigResult.getPath(), { type: 'bucket' });
if (isLegendLabel) results = _.filter(results, findLabel); // filter results array by legend label
// For legend clicks, use the last bucket in the path
if (isLegendLabel) {
// series data has multiple values, use aggConfig on the first
// hierarchical data values is an object with the addConfig
var aggConfig = findByParam(event.point.values, 'aggConfig');
aggBuckets = aggBuckets.filter((result) => result.aggConfig && result.aggConfig === aggConfig);
}
var filters = _(results)
var filters = _(aggBuckets)
.map(function (result) {
try {
return result.createFilter();