Skip to content

Commit

Permalink
[ML] Anomaly Explorer: if filter includes wildcard ensure matching sw…
Browse files Browse the repository at this point in the history
…imlanes are not masked (#65384) (#66078)

* if wildcard search no mask for matching swimlanes

* update swimlane proptypes

* add helper function

* add tests for helper function
  • Loading branch information
alvarezmelissa87 committed May 12, 2020
1 parent 53ba250 commit 662f24c
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"laneLabels": [
"View by"
],
"points": [
{
"laneLabel": "test-1",
"time": 1486425600,
"value": 0
},
{
"laneLabel": "test-2",
"time": 1486440000,
"value": 0.01107053
},
{
"laneLabel": "other-3",
"time": 1486454400,
"value": 0.1870243
},
{
"laneLabel": "other-4",
"time": 1486468800,
"value": 0.5947769
},
{
"laneLabel": "other-5",
"time": 1486483200,
"value": 0
}
],
"interval": 14400
}
11 changes: 10 additions & 1 deletion x-pack/plugins/ml/public/application/explorer/explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import { AnomaliesTable } from '../components/anomalies_table/anomalies_table';
import { ResizeChecker } from '../../../../../../src/plugins/kibana_utils/public';
import { getTimefilter, getToastNotifications } from '../util/dependency_cache';
import { MlTooltipComponent } from '../components/chart_tooltip';
import { hasMatchingPoints } from './has_matching_points';

function mapSwimlaneOptionsToEuiOptions(options) {
return options.map(option => ({
Expand Down Expand Up @@ -284,6 +285,7 @@ export class Explorer extends React.Component {
annotationsData,
chartsData,
filterActive,
filteredFields,
filterPlaceHolder,
indexPattern,
influencers,
Expand Down Expand Up @@ -418,6 +420,7 @@ export class Explorer extends React.Component {
<ExplorerSwimlane
chartWidth={swimlaneContainerWidth}
filterActive={filterActive}
filteredFields={filteredFields}
maskAll={maskAll}
timeBuckets={this.timeBuckets}
swimlaneCellClick={this.swimlaneCellClick}
Expand Down Expand Up @@ -499,7 +502,13 @@ export class Explorer extends React.Component {
<ExplorerSwimlane
chartWidth={swimlaneContainerWidth}
filterActive={filterActive}
maskAll={maskAll}
maskAll={
maskAll &&
!hasMatchingPoints({
filteredFields,
swimlaneData: viewBySwimlaneData,
})
}
timeBuckets={this.timeBuckets}
swimlaneCellClick={this.swimlaneCellClick}
swimlaneData={viewBySwimlaneData}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ export class ExplorerSwimlane extends React.Component<ExplorerSwimlaneProps> {
if (selectedCellTimes.length > 0) {
this.highlightOverall(selectedCellTimes);
}
this.maskIrrelevantSwimlanes(!!maskAll);
this.maskIrrelevantSwimlanes(Boolean(maskAll));
} else {
this.clearSelection();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import mockViewBySwimlaneData from './__mocks__/mock_viewby_swimlane.json';
import { hasMatchingPoints } from './has_matching_points';

const filteredFieldsMatch = ['test@kuery-wildcard@'];
const filteredFieldsNoMatch = ['no-match@kuery-wildcard@', 'nonexistant'];

describe('hasMatchingPoints', () => {
test('is true', () => {
expect(
hasMatchingPoints({
filteredFields: filteredFieldsMatch,
swimlaneData: mockViewBySwimlaneData,
})
).toBe(true);
});

test('is false', () => {
expect(
hasMatchingPoints({
filteredFields: filteredFieldsNoMatch,
swimlaneData: mockViewBySwimlaneData,
})
).toBe(false);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { ExplorerState } from './reducers';
import { OverallSwimlaneData, SwimlaneData } from './explorer_utils';

interface HasMatchingPointsParams {
filteredFields?: ExplorerState['filteredFields'];
swimlaneData: SwimlaneData | OverallSwimlaneData;
}

export const hasMatchingPoints = ({
filteredFields = [],
swimlaneData,
}: HasMatchingPointsParams): boolean => {
// If filtered fields includes a wildcard search maskAll only if there are no points matching the pattern
const wildCardField = filteredFields.find(field => /\@kuery-wildcard\@$/.test(field));
const substring =
wildCardField !== undefined ? wildCardField.replace(/\@kuery-wildcard\@$/, '') : null;

return (
substring !== null &&
swimlaneData.points.some(point => {
return point.laneLabel.includes(substring);
})
);
};

0 comments on commit 662f24c

Please sign in to comment.