From ec827791cc5abee8cafd244d4a5f79032296fa30 Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Thu, 19 Mar 2020 12:15:05 +0100 Subject: [PATCH] fix: type changes and ml custom tooltip data --- .../np_ready/angular/directives/histogram.tsx | 3 +- .../chart_tooltip/chart_tooltip.tsx | 8 +- .../explorer_chart_distribution.js | 57 +++++--- .../explorer_chart_single_metric.js | 64 ++++++--- .../application/explorer/explorer_swimlane.js | 18 ++- .../timeseries_chart/timeseries_chart.js | 136 +++++++++++------- 6 files changed, 180 insertions(+), 106 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx index 8db3c77ba0f47..107c30ec5e688 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx @@ -38,6 +38,7 @@ import { TooltipValue, TooltipType, ElementClickListener, + XYChartElementEvent, } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; @@ -140,7 +141,7 @@ export class DiscoverHistogram extends Component ([elementData]) => { - const startRange = elementData[0].x; + const startRange = (elementData as XYChartElementEvent)[0].x; const range = { from: startRange, diff --git a/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx b/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx index db42c90d49ebb..9cc42a4df2f66 100644 --- a/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx +++ b/x-pack/plugins/ml/public/application/components/chart_tooltip/chart_tooltip.tsx @@ -60,7 +60,7 @@ const renderHeader = (headerData?: ChartTooltipValue, formatter?: TooltipValueFo return null; } - return formatter ? formatter(headerData) : headerData.name; + return formatter ? formatter(headerData) : headerData.label; }; export const ChartTooltip: FC = () => { @@ -85,20 +85,20 @@ export const ChartTooltip: FC = () => {
{tooltipData .slice(1) - .map(({ name, value, color, isHighlighted, seriesKey, yAccessor }) => { + .map(({ label, value, color, isHighlighted, seriesIdentifier, valueAccessor }) => { const classes = classNames('mlChartTooltip__item', { /* eslint @typescript-eslint/camelcase:0 */ echTooltip__rowHighlighted: isHighlighted, }); return (
- {name} + {label} {value}
); diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js index d0781fc8161f1..5fc1160093a49 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js @@ -440,16 +440,19 @@ export class ExplorerChartDistribution extends React.Component { // Show the time and metric values in the tooltip. // Uses date, value, upper, lower and anomalyScore (optional) marker properties. const formattedDate = formatHumanReadableDateTime(marker.date); - const tooltipData = [{ name: formattedDate }]; + const tooltipData = [{ label: formattedDate }]; const seriesKey = config.detectorLabel; if (_.has(marker, 'entity')) { tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.distributionChart.entityLabel', { + label: i18n.translate('xpack.ml.explorer.distributionChart.entityLabel', { defaultMessage: 'entity', }), value: marker.entity, - seriesKey, + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'entity', }); } @@ -457,36 +460,42 @@ export class ExplorerChartDistribution extends React.Component { const score = parseInt(marker.anomalyScore); const displayScore = score > 0 ? score : '< 1'; tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.distributionChart.anomalyScoreLabel', { + label: i18n.translate('xpack.ml.explorer.distributionChart.anomalyScoreLabel', { defaultMessage: 'anomaly score', }), value: displayScore, color: getSeverityColor(score), - seriesKey, - yAccessor: 'anomaly_score', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'anomaly_score', }); if (chartType !== CHART_TYPE.EVENT_DISTRIBUTION) { tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.distributionChart.valueLabel', { + label: i18n.translate('xpack.ml.explorer.distributionChart.valueLabel', { defaultMessage: 'value', }), value: formatValue(marker.value, config.functionDescription, fieldFormat), - seriesKey, - yAccessor: 'value', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'value', }); if (typeof marker.numberOfCauses === 'undefined' || marker.numberOfCauses === 1) { tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.distributionChart.typicalLabel', { + label: i18n.translate('xpack.ml.explorer.distributionChart.typicalLabel', { defaultMessage: 'typical', }), value: formatValue(marker.typical, config.functionDescription, fieldFormat), - seriesKey, - yAccessor: 'typical', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'typical', }); } if (typeof marker.byFieldName !== 'undefined' && _.has(marker, 'numberOfCauses')) { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.explorer.distributionChart.unusualByFieldValuesLabel', { defaultMessage: @@ -499,29 +508,33 @@ export class ExplorerChartDistribution extends React.Component { }, } ), - seriesKey, - yAccessor: 'numberOfCauses', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'numberOfCauses', }); } } } else if (chartType !== CHART_TYPE.EVENT_DISTRIBUTION) { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.explorer.distributionChart.valueWithoutAnomalyScoreLabel', { defaultMessage: 'value', } ), value: formatValue(marker.value, config.functionDescription, fieldFormat), - seriesKey, - yAccessor: 'value', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'value', }); } if (_.has(marker, 'scheduledEvents')) { marker.scheduledEvents.forEach((scheduledEvent, i) => { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.scheduledEventsLabel', { defaultMessage: 'scheduled event{counter}', @@ -529,8 +542,10 @@ export class ExplorerChartDistribution extends React.Component { } ), value: scheduledEvent, - seriesKey, - yAccessor: `scheduled_events_${i + 1}`, + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: `scheduled_events_${i + 1}`, }); }); } diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js index d8d6709175090..dd9479be931a7 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_single_metric.js @@ -384,30 +384,34 @@ export class ExplorerChartSingleMetric extends React.Component { // Show the time and metric values in the tooltip. // Uses date, value, upper, lower and anomalyScore (optional) marker properties. const formattedDate = formatHumanReadableDateTime(marker.date); - const tooltipData = [{ name: formattedDate }]; + const tooltipData = [{ label: formattedDate }]; const seriesKey = config.detectorLabel; if (_.has(marker, 'anomalyScore')) { const score = parseInt(marker.anomalyScore); const displayScore = score > 0 ? score : '< 1'; tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.singleMetricChart.anomalyScoreLabel', { + label: i18n.translate('xpack.ml.explorer.singleMetricChart.anomalyScoreLabel', { defaultMessage: 'anomaly score', }), value: displayScore, color: getSeverityColor(score), - seriesKey, - yAccessor: 'anomaly_score', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'anomaly_score', }); if (showMultiBucketAnomalyTooltip(marker) === true) { tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.singleMetricChart.multiBucketImpactLabel', { + label: i18n.translate('xpack.ml.explorer.singleMetricChart.multiBucketImpactLabel', { defaultMessage: 'multi-bucket impact', }), value: getMultiBucketImpactLabel(marker.multiBucketImpact), - seriesKey, - yAccessor: 'multi_bucket_impact', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'multi_bucket_impact', }); } @@ -418,33 +422,39 @@ export class ExplorerChartSingleMetric extends React.Component { // Display the record actual in preference to the chart value, which may be // different depending on the aggregation interval of the chart. tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.singleMetricChart.actualLabel', { + label: i18n.translate('xpack.ml.explorer.singleMetricChart.actualLabel', { defaultMessage: 'actual', }), value: formatValue(marker.actual, config.functionDescription, fieldFormat), - seriesKey, - yAccessor: 'actual', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'actual', }); tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.singleMetricChart.typicalLabel', { + label: i18n.translate('xpack.ml.explorer.singleMetricChart.typicalLabel', { defaultMessage: 'typical', }), value: formatValue(marker.typical, config.functionDescription, fieldFormat), - seriesKey, - yAccessor: 'typical', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'typical', }); } else { tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.singleMetricChart.valueLabel', { + label: i18n.translate('xpack.ml.explorer.singleMetricChart.valueLabel', { defaultMessage: 'value', }), value: formatValue(marker.value, config.functionDescription, fieldFormat), - seriesKey, - yAccessor: 'value', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'value', }); if (_.has(marker, 'byFieldName') && _.has(marker, 'numberOfCauses')) { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.explorer.distributionChart.unusualByFieldValuesLabel', { defaultMessage: @@ -457,31 +467,39 @@ export class ExplorerChartSingleMetric extends React.Component { }, } ), - seriesKey, - yAccessor: 'numberOfCauses', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'numberOfCauses', }); } } } else { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.explorer.singleMetricChart.valueWithoutAnomalyScoreLabel', { defaultMessage: 'value', } ), value: formatValue(marker.value, config.functionDescription, fieldFormat), - seriesKey, - yAccessor: 'value', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'value', }); } if (_.has(marker, 'scheduledEvents')) { tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.singleMetricChart.scheduledEventsLabel', { + label: i18n.translate('xpack.ml.explorer.singleMetricChart.scheduledEventsLabel', { defaultMessage: 'Scheduled events', }), value: marker.scheduledEvents.map(mlEscape).join('
'), + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'scheduledEvents', }); } diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.js b/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.js index 6582f5c609864..a229537ba3ca1 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.js @@ -323,24 +323,28 @@ export class ExplorerSwimlane extends React.Component { // Display date using same format as Kibana visualizations. const formattedDate = formatHumanReadableDateTime(time * 1000); - const tooltipData = [{ name: formattedDate }]; + const tooltipData = [{ label: formattedDate }]; if (swimlaneData.fieldName !== undefined) { tooltipData.push({ - name: swimlaneData.fieldName, + label: swimlaneData.fieldName, value: laneLabel, - seriesKey: laneLabel, - yAccessor: 'fieldName', + seriesIdentifier: { + key: laneLabel, + }, + valueAccessor: 'fieldName', }); } tooltipData.push({ - name: i18n.translate('xpack.ml.explorer.swimlane.maxAnomalyScoreLabel', { + label: i18n.translate('xpack.ml.explorer.swimlane.maxAnomalyScoreLabel', { defaultMessage: 'Max anomaly score', }), value: displayScore, color: colorScore(displayScore), - seriesKey: laneLabel, - yAccessor: 'anomaly_score', + seriesIdentifier: { + key: laneLabel, + }, + valueAccessor: 'anomaly_score', }); const offsets = target.className === 'sl-cell-inner' ? { x: 6, y: 0 } : { x: 8, y: 1 }; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js index bafb12de068bb..dffc268cb992b 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js @@ -1384,32 +1384,36 @@ class TimeseriesChartIntl extends Component { // Show the time and metric values in the tooltip. // Uses date, value, upper, lower and anomalyScore (optional) marker properties. const formattedDate = formatHumanReadableDateTimeSeconds(marker.date); - const tooltipData = [{ name: formattedDate }]; + const tooltipData = [{ label: formattedDate }]; if (_.has(marker, 'anomalyScore')) { const score = parseInt(marker.anomalyScore); const displayScore = score > 0 ? score : '< 1'; tooltipData.push({ - name: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.anomalyScoreLabel', { + label: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.anomalyScoreLabel', { defaultMessage: 'anomaly score', }), value: displayScore, color: anomalyColorScale(score), - seriesKey, - yAccessor: 'anomaly_score', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'anomaly_score', }); if (showMultiBucketAnomalyTooltip(marker) === true) { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.multiBucketImpactLabel', { defaultMessage: 'multi-bucket impact', } ), value: getMultiBucketImpactLabel(marker.multiBucketImpact), - seriesKey, - yAccessor: 'multi_bucket_impact', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'multi_bucket_impact', }); } @@ -1421,36 +1425,42 @@ class TimeseriesChartIntl extends Component { // Display the record actual in preference to the chart value, which may be // different depending on the aggregation interval of the chart. tooltipData.push({ - name: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.actualLabel', { + label: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.actualLabel', { defaultMessage: 'actual', }), value: formatValue(marker.actual, marker.function, fieldFormat), - seriesKey, - yAccessor: 'actual', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'actual', }); tooltipData.push({ - name: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.typicalLabel', { + label: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.typicalLabel', { defaultMessage: 'typical', }), value: formatValue(marker.typical, marker.function, fieldFormat), - seriesKey, - yAccessor: 'typical', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'typical', }); } else { tooltipData.push({ - name: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.valueLabel', { + label: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.valueLabel', { defaultMessage: 'value', }), value: formatValue(marker.value, marker.function, fieldFormat), - seriesKey, - yAccessor: 'value', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'value', }); if (_.has(marker, 'byFieldName') && _.has(marker, 'numberOfCauses')) { const numberOfCauses = marker.numberOfCauses; // If numberOfCauses === 1, won't go into this block as actual/typical copied to top level fields. const byFieldName = mlEscape(marker.byFieldName); tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.moreThanOneUnusualByFieldValuesLabel', { defaultMessage: '{numberOfCauses}{plusSign} unusual {byFieldName} values', @@ -1462,96 +1472,112 @@ class TimeseriesChartIntl extends Component { }, } ), - seriesKey, - yAccessor: 'numberOfCauses', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'numberOfCauses', }); } } } else { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.modelPlotEnabled.actualLabel', { defaultMessage: 'actual', } ), value: formatValue(marker.actual, marker.function, fieldFormat), - seriesKey, - yAccessor: 'actual', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'actual', }); tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.modelPlotEnabled.upperBoundsLabel', { defaultMessage: 'upper bounds', } ), value: formatValue(marker.upper, marker.function, fieldFormat), - seriesKey, - yAccessor: 'upper_bounds', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'upper_bounds', }); tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.modelPlotEnabled.lowerBoundsLabel', { defaultMessage: 'lower bounds', } ), value: formatValue(marker.lower, marker.function, fieldFormat), - seriesKey, - yAccessor: 'lower_bounds', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'lower_bounds', }); } } else { // TODO - need better formatting for small decimals. if (_.get(marker, 'isForecast', false) === true) { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.withoutAnomalyScore.predictionLabel', { defaultMessage: 'prediction', } ), value: formatValue(marker.value, marker.function, fieldFormat), - seriesKey, - yAccessor: 'prediction', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'prediction', }); } else { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.withoutAnomalyScore.valueLabel', { defaultMessage: 'value', } ), value: formatValue(marker.value, marker.function, fieldFormat), - seriesKey, - yAccessor: 'value', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'value', }); } if (modelPlotEnabled === true) { tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.withoutAnomalyScoreAndModelPlotEnabled.upperBoundsLabel', { defaultMessage: 'upper bounds', } ), value: formatValue(marker.upper, marker.function, fieldFormat), - seriesKey, - yAccessor: 'upper_bounds', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'upper_bounds', }); tooltipData.push({ - name: i18n.translate( + label: i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.withoutAnomalyScoreAndModelPlotEnabled.lowerBoundsLabel', { defaultMessage: 'lower bounds', } ), value: formatValue(marker.lower, marker.function, fieldFormat), - seriesKey, - yAccessor: 'lower_bounds', + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'lower_bounds', }); } } @@ -1559,23 +1585,29 @@ class TimeseriesChartIntl extends Component { if (_.has(marker, 'scheduledEvents')) { marker.scheduledEvents.forEach((scheduledEvent, i) => { tooltipData.push({ - name: i18n.translate('xpack.ml.timeSeriesExplorer.timeSeriesChart.scheduledEventsLabel', { - defaultMessage: 'scheduled event{counter}', - values: { - counter: marker.scheduledEvents.length > 1 ? ` #${i + 1}` : '', - }, - }), + label: i18n.translate( + 'xpack.ml.timeSeriesExplorer.timeSeriesChart.scheduledEventsLabel', + { + defaultMessage: 'scheduled event{counter}', + values: { + counter: marker.scheduledEvents.length > 1 ? ` #${i + 1}` : '', + }, + } + ), value: scheduledEvent, - seriesKey, - yAccessor: `scheduled_events_${i + 1}`, + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: `scheduled_events_${i + 1}`, }); }); } if (_.has(marker, 'annotation')) { tooltipData.length = 0; + // header tooltipData.push({ - name: marker.annotation, + label: marker.annotation, }); let timespan = moment(marker.timestamp).format('MMMM Do YYYY, HH:mm'); @@ -1583,7 +1615,11 @@ class TimeseriesChartIntl extends Component { timespan += ` - ${moment(marker.end_timestamp).format('MMMM Do YYYY, HH:mm')}`; } tooltipData.push({ - name: timespan, + label: timespan, + seriesIdentifier: { + key: seriesKey, + }, + valueAccessor: 'timespan', }); }