diff --git a/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.test.ts b/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.test.ts index 64bf7a5284c89..e91142934359d 100644 --- a/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.test.ts +++ b/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.test.ts @@ -6,36 +6,37 @@ */ import { getSeverityColor } from './get_severity_color'; +import { ML_SEVERITY_COLORS } from './severity_colors'; describe('getSeverityColor', () => { test('returns correct hex code for low for 0 <= score < 3', () => { - expect(getSeverityColor(0)).toBe('#d2e9f7'); - expect(getSeverityColor(0.001)).toBe('#d2e9f7'); - expect(getSeverityColor(2.99)).toBe('#d2e9f7'); + expect(getSeverityColor(0)).toBe(ML_SEVERITY_COLORS.LOW); + expect(getSeverityColor(0.001)).toBe(ML_SEVERITY_COLORS.LOW); + expect(getSeverityColor(2.99)).toBe(ML_SEVERITY_COLORS.LOW); }); test('returns correct hex code for warning for 3 <= score < 25', () => { - expect(getSeverityColor(3)).toBe('#8bc8fb'); - expect(getSeverityColor(24.99)).toBe('#8bc8fb'); + expect(getSeverityColor(3)).toBe(ML_SEVERITY_COLORS.WARNING); + expect(getSeverityColor(24.99)).toBe(ML_SEVERITY_COLORS.WARNING); }); test('returns correct hex code for minor for 25 <= score < 50', () => { - expect(getSeverityColor(25)).toBe('#fdec25'); - expect(getSeverityColor(49.99)).toBe('#fdec25'); + expect(getSeverityColor(25)).toBe(ML_SEVERITY_COLORS.MINOR); + expect(getSeverityColor(49.99)).toBe(ML_SEVERITY_COLORS.MINOR); }); test('returns correct hex code for major for 50 <= score < 75', () => { - expect(getSeverityColor(50)).toBe('#fba740'); - expect(getSeverityColor(74.99)).toBe('#fba740'); + expect(getSeverityColor(50)).toBe(ML_SEVERITY_COLORS.MAJOR); + expect(getSeverityColor(74.99)).toBe(ML_SEVERITY_COLORS.MAJOR); }); test('returns correct hex code for critical for score >= 75', () => { - expect(getSeverityColor(75)).toBe('#fe5050'); - expect(getSeverityColor(100)).toBe('#fe5050'); - expect(getSeverityColor(1000)).toBe('#fe5050'); + expect(getSeverityColor(75)).toBe(ML_SEVERITY_COLORS.CRITICAL); + expect(getSeverityColor(100)).toBe(ML_SEVERITY_COLORS.CRITICAL); + expect(getSeverityColor(1000)).toBe(ML_SEVERITY_COLORS.CRITICAL); }); test('returns correct hex code for unknown for scores less than 0', () => { - expect(getSeverityColor(-10)).toBe('#ffffff'); + expect(getSeverityColor(-10)).toBe(ML_SEVERITY_COLORS.UNKNOWN); }); }); diff --git a/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.ts b/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.ts index f17609ecef5e7..dcc5ac3544e1b 100644 --- a/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.ts +++ b/x-pack/platform/packages/shared/ml/anomaly_utils/get_severity_color.ts @@ -9,7 +9,7 @@ import { ML_ANOMALY_THRESHOLD } from './anomaly_threshold'; import { ML_SEVERITY_COLORS } from './severity_colors'; /** - * Returns a severity RGB color (one of critical, major, minor, warning, low or blank) + * Returns a severity RGB color (one of critical, major, minor, warning, low or unknown) * for the supplied normalized anomaly score (a value between 0 and 100). * @param normalizedScore - A normalized score between 0-100, which is based on the probability of the anomalousness of this record */ @@ -25,6 +25,6 @@ export function getSeverityColor(normalizedScore: number): string { } else if (normalizedScore >= ML_ANOMALY_THRESHOLD.LOW) { return ML_SEVERITY_COLORS.LOW; } else { - return ML_SEVERITY_COLORS.BLANK; + return ML_SEVERITY_COLORS.UNKNOWN; } } diff --git a/x-pack/platform/packages/shared/ml/anomaly_utils/severity_colors.ts b/x-pack/platform/packages/shared/ml/anomaly_utils/severity_colors.ts index e871528463399..67cc59fe46a2b 100644 --- a/x-pack/platform/packages/shared/ml/anomaly_utils/severity_colors.ts +++ b/x-pack/platform/packages/shared/ml/anomaly_utils/severity_colors.ts @@ -38,5 +38,5 @@ export const ML_SEVERITY_COLORS = { /** * Color used in the UI to indicate an anomaly for which the score is unknown. */ - BLANK: '#ffffff', + UNKNOWN: '#ffffff', }; diff --git a/x-pack/platform/plugins/shared/ml/public/alerting/anomaly_detection_alerts_table/render_cell_value.test.tsx b/x-pack/platform/plugins/shared/ml/public/alerting/anomaly_detection_alerts_table/render_cell_value.test.tsx index bba6b909863bb..5df6f4c018ffe 100644 --- a/x-pack/platform/plugins/shared/ml/public/alerting/anomaly_detection_alerts_table/render_cell_value.test.tsx +++ b/x-pack/platform/plugins/shared/ml/public/alerting/anomaly_detection_alerts_table/render_cell_value.test.tsx @@ -5,11 +5,16 @@ * 2.0. */ +import React from 'react'; + import { EuiHealth } from '@elastic/eui'; + import { type FieldFormatsRegistry } from '@kbn/field-formats-plugin/common'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; -import React from 'react'; +import { ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils'; + import { ALERT_ANOMALY_SCORE } from '../../../common/constants/alerts'; + import { getAlertFormatters } from './render_cell_value'; describe('getAlertFormatters', () => { @@ -19,31 +24,31 @@ describe('getAlertFormatters', () => { test('format anomaly score correctly', () => { expect(alertFormatter(ALERT_ANOMALY_SCORE, 50.3)).toEqual( - + 50 ); expect(alertFormatter(ALERT_ANOMALY_SCORE, '50.3,89.6')).toEqual( - + 89 ); expect(alertFormatter(ALERT_ANOMALY_SCORE, '0.7')).toEqual( - + < 1 ); expect(alertFormatter(ALERT_ANOMALY_SCORE, '0')).toEqual( - + < 1 ); expect(alertFormatter(ALERT_ANOMALY_SCORE, '')).toEqual( - + < 1 ); diff --git a/x-pack/platform/plugins/shared/ml/public/application/_index.scss b/x-pack/platform/plugins/shared/ml/public/application/_index.scss index 91201434b20b1..66b04a8ff0e78 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/_index.scss +++ b/x-pack/platform/plugins/shared/ml/public/application/_index.scss @@ -1,6 +1,3 @@ -// ML has it's own variables for coloring -@import 'variables'; - // Protect the rest of Kibana from ML generic namespacing // SASSTODO: Prefix ml selectors instead .ml-app { @@ -14,4 +11,4 @@ @import 'components/job_selector/index'; @import 'components/rule_editor/index'; // SASSTODO: This file overwrites EUI directly -} \ No newline at end of file +} diff --git a/x-pack/platform/plugins/shared/ml/public/application/_variables.scss b/x-pack/platform/plugins/shared/ml/public/application/_variables.scss deleted file mode 100644 index f81a97cf8c156..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/_variables.scss +++ /dev/null @@ -1,12 +0,0 @@ -$mlColorCritical: #FE5050; -$mlColorMajor: #FBA740; -$mlColorMinor: #FDEC25; -$mlColorWarning: #8BC8FB; -$mlColorLowWarning: #D2E9F7; -$mlColorUnknown: #C0C0C0; - -$mlColorCriticalText: makeHighContrastColor($mlColorCritical, $euiColorEmptyShade); -$mlColorMajorText: makeHighContrastColor($mlColorMajor, $euiColorEmptyShade); -$mlColorMinorText: makeHighContrastColor($mlColorMinor, $euiColorEmptyShade); -$mlColorWarningText: makeHighContrastColor($mlColorWarning, $euiColorEmptyShade); -$mlColorUnknownText: $euiColorDarkShade; diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/severity_cell/severity_cell.test.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/severity_cell/severity_cell.test.tsx index e9166c0c6c28c..25071f30400cb 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/severity_cell/severity_cell.test.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/anomalies_table/severity_cell/severity_cell.test.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils/severity_colors'; import { SeverityCell } from './severity_cell'; describe('SeverityCell', () => { @@ -18,7 +19,7 @@ describe('SeverityCell', () => { const { container } = render(); expect(container.textContent).toBe('75'); const svgEl = container.querySelectorAll('[data-euiicon-type]')[0]; - expect(svgEl && svgEl.getAttribute('color')).toBe('#fe5050'); + expect(svgEl && svgEl.getAttribute('color')).toBe(ML_SEVERITY_COLORS.CRITICAL); }); test('should render a multi-bucket marker with low severity score', () => { @@ -29,6 +30,6 @@ describe('SeverityCell', () => { const { container } = render(); expect(container.textContent).toBe('< 1'); const svgEl = container.getElementsByTagName('svg').item(0); - expect(svgEl && svgEl.getAttribute('fill')).toBe('#d2e9f7'); + expect(svgEl && svgEl.getAttribute('fill')).toBe(ML_SEVERITY_COLORS.LOW); }); }); diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts index d54eb495a0a33..e6cfd5b3f66fa 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts +++ b/x-pack/platform/plugins/shared/ml/public/application/components/influencers_list/influencers_list_styles.ts @@ -9,7 +9,7 @@ import { css } from '@emotion/react'; import { useEuiFontSize, useEuiTheme } from '@elastic/eui'; -import { mlColors } from '../../styles'; +import { ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils'; export const useInfluencersListStyles = () => { const { euiTheme } = useEuiTheme(); @@ -50,12 +50,12 @@ export const useInfluencersListStyles = () => { width: `${barScore}%`, backgroundColor: severity === 'critical' - ? mlColors.critical + ? ML_SEVERITY_COLORS.CRITICAL : severity === 'major' - ? mlColors.major + ? ML_SEVERITY_COLORS.MAJOR : severity === 'minor' - ? mlColors.minor - : mlColors.warning, + ? ML_SEVERITY_COLORS.MINOR + : ML_SEVERITY_COLORS.WARNING, }), scoreLabel: (severity: string) => css({ @@ -67,12 +67,12 @@ export const useInfluencersListStyles = () => { display: 'inline', borderColor: severity === 'critical' - ? mlColors.critical + ? ML_SEVERITY_COLORS.CRITICAL : severity === 'major' - ? mlColors.major + ? ML_SEVERITY_COLORS.MAJOR : severity === 'minor' - ? mlColors.minor - : mlColors.warning, + ? ML_SEVERITY_COLORS.MINOR + : ML_SEVERITY_COLORS.WARNING, }), totalScoreLabel: css({ width: euiTheme.size.xl, diff --git a/x-pack/platform/plugins/shared/ml/public/application/components/severity_control/severity_control.tsx b/x-pack/platform/plugins/shared/ml/public/application/components/severity_control/severity_control.tsx index 1392c38d84507..096b7d263b183 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/components/severity_control/severity_control.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/components/severity_control/severity_control.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import type { EuiRangeProps } from '@elastic/eui'; import { EuiFieldNumber, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiRange } from '@elastic/eui'; -import { ML_ANOMALY_THRESHOLD } from '@kbn/ml-anomaly-utils'; +import { ML_ANOMALY_THRESHOLD, ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils'; export interface SeveritySelectorProps { value: number | undefined; @@ -24,22 +24,22 @@ export const SeverityControl: FC = React.memo(({ value, o { min: ML_ANOMALY_THRESHOLD.LOW, max: ML_ANOMALY_THRESHOLD.MINOR, - color: '#8BC8FB', + color: ML_SEVERITY_COLORS.WARNING, }, { min: ML_ANOMALY_THRESHOLD.MINOR, max: ML_ANOMALY_THRESHOLD.MAJOR, - color: '#FDEC25', + color: ML_SEVERITY_COLORS.MINOR, }, { min: ML_ANOMALY_THRESHOLD.MAJOR, max: ML_ANOMALY_THRESHOLD.CRITICAL, - color: '#FBA740', + color: ML_SEVERITY_COLORS.MAJOR, }, { min: ML_ANOMALY_THRESHOLD.CRITICAL, max: MAX_ANOMALY_SCORE, - color: '#FE5050', + color: ML_SEVERITY_COLORS.CRITICAL, }, ]; diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/_explorer_chart.scss b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/_explorer_chart.scss deleted file mode 100644 index 29967e8db9b3f..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/_explorer_chart.scss +++ /dev/null @@ -1,120 +0,0 @@ -// stylelint-disable selector-no-qualifying-type -.ml-explorer-chart-container { - overflow: hidden; - - .ml-explorer-chart-svg { - font-size: $euiFontSizeXS; - font-family: $euiFontFamily; - - .line-chart { - rect { - fill: $euiColorEmptyShade; - opacity: 1; - } - - rect.selected-interval { - fill: rgba(200, 200, 200, .1); - stroke: $euiColorDarkShade; - stroke-width: calc($euiSizeXS / 2); - stroke-opacity: .8; - } - - rect.scheduled-event-marker { - stroke-width: 1px; - stroke: $euiColorDarkShade; - fill: $euiColorLightShade; - pointer-events: none; - } - } - } - - .axis path, .axis line { - fill: none; - stroke: $euiBorderColor; - shape-rendering: crispEdges; - } - - .axis .tick line.ml-tick-emphasis { - stroke: rgba(0, 0, 0, .2); - } - - .axis text { - fill: $euiColorDarkShade; - } - - .axis .tick line { - stroke: $euiColorLightShade; - stroke-width: 1px; - } - - .values-line { - fill: none; - stroke: $euiColorPrimary; - stroke-width: 2; - } - - .values-dots circle, - .values-dots-circle { - fill: $euiColorPrimary; - stroke-width: 0; - } - - .values-dots circle.values-dots-circle-blur { - fill: $euiColorMediumShade; - } - - .metric-value { - opacity: 1; - fill: transparent; - stroke: $euiColorPrimary; - stroke-width: 0; - } - - .anomaly-marker { - stroke-width: 1px; - stroke: $euiColorMediumShade; - } - - .anomaly-marker:hover { - stroke-width: 6px; - stroke: $euiColorPrimary; - } - - .anomaly-marker.critical { - fill: $mlColorCritical; - } - - .anomaly-marker.major { - fill: $mlColorMajor; - } - - .anomaly-marker.minor { - fill: $mlColorMinor; - } - - .anomaly-marker.warning { - fill: $mlColorWarning; - } - - .anomaly-marker.low { - fill: $mlColorLowWarning; - } - - .metric-value:hover, - .anomaly-marker:hover { - stroke-width: 6px; - stroke-opacity: .65; - } -} - -.ml-explorer-chart { - overflow: hidden; -} - -.ml-explorer-chart-content-wrapper { - height: 215px; -} - -.ml-explorer-chart-axis-emphasis { - font-weight: bold; -} diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/_index.scss b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/_index.scss index d32d1ce81cd78..62ef4c05e1f7a 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/_index.scss +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/_index.scss @@ -1,3 +1 @@ -@import '../../../application/variables'; @import 'components/explorer_chart_label/index'; -@import 'explorer_chart'; diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js index c7fcddbe4c515..0210663103ac5 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js @@ -47,6 +47,7 @@ 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'; +import { cssMlExplorerChart } from './explorer_chart_styles'; const popoverMenuOffset = 0; const CONTENT_WRAPPER_HEIGHT = 215; @@ -776,7 +777,7 @@ export class ExplorerChartDistribution extends React.Component { )} -
+
{isLoading && } {!isLoading &&
}
diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js index 1b746647ef38d..9935af37feec6 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js @@ -12,6 +12,7 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { css } from '@emotion/react'; import d3 from 'd3'; import moment from 'moment'; @@ -48,10 +49,15 @@ import { LoadingIndicator } from '../../components/loading_indicator/loading_ind import { CHART_HEIGHT, TRANSPARENT_BACKGROUND } from './constants'; import { filter } from 'rxjs'; import { drawCursor } from './utils/draw_anomaly_explorer_charts_cursor'; +import { cssMlExplorerChart } from './explorer_chart_styles'; const popoverMenuOffset = 0; const CONTENT_WRAPPER_HEIGHT = 215; +// Not used for CSS, but with d3 to select elements. const CONTENT_WRAPPER_CLASS = 'ml-explorer-chart-content-wrapper'; +const mlExplorerChartContentWrapper = css({ + height: `${CONTENT_WRAPPER_HEIGHT}px`, +}); export class ExplorerChartSingleMetric extends React.Component { static contextType = context; @@ -721,9 +727,11 @@ export class ExplorerChartSingleMetric extends React.Component {
)} -
+
{isLoading && } - {!isLoading &&
} + {!isLoading && ( +
+ )}
); diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_styles.ts b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_styles.ts new file mode 100644 index 0000000000000..e89877fc03392 --- /dev/null +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_chart_styles.ts @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { css } from '@emotion/react'; + +import { useEuiFontSize, useEuiTheme, mathWithUnits, transparentize } from '@elastic/eui'; + +import { ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils'; + +export const useCssMlExplorerChartContainer = () => { + const { euiTheme } = useEuiTheme(); + const euiFontSizeXS = useEuiFontSize('xs').fontSize; + + return css({ + overflow: 'hidden', + + '.ml-explorer-chart-svg': { + fontSize: euiFontSizeXS, + fontFamily: euiTheme.font.family, + + '.line-chart': { + rect: { + fill: euiTheme.colors.emptyShade, + opacity: 1, + }, + + 'rect.selected-interval': { + fill: transparentize('#c8c8c8', 0.1), + stroke: euiTheme.colors.darkShade, + strokeWidth: mathWithUnits(euiTheme.size.xs, (x) => x / 2), + strokeOpacity: 0.8, + }, + + 'rect.scheduled-event-marker': { + strokeWidth: '1px', + stroke: euiTheme.colors.darkShade, + fill: euiTheme.colors.lightShade, + pointerEvents: 'none', + }, + }, + }, + + '.axis path, .axis line': { + fill: 'none', + stroke: euiTheme.border.color, + shapeRendering: 'crispEdges', + }, + + '.axis .tick line.ml-tick-emphasis': { + stroke: transparentize('#000', 0.2), + }, + + '.axis text': { + fill: euiTheme.colors.lightShade, + }, + + '.axis .tick line': { + stroke: euiTheme.colors.lightShade, + strokeWidth: '1px', + }, + + '.values-line': { + fill: 'none', + stroke: euiTheme.colors.primary, + strokeWidth: '2px', + }, + + '.values-dots circle, .values-dots-circle': { + fill: euiTheme.colors.primary, + strokeWidth: 0, + }, + + '.values-dots circle.values-dots-circle-blur': { + fill: euiTheme.colors.mediumShade, + }, + + '.metric-value': { + opacity: 1, + fill: 'transparent', + stroke: euiTheme.colors.primary, + strokeWidth: 0, + }, + + '.anomaly-marker': { + strokeWidth: '1px', + stroke: euiTheme.colors.mediumShade, + }, + + '.anomaly-marker:hover': { + strokeWidth: '6px', + stroke: euiTheme.colors.primary, + }, + + '.anomaly-marker.critical': { + fill: ML_SEVERITY_COLORS.CRITICAL, + }, + + '.anomaly-marker.major': { + fill: ML_SEVERITY_COLORS.MAJOR, + }, + + '.anomaly-marker.minor': { + fill: ML_SEVERITY_COLORS.MINOR, + }, + + '.anomaly-marker.warning': { + fill: ML_SEVERITY_COLORS.WARNING, + }, + + '.anomaly-marker.low': { + fill: ML_SEVERITY_COLORS.LOW, + }, + + '.metric-value:hover, .anomaly-marker:hover': { + strokeWidth: '6px', + strokeOpacity: 0.65, + }, + + 'ml-explorer-chart-axis-emphasis': { + fontWeight: 'bold', + }, + }); +}; + +export const cssMlExplorerChart = css({ + overflow: 'hidden', +}); diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_charts_container.js b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_charts_container.js index 9bc1317a9aa50..1f3a2d20eea28 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_charts_container.js +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/explorer_charts/explorer_charts_container.js @@ -45,6 +45,7 @@ import { EmbeddedMapComponentWrapper } from './explorer_chart_embedded_map'; import { useActiveCursor } from '@kbn/charts-plugin/public'; import { BarSeries, Chart, Settings, LEGACY_LIGHT_THEME } from '@elastic/charts'; import { escapeKueryForFieldValuePair } from '../../util/string_utils'; +import { useCssMlExplorerChartContainer } from './explorer_chart_styles'; const textTooManyBuckets = i18n.translate('xpack.ml.explorer.charts.tooManyBucketsDescription', { defaultMessage: @@ -398,6 +399,7 @@ export const ExplorerChartsContainerUI = ({ chartsService, showFilterIcons = true, }) => { + const cssMlExplorerChartContainer = useCssMlExplorerChartContainer(); const { services: { embeddable: embeddablePlugin, maps: mapsPlugin }, } = kibana; @@ -443,7 +445,8 @@ export const ExplorerChartsContainerUI = ({ return ( { // We test child components with snapshots separately // so we just do a high level check here. - expect(wrapper.find('div.ml-explorer-chart-container').children()).toHaveLength(1); + expect( + wrapper.find('div[data-test-subj="mlExplorerChartContainerItem"]').children() + ).toHaveLength(1); // Check if the additional y-axis information for rare charts is not part of the chart expect(wrapper.html().search(rareChartUniqueString)).toBe(-1); @@ -148,7 +150,9 @@ describe('ExplorerChartsContainer', () => { // We test child components with snapshots separately // so we just do a high level check here. - expect(wrapper.find('div.ml-explorer-chart-container').children()).toHaveLength(1); + expect( + wrapper.find('div[data-test-subj="mlExplorerChartContainerItem"]').children() + ).toHaveLength(1); // Check if the additional y-axis information for rare charts is part of the chart expect(wrapper.html().search(rareChartUniqueString)).toBeGreaterThan(0); diff --git a/x-pack/platform/plugins/shared/ml/public/application/styles.ts b/x-pack/platform/plugins/shared/ml/public/application/styles.ts deleted file mode 100644 index 86f4dbe3bbcd4..0000000000000 --- a/x-pack/platform/plugins/shared/ml/public/application/styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// Replacement for ./_variables.scss as we aim to remove the scss files - -export const mlColors = { - critical: '#FE5050', - major: '#FBA740', - minor: '#FDEC25', - warning: '#8BC8FB', - lowWarning: '#D2E9F7', - unknown: '#C0C0C0', -}; diff --git a/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js index f39bab106c643..d43603684b043 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js +++ b/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js @@ -20,7 +20,11 @@ import moment from 'moment'; import { EuiPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { getFormattedSeverityScore, getSeverityWithLow } from '@kbn/ml-anomaly-utils'; +import { + getFormattedSeverityScore, + getSeverityWithLow, + ML_SEVERITY_COLORS, +} from '@kbn/ml-anomaly-utils'; import { formatHumanReadableDateTimeSeconds } from '@kbn/ml-date-utils'; import { context } from '@kbn/kibana-react-plugin/public'; @@ -87,7 +91,13 @@ const ZOOM_INTERVAL_OPTIONS = [ const anomalyColorScale = d3.scale .threshold() .domain([3, 25, 50, 75, 100]) - .range(['#d2e9f7', '#8bc8fb', '#ffdd00', '#ff7e00', '#fe5050']); + .range([ + ML_SEVERITY_COLORS.LOW, + ML_SEVERITY_COLORS.WARNING, + ML_SEVERITY_COLORS.MINOR, + ML_SEVERITY_COLORS.MAJOR, + ML_SEVERITY_COLORS.CRITICAL, + ]); // Create a gray-toned version of the color scale to use under the context chart mask. const anomalyGrayScale = d3.scale diff --git a/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/styles.ts b/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/styles.ts index 7c4315e01688b..0c9ba5619908d 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/styles.ts +++ b/x-pack/platform/plugins/shared/ml/public/application/timeseriesexplorer/styles.ts @@ -10,7 +10,7 @@ import { css } from '@emotion/react'; import { useEuiFontSize, useEuiTheme, transparentize } from '@elastic/eui'; -import { mlColors } from '../styles'; +import { ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils'; // Annotations constants const mlAnnotationBorderWidth = '2px'; @@ -119,23 +119,23 @@ export const useTimeseriesExplorerStyles = () => { stroke: euiTheme.colors.mediumShade, '&.critical': { - fill: mlColors.critical, + fill: ML_SEVERITY_COLORS.CRITICAL, }, '&.major': { - fill: mlColors.major, + fill: ML_SEVERITY_COLORS.MAJOR, }, '&.minor': { - fill: mlColors.minor, + fill: ML_SEVERITY_COLORS.MINOR, }, '&.warning': { - fill: mlColors.warning, + fill: ML_SEVERITY_COLORS.WARNING, }, '&.low': { - fill: mlColors.lowWarning, + fill: ML_SEVERITY_COLORS.LOW, }, }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/ml/score/score_health.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/ml/score/score_health.tsx index ac179b2ac8337..b685ccb47e779 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/ml/score/score_health.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/ml/score/score_health.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { EuiHealth } from '@elastic/eui'; +import { ML_SEVERITY_COLORS } from '@kbn/ml-anomaly-utils/severity_colors'; interface Props { score: number; @@ -29,16 +30,16 @@ ScoreHealth.displayName = 'ScoreHealth'; // less than 3 are assigned a severity of 'low'. export const getSeverityColor = (normalizedScore: number): string => { if (normalizedScore >= 75) { - return '#fe5050'; + return ML_SEVERITY_COLORS.CRITICAL; } else if (normalizedScore >= 50) { - return '#fba740'; + return ML_SEVERITY_COLORS.MAJOR; } else if (normalizedScore >= 25) { - return '#fdec25'; + return ML_SEVERITY_COLORS.MINOR; } else if (normalizedScore >= 3) { - return '#8bc8fb'; + return ML_SEVERITY_COLORS.WARNING; } else if (normalizedScore >= 0) { - return '#d2e9f7'; + return ML_SEVERITY_COLORS.LOW; } else { - return '#ffffff'; + return ML_SEVERITY_COLORS.UNKNOWN; } }; diff --git a/x-pack/test/functional/services/ml/anomaly_charts.ts b/x-pack/test/functional/services/ml/anomaly_charts.ts index 50c639094408e..8f63c8cf3710a 100644 --- a/x-pack/test/functional/services/ml/anomaly_charts.ts +++ b/x-pack/test/functional/services/ml/anomaly_charts.ts @@ -31,7 +31,7 @@ export function AnomalyChartsProvider({ getService }: FtrProviderContext) { ? await testSubjects.find(chartsContainerSubj) : await testSubjects.find('mlExplorerChartsContainer'); const actualChartsCount = ( - await chartsContainer?.findAllByClassName('ml-explorer-chart-container', 3000) + await chartsContainer?.findAllByTestSubject('mlExplorerChartContainerItem', 3000) ).length; expect(actualChartsCount).to.eql( expectedChartsCount,