From 074a330c573273db042600ee656ac78f09243ed8 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Wed, 17 Oct 2018 11:29:21 +0100 Subject: [PATCH] [ML] Fixes clean up of multi-bucket markers on Single Metric chart update (#24080) --- .../explorer_chart_single_metric.js | 4 +-- .../styles/explorer_chart.less | 13 +++++----- .../timeseriesexplorer/styles/main.less | 18 +++++-------- .../timeseries_chart_directive.js | 25 +++++++++++-------- x-pack/plugins/ml/public/util/chart_utils.js | 2 +- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js index 2b04b3de05723..605e5f34dc522 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js +++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js @@ -301,11 +301,11 @@ export class ExplorerChartSingleMetric extends React.Component { // Remove multi-bucket markers that are no longer needed multiBucketMarkers.exit().remove(); - // Update markers to new positions. + // Append the multi-bucket markers and position on chart. multiBucketMarkers.enter().append('path') .attr('d', d3.svg.symbol().size(MULTI_BUCKET_SYMBOL_SIZE).type('cross')) .attr('transform', d => `translate(${lineChartXScale(d.date)}, ${lineChartYScale(d.value)})`) - .attr('class', d => `metric-value anomaly-marker multi-bucket ${getSeverityWithLow(d.anomalyScore)}`) + .attr('class', d => `anomaly-marker multi-bucket ${getSeverityWithLow(d.anomalyScore)}`) .on('mouseover', function (d) { showLineChartTooltip(d, this); }) diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less b/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less index 6ab1382384078..2215aa7838126 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less +++ b/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less @@ -84,27 +84,28 @@ stroke: #32a7c2; } - .metric-value.critical { + .anomaly-marker.critical { fill: #fe5050; } - .metric-value.major { + .anomaly-marker.major { fill: #ff7e00; } - .metric-value.minor { + .anomaly-marker.minor { fill: #ffdd00; } - .metric-value.warning { + .anomaly-marker.warning { fill: #8bc8fb; } - .metric-value.low { + .anomaly-marker.low { fill: #d2e9f7; } - .metric-value:hover { + .metric-value:hover, + .anomaly-marker:hover { stroke-width: 6px; stroke-opacity: 0.65; } diff --git a/x-pack/plugins/ml/public/timeseriesexplorer/styles/main.less b/x-pack/plugins/ml/public/timeseriesexplorer/styles/main.less index 99ffd2756ae2a..1900000c6bd4b 100644 --- a/x-pack/plugins/ml/public/timeseriesexplorer/styles/main.less +++ b/x-pack/plugins/ml/public/timeseriesexplorer/styles/main.less @@ -163,34 +163,28 @@ stroke: #aaaaaa; } - .metric-value.critical { + .anomaly-marker.critical { fill: #fe5050; } - .metric-value.major { + .anomaly-marker.major { fill: #ff7e00; } - .metric-value.minor { + .anomaly-marker.minor { fill: #ffdd00; } - .metric-value.warning { + .anomaly-marker.warning { fill: #8bc8fb; } - .metric-value.low { + .anomaly-marker.low { fill: #d2e9f7; } .metric-value:hover, - .anomaly-marker.highlighted { - stroke-width: 6px; - stroke-opacity: 0.65; - stroke: #32a7c2; - } - - .metric-value:hover, + .anomaly-marker:hover, .anomaly-marker.highlighted { stroke-width: 6px; stroke-opacity: 0.65; diff --git a/x-pack/plugins/ml/public/timeseriesexplorer/timeseries_chart_directive.js b/x-pack/plugins/ml/public/timeseriesexplorer/timeseries_chart_directive.js index ef7ff6bda58b9..1c212a4a4dd81 100644 --- a/x-pack/plugins/ml/public/timeseriesexplorer/timeseries_chart_directive.js +++ b/x-pack/plugins/ml/public/timeseriesexplorer/timeseries_chart_directive.js @@ -489,23 +489,26 @@ module.directive('mlTimeseriesChart', function () { return markerClass; }); + // Render cross symbols for any multi-bucket anomalies. const multiBucketMarkers = d3.select('.focus-chart-markers').selectAll('.multi-bucket') .data(data.filter(d => (d.anomalyScore !== null && showMultiBucketAnomalyMarker(d) === true))); - // Remove multi-bucket markers that are no longer needed + // Remove multi-bucket markers that are no longer needed. multiBucketMarkers.exit().remove(); - // Update markers to new positions. + // Add any new markers that are needed i.e. if number of multi-bucket points has increased. multiBucketMarkers.enter().append('path') .attr('d', d3.svg.symbol().size(MULTI_BUCKET_SYMBOL_SIZE).type('cross')) - .attr('transform', d => `translate(${focusXScale(d.date)}, ${focusYScale(d.value)})`) - .attr('class', d => `metric-value anomaly-marker multi-bucket ${getSeverityWithLow(d.anomalyScore)}`) .on('mouseover', function (d) { showFocusChartTooltip(d, this); }) .on('mouseout', () => mlChartTooltipService.hide()); + // Update all markers to new positions. + multiBucketMarkers.attr('transform', d => `translate(${focusXScale(d.date)}, ${focusYScale(d.value)})`) + .attr('class', d => `anomaly-marker multi-bucket ${getSeverityWithLow(d.anomalyScore)}`); + // Add rectangular markers for any scheduled events. const scheduledEventMarkers = d3.select('.focus-chart-markers').selectAll('.scheduled-event-marker') @@ -1056,21 +1059,21 @@ module.directive('mlTimeseriesChart', function () { if (showMultiBucketAnomalyMarker(markerToSelect) === true) { selectedMarker.enter().append('path') .attr('d', d3.svg.symbol().size(MULTI_BUCKET_SYMBOL_SIZE).type('cross')) - .attr('transform', d => `translate(${focusXScale(d.date)}, ${focusYScale(d.value)})`); + .attr('transform', d => `translate(${focusXScale(d.date)}, ${focusYScale(d.value)})`) + .attr('class', d => `anomaly-marker multi-bucket ${getSeverityWithLow(d.anomalyScore)} highlighted`); } else { selectedMarker.enter().append('circle') .attr('r', LINE_CHART_ANOMALY_RADIUS) .attr('cx', d => focusXScale(d.date)) - .attr('cy', d => focusYScale(d.value)); + .attr('cy', d => focusYScale(d.value)) + .attr('class', d => `anomaly-marker metric-value ${getSeverityWithLow(d.anomalyScore)} highlighted`); } - selectedMarker.attr('class', - d => `metric-value anomaly-marker ${getSeverityWithLow(d.anomalyScore)} highlighted`); // Display the chart tooltip for this marker. // Note the values of the record and marker may differ depending on the levels of aggregation. - const circle = $('.focus-chart-markers .anomaly-marker.highlighted'); - if (circle.length) { - showFocusChartTooltip(markerToSelect, circle[0]); + const anomalyMarker = $('.focus-chart-markers .anomaly-marker.highlighted'); + if (anomalyMarker.length) { + showFocusChartTooltip(markerToSelect, anomalyMarker[0]); } } } diff --git a/x-pack/plugins/ml/public/util/chart_utils.js b/x-pack/plugins/ml/public/util/chart_utils.js index 4cf3293db01fd..8a9246a13c360 100644 --- a/x-pack/plugins/ml/public/util/chart_utils.js +++ b/x-pack/plugins/ml/public/util/chart_utils.js @@ -18,7 +18,7 @@ import { timefilter } from 'ui/timefilter'; import { CHART_TYPE } from '../explorer/explorer_constants'; export const LINE_CHART_ANOMALY_RADIUS = 7; -export const MULTI_BUCKET_SYMBOL_SIZE = 144; // In square pixels for use with d3 symbol.size +export const MULTI_BUCKET_SYMBOL_SIZE = 100; // In square pixels for use with d3 symbol.size export const SCHEDULED_EVENT_SYMBOL_HEIGHT = 5; const MAX_LABEL_WIDTH = 100;