Skip to content

Commit fa13af9

Browse files
lcawldarnautovMichael Marcialis
authored
[ML] Add popover help for swim lanes (#98855)
Co-authored-by: Dima Arnautov <arnautov.dima@gmail.com> Co-authored-by: Michael Marcialis <michael@marcial.is>
1 parent 1d4bdc5 commit fa13af9

5 files changed

Lines changed: 143 additions & 0 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.mlHelpPopover__panel {
2+
max-width: $euiSize * 30;
3+
}
4+
5+
.mlHelpPopover__content {
6+
@include euiYScrollWithShadows;
7+
max-height: 40vh;
8+
padding: $euiSizeS;
9+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import React, { ReactNode } from 'react';
9+
import {
10+
EuiButtonIcon,
11+
EuiLinkButtonProps,
12+
EuiPopover,
13+
EuiPopoverProps,
14+
EuiPopoverTitle,
15+
EuiText,
16+
} from '@elastic/eui';
17+
import './help_popover.scss';
18+
19+
export const HelpPopoverButton = ({ onClick }: { onClick: EuiLinkButtonProps['onClick'] }) => {
20+
return (
21+
<EuiButtonIcon
22+
className="mlHelpPopover__buttonIcon"
23+
size="s"
24+
iconType="help"
25+
onClick={onClick}
26+
/>
27+
);
28+
};
29+
30+
export const HelpPopover = ({
31+
anchorPosition,
32+
button,
33+
children,
34+
closePopover,
35+
isOpen,
36+
title,
37+
}: {
38+
anchorPosition?: EuiPopoverProps['anchorPosition'];
39+
button: EuiPopoverProps['button'];
40+
children: ReactNode;
41+
closePopover: EuiPopoverProps['closePopover'];
42+
isOpen: EuiPopoverProps['isOpen'];
43+
title?: string;
44+
}) => {
45+
return (
46+
<EuiPopover
47+
anchorPosition={anchorPosition}
48+
button={button}
49+
className="mlHelpPopover"
50+
closePopover={closePopover}
51+
isOpen={isOpen}
52+
ownFocus
53+
panelClassName="mlHelpPopover__panel"
54+
panelPaddingSize="none"
55+
>
56+
{title && <EuiPopoverTitle paddingSize="s">{title}</EuiPopoverTitle>}
57+
58+
<EuiText className="mlHelpPopover__content" size="s">
59+
{children}
60+
</EuiText>
61+
</EuiPopover>
62+
);
63+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
export { HelpPopoverButton, HelpPopover } from './help_popover';

x-pack/plugins/ml/public/application/explorer/anomaly_timeline.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { ExplorerNoInfluencersFound } from './components/explorer_no_influencers
3535
import { SwimlaneContainer } from './swimlane_container';
3636
import { AppStateSelectedCells, OverallSwimlaneData, ViewBySwimLaneData } from './explorer_utils';
3737
import { NoOverallData } from './components/no_overall_data';
38+
import { AnomalyTimelineHelpPopover } from './anomaly_timeline_help_popover';
3839

3940
function mapSwimlaneOptionsToEuiOptions(options: string[]) {
4041
return options.map((option) => ({
@@ -225,6 +226,10 @@ export const AnomalyTimeline: FC<AnomalyTimelineProps> = React.memo(
225226
</EuiPopover>
226227
</EuiFlexItem>
227228
)}
229+
230+
<EuiFlexItem grow={false}>
231+
<AnomalyTimelineHelpPopover />
232+
</EuiFlexItem>
228233
</EuiFlexGroup>
229234

230235
<EuiSpacer size="m" />
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import React, { useState } from 'react';
9+
import { i18n } from '@kbn/i18n';
10+
import { FormattedMessage } from '@kbn/i18n/react';
11+
import { HelpPopover, HelpPopoverButton } from '../components/help_popover/help_popover';
12+
13+
export const AnomalyTimelineHelpPopover = () => {
14+
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
15+
16+
return (
17+
<HelpPopover
18+
anchorPosition="upCenter"
19+
button={
20+
<HelpPopoverButton
21+
onClick={() => {
22+
setIsPopoverOpen(!isPopoverOpen);
23+
}}
24+
/>
25+
}
26+
closePopover={() => setIsPopoverOpen(false)}
27+
isOpen={isPopoverOpen}
28+
title={i18n.translate('xpack.ml.explorer.anomalyTimelinePopoverTitle', {
29+
defaultMessage: 'Anomaly timelines',
30+
})}
31+
>
32+
<p>
33+
<FormattedMessage
34+
id="xpack.ml.explorer.anomalyTimelinePopoverBasicExplanation"
35+
defaultMessage="Swim lanes provide an overview of the buckets of data that have been analyzed within the selected time period. You can view an overall swim lane or view them by job or influencer."
36+
/>
37+
</p>
38+
<p>
39+
<FormattedMessage
40+
id="xpack.ml.explorer.anomalyTimelinePopoverScoreExplanation"
41+
defaultMessage="Each block in a swim lane is colored according to its anomaly score, which is a value from 0 to 100. The blocks with high scores are shown in red and low scores are indicated in blue."
42+
/>
43+
</p>
44+
<p>
45+
<FormattedMessage
46+
id="xpack.ml.explorer.anomalyTimelinePopoverAdvancedExplanation"
47+
defaultMessage="The anomaly scores that you see in each section of the Anomaly Explorer might differ slightly. This disparity occurs because for each job there are bucket results, overall bucket results, influencer results, and record results. Anomaly scores are generated for each type of result. The overall swim lane shows the maximum overall bucket score for each block. When you view a swim lane by job, it shows the maximum bucket score in each block. When you view by influencer, it shows the maximum influencer score in each block."
48+
/>
49+
</p>
50+
<p>
51+
<FormattedMessage
52+
id="xpack.ml.explorer.anomalyTimelinePopoverSelectionExplanation"
53+
defaultMessage="When you select one or more blocks in the swim lanes, the list of anomalies and top influencers is likewise filtered to provide information relative to that selection."
54+
/>
55+
</p>
56+
</HelpPopover>
57+
);
58+
};

0 commit comments

Comments
 (0)