[8.x] [ML] Anomaly Explorer: Display markers for scheduled events in distribution type anomaly charts (#192377) (#193118)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ML] Anomaly Explorer: Display markers for scheduled events in
distribution type anomaly charts
(#192377)](https://github.com/elastic/kibana/pull/192377)

<!--- 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-17T07:53:32Z","message":"[ML]
Anomaly Explorer: Display markers for scheduled events in distribution
type anomaly charts (#192377)\n\n## Summary\r\n\r\nFix for
[#129304](https://github.com/elastic/kibana/issues/129304)\r\n\r\nPreviously,
for distribution type charts, we displayed calendar event\r\nmarkers
only for anomalous data points. The changes improve the display\r\nof
event markers for such chart types, including showing calendar
event\r\nmarkers even when there is no underlying data point.\r\n\r\n|
Scenario | Before | After |\r\n| :---: | :---: | :---: |\r\n| Rare chart
|\r\n![image](3dd51cd1-6972-4343-bbc8-8e5f38d7c6bd)\r\n|\r\n|
Population chart | ![Zrzut ekranu 2024-09-9 o 16
16\r\n01](c198e75e-14c8-4194-9d71-2358d25f21d5)\r\n|\r\n|
Single metric chart (no difference)
|\r\n![image](c11ec696-b1f4-4ddf-9542-037b8dd2d31f)\r\n|","sha":"d5b1fdf49af8eb23210e3b15a20fe1f9b660eea8","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement",":ml","Feature:Anomaly
Detection","v9.0.0","Team:ML","v8.16.0"],"title":"[ML] Anomaly Explorer:
Display markers for scheduled events in distribution type anomaly
charts","number":192377,"url":"https://github.com/elastic/kibana/pull/192377","mergeCommit":{"message":"[ML]
Anomaly Explorer: Display markers for scheduled events in distribution
type anomaly charts (#192377)\n\n## Summary\r\n\r\nFix for
[#129304](https://github.com/elastic/kibana/issues/129304)\r\n\r\nPreviously,
for distribution type charts, we displayed calendar event\r\nmarkers
only for anomalous data points. The changes improve the display\r\nof
event markers for such chart types, including showing calendar
event\r\nmarkers even when there is no underlying data point.\r\n\r\n|
Scenario | Before | After |\r\n| :---: | :---: | :---: |\r\n| Rare chart
|\r\n![image](3dd51cd1-6972-4343-bbc8-8e5f38d7c6bd)\r\n|\r\n|
Population chart | ![Zrzut ekranu 2024-09-9 o 16
16\r\n01](c198e75e-14c8-4194-9d71-2358d25f21d5)\r\n|\r\n|
Single metric chart (no difference)
|\r\n![image](c11ec696-b1f4-4ddf-9542-037b8dd2d31f)\r\n|","sha":"d5b1fdf49af8eb23210e3b15a20fe1f9b660eea8"}},"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/192377","number":192377,"mergeCommit":{"message":"[ML]
Anomaly Explorer: Display markers for scheduled events in distribution
type anomaly charts (#192377)\n\n## Summary\r\n\r\nFix for
[#129304](https://github.com/elastic/kibana/issues/129304)\r\n\r\nPreviously,
for distribution type charts, we displayed calendar event\r\nmarkers
only for anomalous data points. The changes improve the display\r\nof
event markers for such chart types, including showing calendar
event\r\nmarkers even when there is no underlying data point.\r\n\r\n|
Scenario | Before | After |\r\n| :---: | :---: | :---: |\r\n| Rare chart
|\r\n![image](3dd51cd1-6972-4343-bbc8-8e5f38d7c6bd)\r\n|\r\n|
Population chart | ![Zrzut ekranu 2024-09-9 o 16
16\r\n01](c198e75e-14c8-4194-9d71-2358d25f21d5)\r\n|\r\n|
Single metric chart (no difference)
|\r\n![image](c11ec696-b1f4-4ddf-9542-037b8dd2d31f)\r\n|","sha":"d5b1fdf49af8eb23210e3b15a20fe1f9b660eea8"}},{"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-09-17 19:33:10 +10:00 committed by GitHub
parent 12fcb6110a
commit 6113e6c1e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 43 additions and 7 deletions

View file

@ -13,3 +13,5 @@ export const CHART_TYPE = {
} as const;
export type ChartType = (typeof CHART_TYPE)[keyof typeof CHART_TYPE];
export const SCHEDULE_EVENT_MARKER_ENTITY = 'schedule_event_marker_entity';

View file

@ -40,6 +40,7 @@ import { CHART_TYPE } from '../explorer_constants';
import { CHART_HEIGHT, TRANSPARENT_BACKGROUND } from './constants';
import { filter } from 'rxjs';
import { drawCursor } from './utils/draw_anomaly_explorer_charts_cursor';
import { SCHEDULE_EVENT_MARKER_ENTITY } from '../../../../common/constants/charts';
const CONTENT_WRAPPER_HEIGHT = 215;
const SCHEDULED_EVENT_MARKER_HEIGHT = 5;
@ -158,12 +159,29 @@ export class ExplorerChartDistribution extends React.Component {
.key((d) => d.entity)
.entries(chartData)
.sort((a, b) => {
// To display calendar event markers we populate the chart with fake data points.
// If a category has fake data points, it should be sorted to the end.
const aHasFakeData = a.values.some((d) => d.entity === SCHEDULE_EVENT_MARKER_ENTITY);
const bHasFakeData = b.values.some((d) => d.entity === SCHEDULE_EVENT_MARKER_ENTITY);
if (aHasFakeData && !bHasFakeData) {
return 1;
}
if (bHasFakeData && !aHasFakeData) {
return -1;
}
return b.values.length - a.values.length;
})
.filter((d, i) => {
// only filter for rare charts
if (chartType === CHART_TYPE.EVENT_DISTRIBUTION) {
return i < categoryLimit || d.key === highlight;
return (
i < categoryLimit ||
d.key === highlight ||
d.values.some((d) => d.entity === SCHEDULE_EVENT_MARKER_ENTITY)
);
}
return true;
})
@ -373,7 +391,8 @@ export class ExplorerChartDistribution extends React.Component {
.orient('left')
.innerTickSize(0)
.outerTickSize(0)
.tickPadding(10);
.tickPadding(10)
.tickFormat((d) => (d === SCHEDULE_EVENT_MARKER_ENTITY ? null : d));
if (fieldFormat !== undefined) {
yAxis.tickFormat((d) => fieldFormat.convert(d, 'text'));
@ -518,7 +537,8 @@ export class ExplorerChartDistribution extends React.Component {
const tooltipData = [{ label: formattedDate }];
const seriesKey = config.detectorLabel;
if (marker.entity !== undefined) {
// Hide entity for scheduled events with mocked value.
if (marker.entity !== undefined && marker.entity !== SCHEDULE_EVENT_MARKER_ENTITY) {
tooltipData.push({
label: i18n.translate('xpack.ml.explorer.distributionChart.entityLabel', {
defaultMessage: 'entity',
@ -590,7 +610,11 @@ export class ExplorerChartDistribution extends React.Component {
});
}
}
} else if (chartType !== CHART_TYPE.EVENT_DISTRIBUTION) {
} else if (
chartType !== CHART_TYPE.EVENT_DISTRIBUTION &&
// Hide value for scheduled events with mocked value.
marker.entity !== SCHEDULE_EVENT_MARKER_ENTITY
) {
tooltipData.push({
label: i18n.translate(
'xpack.ml.explorer.distributionChart.valueWithoutAnomalyScoreLabel',

View file

@ -53,7 +53,7 @@ import { parseInterval } from '../../../common/util/parse_interval';
import { getDatafeedAggregations } from '../../../common/util/datafeed_utils';
import { findAggField } from '../../../common/util/validation_utils';
import type { ChartType } from '../../../common/constants/charts';
import { CHART_TYPE } from '../../../common/constants/charts';
import { CHART_TYPE, SCHEDULE_EVENT_MARKER_ENTITY } from '../../../common/constants/charts';
import { getChartType } from '../../../common/util/chart_utils';
import type { MlJob } from '../..';
@ -1124,9 +1124,19 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu
each(scheduledEvents, (events, time) => {
const chartPoint = findChartPointForTime(chartDataForPointSearch, Number(time));
if (chartPoint !== undefined) {
// Note if the scheduled event coincides with an absence of the underlying metric data,
// we don't worry about plotting the event.
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) {
// If there's no underlying metric data point for the scheduled event,
// create a new chart point with a value of 0.
const eventChartPoint: ChartPoint = {
date: Number(time),
value: 0,
entity: SCHEDULE_EVENT_MARKER_ENTITY,
scheduledEvents: events,
};
chartData.push(eventChartPoint);
}
});
}