mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
This commit is contained in:
parent
8fa2c7bafe
commit
0218afc961
2 changed files with 63 additions and 21 deletions
|
@ -30,7 +30,7 @@ import {
|
|||
import { TimeBuckets } from 'ui/time_buckets';
|
||||
import { mlAnomaliesTableService } from 'plugins/ml/components/anomalies_table/anomalies_table_service';
|
||||
import ContextChartMask from 'plugins/ml/timeseriesexplorer/context_chart_mask';
|
||||
import { findNearestChartPointToTime } from 'plugins/ml/timeseriesexplorer/timeseriesexplorer_utils';
|
||||
import { findChartPointForAnomalyTime } from 'plugins/ml/timeseriesexplorer/timeseriesexplorer_utils';
|
||||
import { mlEscape } from 'plugins/ml/util/string_utils';
|
||||
import { mlFieldFormatService } from 'plugins/ml/services/field_format_service';
|
||||
|
||||
|
@ -1017,11 +1017,11 @@ module.directive('mlTimeseriesChart', function (
|
|||
function highlightFocusChartAnomaly(record) {
|
||||
// Highlights the anomaly marker in the focus chart corresponding to the specified record.
|
||||
|
||||
// Find the anomaly marker which is closest in time to the source record.
|
||||
// Find the anomaly marker which corresponds to the time of the anomaly record.
|
||||
// Depending on the way the chart is aggregated, there may not be
|
||||
// a point at exactly the same time as the record being highlighted.
|
||||
const anomalyTime = record.source.timestamp;
|
||||
const markerToSelect = findNearestChartPointToTime(scope.focusChartData, anomalyTime);
|
||||
const markerToSelect = findChartPointForAnomalyTime(scope.focusChartData, anomalyTime);
|
||||
|
||||
// Render an additional highlighted anomaly marker on the focus chart.
|
||||
// TODO - plot anomaly markers for cases where there is an anomaly due
|
||||
|
|
|
@ -98,14 +98,15 @@ export function processDataForFocusAnomalies(
|
|||
anomalyRecords,
|
||||
timeFieldName) {
|
||||
|
||||
// Iterate through the anomaly records, adding anomalyScore properties
|
||||
// Iterate through the anomaly records, adding anomalyScore, function,
|
||||
// actual and typical properties, plus causes info if applicable,
|
||||
// to the chartData entries for anomalous buckets.
|
||||
_.each(anomalyRecords, (record) => {
|
||||
|
||||
// Look for a chart point with the same time as the record.
|
||||
// If none found, find closest time in chartData set.
|
||||
const recordTime = record[timeFieldName];
|
||||
let chartPoint = findNearestChartPointToTime(chartData, recordTime);
|
||||
let chartPoint = findChartPointForAnomalyTime(chartData, recordTime);
|
||||
|
||||
// TODO - handle case where there is an anomaly due to the absence of data
|
||||
// and there is no model plot.
|
||||
|
@ -121,23 +122,28 @@ export function processDataForFocusAnomalies(
|
|||
|
||||
if (chartPoint !== undefined) {
|
||||
// If chart aggregation interval > bucket span, there may be more than
|
||||
// one anomaly record in the interval, so get max record anomalyScore.
|
||||
chartPoint.anomalyScore = Math.max(_.get(chartPoint, 'anomalyScore', 0), record.record_score);
|
||||
chartPoint.function = record.function;
|
||||
// one anomaly record in the interval, so use the properties from
|
||||
// the record with the highest anomalyScore.
|
||||
const recordScore = record.record_score;
|
||||
const pointScore = chartPoint.anomalyScore;
|
||||
if (pointScore === undefined || pointScore < recordScore) {
|
||||
chartPoint.anomalyScore = recordScore;
|
||||
chartPoint.function = record.function;
|
||||
|
||||
if (_.has(record, 'actual')) {
|
||||
chartPoint.actual = record.actual;
|
||||
chartPoint.typical = record.typical;
|
||||
} else {
|
||||
const causes = _.get(record, 'causes', []);
|
||||
if (causes.length > 0) {
|
||||
chartPoint.byFieldName = record.by_field_name;
|
||||
chartPoint.numberOfCauses = causes.length;
|
||||
if (causes.length === 1) {
|
||||
// If only a single cause, copy actual and typical values to the top level.
|
||||
const cause = _.first(record.causes);
|
||||
chartPoint.actual = cause.actual;
|
||||
chartPoint.typical = cause.typical;
|
||||
if (_.has(record, 'actual')) {
|
||||
chartPoint.actual = record.actual;
|
||||
chartPoint.typical = record.typical;
|
||||
} else {
|
||||
const causes = _.get(record, 'causes', []);
|
||||
if (causes.length > 0) {
|
||||
chartPoint.byFieldName = record.by_field_name;
|
||||
chartPoint.numberOfCauses = causes.length;
|
||||
if (causes.length === 1) {
|
||||
// If only a single cause, copy actual and typical values to the top level.
|
||||
const cause = _.first(record.causes);
|
||||
chartPoint.actual = cause.actual;
|
||||
chartPoint.typical = cause.typical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,6 +171,7 @@ export function processScheduledEventsForChart(chartData, scheduledEvents) {
|
|||
return chartData;
|
||||
}
|
||||
|
||||
// Finds the chart point which is closest in time to the specified time.
|
||||
export function findNearestChartPointToTime(chartData, time) {
|
||||
let chartPoint;
|
||||
if(chartData === undefined) {
|
||||
|
@ -198,6 +205,41 @@ export function findNearestChartPointToTime(chartData, time) {
|
|||
} else {
|
||||
foundItem = previousItem;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chartPoint = foundItem;
|
||||
}
|
||||
|
||||
return chartPoint;
|
||||
}
|
||||
|
||||
// Finds the chart point which corresponds to an anomaly with the
|
||||
// specified time.
|
||||
export function findChartPointForAnomalyTime(chartData, anomalyTime) {
|
||||
let chartPoint;
|
||||
if(chartData === undefined) {
|
||||
return chartPoint;
|
||||
}
|
||||
|
||||
for (let i = 0; i < chartData.length; i++) {
|
||||
if (chartData[i].date.getTime() === anomalyTime) {
|
||||
chartPoint = chartData[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (chartPoint === undefined) {
|
||||
// Find the time of the point which falls immediately before the
|
||||
// time of the anomaly. This is the start of the chart 'bucket'
|
||||
// which contains the anomalous bucket.
|
||||
let foundItem;
|
||||
for (let i = 0; i < chartData.length; i++) {
|
||||
const itemTime = chartData[i].date.getTime();
|
||||
if (itemTime > anomalyTime) {
|
||||
foundItem = (i > 0) ? chartData[i - 1] : chartData[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue