[ML] Correctly pass on severity value to anomaly explorer charts. (#55207) (#55328)

- Fixes passing on the severity value correctly to anomaly explorer charts. The wrong value of undefined being passed down caused anomaly markers not showing up.
- This bug surfaced that the severity value was never applied to filter multi-bucket anomalies which is now also fixed by this PR.
- Adds a check if topInfluencers is an array.
This commit is contained in:
Walter Rafelsberger 2020-01-20 17:04:50 +01:00 committed by GitHub
parent 7e365acbf9
commit 6c87958eb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 12 deletions

View file

@ -15,6 +15,7 @@ import { AppStateSelectedCells } from '../explorer/explorer_utils';
declare interface ExplorerProps { declare interface ExplorerProps {
explorerState: ExplorerState; explorerState: ExplorerState;
severity: number;
showCharts: boolean; showCharts: boolean;
setSelectedCells: (swimlaneSelectedCells: AppStateSelectedCells) => void; setSelectedCells: (swimlaneSelectedCells: AppStateSelectedCells) => void;
} }

View file

@ -96,6 +96,7 @@ export class Explorer extends React.Component {
static propTypes = { static propTypes = {
explorerState: PropTypes.object.isRequired, explorerState: PropTypes.object.isRequired,
setSelectedCells: PropTypes.func.isRequired, setSelectedCells: PropTypes.func.isRequired,
severity: PropTypes.number.isRequired,
showCharts: PropTypes.bool.isRequired, showCharts: PropTypes.bool.isRequired,
}; };
@ -260,7 +261,7 @@ export class Explorer extends React.Component {
}; };
render() { render() {
const { showCharts } = this.props; const { showCharts, severity } = this.props;
const { const {
annotationsData, annotationsData,
@ -276,7 +277,6 @@ export class Explorer extends React.Component {
queryString, queryString,
selectedCells, selectedCells,
selectedJobs, selectedJobs,
severity,
swimlaneContainerWidth, swimlaneContainerWidth,
tableData, tableData,
tableQueryString, tableQueryString,

View file

@ -53,7 +53,7 @@ export const ExplorerChartSingleMetric = injectI18n(
static propTypes = { static propTypes = {
tooManyBuckets: PropTypes.bool, tooManyBuckets: PropTypes.bool,
seriesConfig: PropTypes.object, seriesConfig: PropTypes.object,
severity: PropTypes.number, severity: PropTypes.number.isRequired,
}; };
componentDidMount() { componentDidMount() {
@ -312,13 +312,16 @@ export const ExplorerChartSingleMetric = injectI18n(
}) })
.on('mouseout', () => mlChartTooltipService.hide()); .on('mouseout', () => mlChartTooltipService.hide());
const isAnomalyVisible = d =>
_.has(d, 'anomalyScore') && Number(d.anomalyScore) >= severity;
// Update all dots to new positions. // Update all dots to new positions.
dots dots
.attr('cx', d => lineChartXScale(d.date)) .attr('cx', d => lineChartXScale(d.date))
.attr('cy', d => lineChartYScale(d.value)) .attr('cy', d => lineChartYScale(d.value))
.attr('class', d => { .attr('class', d => {
let markerClass = 'metric-value'; let markerClass = 'metric-value';
if (_.has(d, 'anomalyScore') && Number(d.anomalyScore) >= severity) { if (isAnomalyVisible(d)) {
markerClass += ` anomaly-marker ${getSeverityWithLow(d.anomalyScore).id}`; markerClass += ` anomaly-marker ${getSeverityWithLow(d.anomalyScore).id}`;
} }
return markerClass; return markerClass;
@ -328,9 +331,7 @@ export const ExplorerChartSingleMetric = injectI18n(
const multiBucketMarkers = lineChartGroup const multiBucketMarkers = lineChartGroup
.select('.chart-markers') .select('.chart-markers')
.selectAll('.multi-bucket') .selectAll('.multi-bucket')
.data( .data(data.filter(d => isAnomalyVisible(d) && showMultiBucketAnomalyMarker(d) === true));
data.filter(d => d.anomalyScore !== null && showMultiBucketAnomalyMarker(d) === true)
);
// Remove multi-bucket markers that are no longer needed // Remove multi-bucket markers that are no longer needed
multiBucketMarkers.exit().remove(); multiBucketMarkers.exit().remove();

View file

@ -280,11 +280,13 @@ export function loadViewByTopFieldValuesForSelectedTime(
const topFieldValues = []; const topFieldValues = [];
const topInfluencers = resp.influencers[viewBySwimlaneFieldName]; const topInfluencers = resp.influencers[viewBySwimlaneFieldName];
topInfluencers.forEach(influencerData => { if (Array.isArray(topInfluencers)) {
if (influencerData.maxAnomalyScore > 0) { topInfluencers.forEach(influencerData => {
topFieldValues.push(influencerData.influencerFieldValue); if (influencerData.maxAnomalyScore > 0) {
} topFieldValues.push(influencerData.influencerFieldValue);
}); }
});
}
resolve(topFieldValues); resolve(topFieldValues);
}); });
} else { } else {

View file

@ -184,6 +184,7 @@ const ExplorerUrlStateManager: FC<ExplorerUrlStateManagerProps> = ({ jobsWithTim
explorerState, explorerState,
setSelectedCells, setSelectedCells,
showCharts, showCharts,
severity: tableSeverity.val,
}} }}
/> />
</div> </div>