Skip to content

Commit

Permalink
[ML] Replace swim lane implementation with elastic-charts Heatmap (#7…
Browse files Browse the repository at this point in the history
…9315) (#79744)

* [ML] replace swim lane vis

* [ML] update swimlane_container, add colors constant

* [ML] update swimlane_container, add colors constant

* [ML] update swimlane_container, add colors constant

* [ML] unfiltered label for Overall swim lane

* [ML] tooltip content

* [ML] fix styles, override legend styles

* [ML] hide timeline for overall swimlane on the Anomaly Explorer page

* [ML] remove explorer_swimlane component

* [ML] remove dragselect dependency

* [ML] fix types

* [ML] fix tooltips, change mask fill to white

* [ML] fix highlightedData

* [ML] maxLegendHeight, fix Y-axis tooltip

* [ML] clear selection

* [ML] dataTestSubj

* [ML] remove jest snapshot for explorer_swimlane

* [ML] handle empty string label, fix translation key

* [ML] better positioning for the loading indicator

* [ML] update elastic/charts version

* [ML] fix getFormattedSeverityScore and showSwimlane condition

* [ML] fix selector for functional test

* [ML] change the legend alignment

* [ML] update elastic charts
  • Loading branch information
darnautov authored Oct 6, 2020
1 parent a8ca8ef commit 2ba1a89
Show file tree
Hide file tree
Showing 17 changed files with 472 additions and 1,328 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@
"@babel/register": "^7.10.5",
"@babel/types": "^7.11.0",
"@elastic/apm-rum": "^5.6.1",
"@elastic/charts": "23.1.1",
"@elastic/charts": "23.2.1",
"@elastic/ems-client": "7.10.0",
"@elastic/eslint-config-kibana": "0.15.0",
"@elastic/eslint-plugin-eui": "0.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-ui-shared-deps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"kbn:watch": "node scripts/build --dev --watch"
},
"dependencies": {
"@elastic/charts": "23.1.1",
"@elastic/charts": "23.2.1",
"@elastic/eui": "29.3.0",
"@elastic/numeral": "^2.5.0",
"@kbn/i18n": "1.0.0",
Expand Down
2 changes: 0 additions & 2 deletions x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
"@types/d3-shape": "^1.3.1",
"@types/d3-time": "^1.0.10",
"@types/d3-time-format": "^2.1.1",
"@types/dragselect": "^1.13.1",
"@types/elasticsearch": "^5.0.33",
"@types/fancy-log": "^1.3.1",
"@types/file-saver": "^2.0.0",
Expand Down Expand Up @@ -165,7 +164,6 @@
"cypress-promise": "^1.1.0",
"d3": "3.5.17",
"d3-scale": "1.0.7",
"dragselect": "1.13.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-adapter-utils": "^1.13.0",
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/ml/common/constants/anomalies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ export enum ANOMALY_THRESHOLD {
LOW = 0,
}

export const SEVERITY_COLORS = {
CRITICAL: '#fe5050',
MAJOR: '#fba740',
MINOR: '#fdec25',
WARNING: '#8bc8fb',
LOW: '#d2e9f7',
BLANK: '#ffffff',
};

export const PARTITION_FIELDS = ['partition_field', 'over_field', 'by_field'] as const;
export const JOB_ID = 'job_id';
export const PARTITION_FIELD_VALUE = 'partition_field_value';
2 changes: 1 addition & 1 deletion x-pack/plugins/ml/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
*/

export { SearchResponse7 } from './types/es_client';
export { ANOMALY_SEVERITY, ANOMALY_THRESHOLD } from './constants/anomalies';
export { ANOMALY_SEVERITY, ANOMALY_THRESHOLD, SEVERITY_COLORS } from './constants/anomalies';
export { getSeverityColor, getSeverityType } from './util/anomaly_utils';
export { composeValidators, patternValidator } from './util/validators';
21 changes: 14 additions & 7 deletions x-pack/plugins/ml/common/util/anomaly_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import { i18n } from '@kbn/i18n';
import { CONDITIONS_NOT_SUPPORTED_FUNCTIONS } from '../constants/detector_rule';
import { MULTI_BUCKET_IMPACT } from '../constants/multi_bucket_impact';
import { ANOMALY_SEVERITY, ANOMALY_THRESHOLD } from '../constants/anomalies';
import { ANOMALY_SEVERITY, ANOMALY_THRESHOLD, SEVERITY_COLORS } from '../constants/anomalies';
import { AnomalyRecordDoc } from '../types/anomalies';

export interface SeverityType {
Expand Down Expand Up @@ -109,6 +109,13 @@ function getSeverityTypes() {
});
}

/**
* Return formatted severity score.
*/
export function getFormattedSeverityScore(score: number): string {
return score < 1 ? '< 1' : String(parseInt(String(score), 10));
}

// Returns a severity label (one of critical, major, minor, warning or unknown)
// for the supplied normalized anomaly score (a value between 0 and 100).
export function getSeverity(normalizedScore: number): SeverityType {
Expand Down Expand Up @@ -168,17 +175,17 @@ export function getSeverityWithLow(normalizedScore: number): SeverityType {
// for the supplied normalized anomaly score (a value between 0 and 100).
export function getSeverityColor(normalizedScore: number): string {
if (normalizedScore >= ANOMALY_THRESHOLD.CRITICAL) {
return '#fe5050';
return SEVERITY_COLORS.CRITICAL;
} else if (normalizedScore >= ANOMALY_THRESHOLD.MAJOR) {
return '#fba740';
return SEVERITY_COLORS.MAJOR;
} else if (normalizedScore >= ANOMALY_THRESHOLD.MINOR) {
return '#fdec25';
return SEVERITY_COLORS.MINOR;
} else if (normalizedScore >= ANOMALY_THRESHOLD.WARNING) {
return '#8bc8fb';
return SEVERITY_COLORS.WARNING;
} else if (normalizedScore >= ANOMALY_THRESHOLD.LOW) {
return '#d2e9f7';
return SEVERITY_COLORS.LOW;
} else {
return '#ffffff';
return SEVERITY_COLORS.BLANK;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.mlChartTooltip {
@include euiToolTipStyle('s');
@include euiFontSizeXS;
position: absolute;
padding: 0;
transition: opacity $euiAnimSpeedNormal;
pointer-events: none;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,57 @@ const renderHeader = (headerData?: ChartTooltipValue, formatter?: TooltipValueFo
return formatter ? formatter(headerData) : headerData.label;
};

/**
* Pure component for rendering the tooltip content with a custom layout across the ML plugin.
*/
export const FormattedTooltip: FC<{ tooltipData: TooltipData }> = ({ tooltipData }) => {
return (
<div className="mlChartTooltip">
{tooltipData.length > 0 && tooltipData[0].skipHeader === undefined && (
<div className="mlChartTooltip__header">{renderHeader(tooltipData[0])}</div>
)}
{tooltipData.length > 1 && (
<div className="mlChartTooltip__list">
{tooltipData
.slice(1)
.map(({ label, value, color, isHighlighted, seriesIdentifier, valueAccessor }) => {
const classes = classNames('mlChartTooltip__item', {
// eslint-disable-next-line @typescript-eslint/naming-convention
echTooltip__rowHighlighted: isHighlighted,
});

const renderValue = Array.isArray(value)
? value.map((v) => <div key={v}>{v}</div>)
: value;

return (
<div
key={`${seriesIdentifier.key}__${valueAccessor}`}
className={classes}
style={{
borderLeftColor: color,
}}
>
<EuiFlexGroup>
<EuiFlexItem className="eui-textBreakWord mlChartTooltip__label" grow={false}>
{label}
</EuiFlexItem>
<EuiFlexItem className="eui-textBreakAll mlChartTooltip__value">
{renderValue}
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
})}
</div>
)}
</div>
);
};

/**
* Tooltip component bundled with the {@link ChartTooltipService}
*/
const Tooltip: FC<{ service: ChartTooltipService }> = React.memo(({ service }) => {
const [tooltipData, setData] = useState<TooltipData>([]);
const refCallback = useRef<ChildrenArg['triggerRef']>();
Expand Down Expand Up @@ -57,50 +108,9 @@ const Tooltip: FC<{ service: ChartTooltipService }> = React.memo(({ service }) =
<div
{...getTooltipProps({
ref: tooltipRef,
className: 'mlChartTooltip',
})}
>
{tooltipData.length > 0 && tooltipData[0].skipHeader === undefined && (
<div className="mlChartTooltip__header">{renderHeader(tooltipData[0])}</div>
)}
{tooltipData.length > 1 && (
<div className="mlChartTooltip__list">
{tooltipData
.slice(1)
.map(({ label, value, color, isHighlighted, seriesIdentifier, valueAccessor }) => {
const classes = classNames('mlChartTooltip__item', {
// eslint-disable-next-line @typescript-eslint/naming-convention
echTooltip__rowHighlighted: isHighlighted,
});

const renderValue = Array.isArray(value)
? value.map((v) => <div key={v}>{v}</div>)
: value;

return (
<div
key={`${seriesIdentifier.key}__${valueAccessor}`}
className={classes}
style={{
borderLeftColor: color,
}}
>
<EuiFlexGroup>
<EuiFlexItem
className="eui-textBreakWord mlChartTooltip__label"
grow={false}
>
{label}
</EuiFlexItem>
<EuiFlexItem className="eui-textBreakAll mlChartTooltip__value">
{renderValue}
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
})}
</div>
)}
<FormattedTooltip tooltipData={tooltipData} />
</div>
);
}) as TooltipTriggerProps['tooltip'],
Expand Down

This file was deleted.

Loading

0 comments on commit 2ba1a89

Please sign in to comment.