[8.x] [ML] Anomaly explorer: Show Data Gaps and Connect Anomalous Points on Single Metric Charts (#194119) (#194426)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ML] Anomaly explorer: Show Data Gaps and Connect Anomalous Points on
Single Metric Charts
(#194119)](https://github.com/elastic/kibana/pull/194119)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Robert
Jaszczurek","email":"92210485+rbrtj@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-09-30T12:17:29Z","message":"[ML]
Anomaly explorer: Show Data Gaps and Connect Anomalous Points on Single
Metric Charts (#194119)\n\n## Summary\r\n\r\nFix for
[#193885](https://github.com/elastic/kibana/issues/193885)\r\n\r\nSingle
metric viewer:\r\n![Screenshot 2024-09-26 at 13
31\r\n35](https://github.com/user-attachments/assets/3576758e-9cb1-4c55-bd84-40f2095cc54f)\r\n\r\nAnomaly
explorer:\r\n| Before | After |\r\n| ------------- | -------------
|\r\n|\r\n![image](https://github.com/user-attachments/assets/89f48abd-26ac-4dd4-ab10-b1c8198f50ff)\r\n|
![Screenshot 2024-09-26 at 13
32\r\n05](https://github.com/user-attachments/assets/e3a6e1e3-6238-4c01-a372-fa0c25475fbd)\r\n|","sha":"32144fc0244566db557646ff35cc82c29734df72","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix",":ml","Feature:Anomaly
Detection","v9.0.0","Team:ML","v8.16.0","backport:version"],"title":"[ML]
Anomaly explorer: Show Data Gaps and Connect Anomalous Points on Single
Metric
Charts","number":194119,"url":"https://github.com/elastic/kibana/pull/194119","mergeCommit":{"message":"[ML]
Anomaly explorer: Show Data Gaps and Connect Anomalous Points on Single
Metric Charts (#194119)\n\n## Summary\r\n\r\nFix for
[#193885](https://github.com/elastic/kibana/issues/193885)\r\n\r\nSingle
metric viewer:\r\n![Screenshot 2024-09-26 at 13
31\r\n35](https://github.com/user-attachments/assets/3576758e-9cb1-4c55-bd84-40f2095cc54f)\r\n\r\nAnomaly
explorer:\r\n| Before | After |\r\n| ------------- | -------------
|\r\n|\r\n![image](https://github.com/user-attachments/assets/89f48abd-26ac-4dd4-ab10-b1c8198f50ff)\r\n|
![Screenshot 2024-09-26 at 13
32\r\n05](https://github.com/user-attachments/assets/e3a6e1e3-6238-4c01-a372-fa0c25475fbd)\r\n|","sha":"32144fc0244566db557646ff35cc82c29734df72"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194119","number":194119,"mergeCommit":{"message":"[ML]
Anomaly explorer: Show Data Gaps and Connect Anomalous Points on Single
Metric Charts (#194119)\n\n## Summary\r\n\r\nFix for
[#193885](https://github.com/elastic/kibana/issues/193885)\r\n\r\nSingle
metric viewer:\r\n![Screenshot 2024-09-26 at 13
31\r\n35](https://github.com/user-attachments/assets/3576758e-9cb1-4c55-bd84-40f2095cc54f)\r\n\r\nAnomaly
explorer:\r\n| Before | After |\r\n| ------------- | -------------
|\r\n|\r\n![image](https://github.com/user-attachments/assets/89f48abd-26ac-4dd4-ab10-b1c8198f50ff)\r\n|
![Screenshot 2024-09-26 at 13
32\r\n05](https://github.com/user-attachments/assets/e3a6e1e3-6238-4c01-a372-fa0c25475fbd)\r\n|","sha":"32144fc0244566db557646ff35cc82c29734df72"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Robert Jaszczurek <92210485+rbrtj@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2024-10-01 00:15:45 +10:00 committed by GitHub
parent 5afb442c86
commit 9e1829eacd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 9 deletions

View file

@ -1055,9 +1055,11 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
// differently because of how the source data is structured.
// For rare chart values we are only interested wether a value is either `0` or not,
// `0` acts like a flag in the chart whether to display the dot/marker.
// All other charts (single metric, population) are metric based and with
// For single metric chart, we need to pass null values to display data gaps.
// All other charts are distribution based and with
// those a value of `null` acts as the flag to hide a data point.
if (
chartType === CHART_TYPE.SINGLE_METRIC ||
(chartType === CHART_TYPE.EVENT_DISTRIBUTION && value > 0) ||
(chartType !== CHART_TYPE.EVENT_DISTRIBUTION && value !== null)
) {
@ -1079,6 +1081,7 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
// Iterate through the anomaly records, adding anomalyScore properties
// to the chartData entries for anomalous buckets.
const chartDataForPointSearch = getChartDataForPointSearch(chartData, records[0], chartType);
let shouldSortChartData = false;
each(records, (record) => {
// Look for a chart point with the same time as the record.
// If none found, insert a point for anomalies due to a gap in the data.
@ -1087,10 +1090,17 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
if (chartPoint === undefined) {
chartPoint = { date: recordTime, value: null };
chartData.push(chartPoint);
shouldSortChartData = true;
}
if (chartPoint !== undefined) {
chartPoint.anomalyScore = record.record_score;
// If it is an empty chart point, set the value to the actual value
// To properly display the anomaly marker on the chart
if (chartPoint.value === null) {
chartPoint.value = Array.isArray(record.actual) ? record.actual[0] : record.actual;
}
if (record.actual !== undefined) {
chartPoint.actual = record.actual;
chartPoint.typical = record.typical;
@ -1119,6 +1129,12 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
}
});
// Chart data is sorted by default, but if we added points for anomalies,
// we need to sort again to ensure the points are in the correct order.
if (shouldSortChartData) {
chartData.sort((a, b) => a.date - b.date);
}
// Add a scheduledEvents property to any points in the chart data set
// which correspond to times of scheduled events for the job.
if (scheduledEvents !== undefined) {
@ -1126,14 +1142,14 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
const chartPoint = findChartPointForTime(chartDataForPointSearch, Number(time));
if (chartPoint !== undefined) {
chartPoint.scheduledEvents = events;
// We do not want to create additional points for single metric charts
// as it could break the chart.
} else if (chartType !== CHART_TYPE.SINGLE_METRIC) {
} else {
// If there's no underlying metric data point for the scheduled event,
// create a new chart point with a value of 0.
// Except for Single Metric Charts, where we want to create a point at the bottom of the chart.
// Which is not always `0`.
const eventChartPoint: ChartPoint = {
date: Number(time),
value: 0,
value: chartType === CHART_TYPE.SINGLE_METRIC ? null : 0,
entity: SCHEDULE_EVENT_MARKER_ENTITY,
scheduledEvents: events,
};