From c698e757976462f077793c3d154b16a98c33b882 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 15 Aug 2022 18:18:02 +0300 Subject: [PATCH 001/129] Added NavigateToLens types. --- .../common/convert_to_lens/constants.ts | 42 +++++ .../common/convert_to_lens/index.ts | 10 ++ .../common/convert_to_lens/types/columns.ts | 125 +++++++++++++++ .../common/convert_to_lens/types/common.ts | 47 ++++++ .../common/convert_to_lens/types/context.ts | 22 +++ .../common/convert_to_lens/types/index.ts | 13 ++ .../convert_to_lens/types/operations.ts | 14 ++ .../common/convert_to_lens/types/params.ts | 150 ++++++++++++++++++ 8 files changed, 423 insertions(+) create mode 100644 src/plugins/visualizations/common/convert_to_lens/constants.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/index.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/types/columns.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/types/common.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/types/context.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/types/index.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/types/operations.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/types/params.ts diff --git a/src/plugins/visualizations/common/convert_to_lens/constants.ts b/src/plugins/visualizations/common/convert_to_lens/constants.ts new file mode 100644 index 0000000000000..59f1ac09d0d32 --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/constants.ts @@ -0,0 +1,42 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const OperationsWithSourceField = { + FILTERS: 'filters', + RANGE: 'range', + TERMS: 'terms', + DATE_HISTOGRAM: 'date_histogram', + MIN: 'min', + MAX: 'max', + AVERAGE: 'average', + SUM: 'sum', + MEDIAN: 'median', + STANDARD_DEVIATION: 'standard_deviation', + UNIQUE_COUNT: 'unique_count', + PERCENTILE: 'percentile', + PERCENTILE_RANK: 'percentile_rank', + COUNT: 'count', + LAST_VALUE: 'last_value', +} as const; + +export const OperationsWithReferences = { + CUMULATIVE_SUM: 'cumulative_sum', + COUNTER_RATE: 'counter_rate', + DIFFERENCES: 'differences', + MOVING_AVERAGE: 'moving_average', + FORMULA: 'formula', + MATH: 'math', + OVERALL_SUM: 'overall_sum', + OVERALL_MIN: 'overall_min', + OVERALL_MAX: 'overall_max', + OVERALL_AVERAGE: 'overall_average', + STATIC_VALUE: 'static_value', + NORMALIZE_BY_UNIT: 'normalize_by_unit', +} as const; + +export const Operations = { ...OperationsWithSourceField, ...OperationsWithReferences } as const; diff --git a/src/plugins/visualizations/common/convert_to_lens/index.ts b/src/plugins/visualizations/common/convert_to_lens/index.ts new file mode 100644 index 0000000000000..8c1f7eaf9dd93 --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/index.ts @@ -0,0 +1,10 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export type * from './types'; +export * from './constants'; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts new file mode 100644 index 0000000000000..4ddd4ef1cb9b5 --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -0,0 +1,125 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { DataType, FilterQuery, TimeScaleUnit } from './common'; +import { Operation, OperationWithReferences, OperationWithSourceField } from './operations'; +import { + AvgParams, + CardinalityParams, + DateHistogramParams, + FiltersParams, + MaxParams, + MedianParams, + MinParams, + RangeParams, + StandardDeviationParams, + SumParams, + TermsParams, + PercentileParams, + PercentileRanksParams, + CountParams, + LastValueParams, + CumulativeSumParams, + CounterRateParams, + DerivativeParams, + MovingAverageParams, + FormulaParams, + MathParams, + TimeScaleParams, + StaticValueParams, +} from './params'; + +export interface BaseColumn { + columnId: string; + operationType: OperationType; + customLabel?: boolean; + label: string; + isBucketed: boolean; + dataType: DataType; + timeScale?: TimeScaleUnit; // ? + timeShift?: string; + window?: string; + scale?: 'ordinal' | 'interval' | 'ratio'; // ? + isStaticValue?: boolean; + filter?: FilterQuery; + params: Params; +} + +export interface ColumnWithSourceField + extends BaseColumn { + sourceField: string; +} + +export interface ColumnWithReferences + extends BaseColumn { + references: string[]; +} + +export type FitlersColumn = ColumnWithSourceField<'filters', FiltersParams>; +export type RangeColumn = ColumnWithSourceField<'range', RangeParams>; +export type TermsColumn = ColumnWithSourceField<'terms', TermsParams>; +export type DateHistogramColumn = ColumnWithSourceField<'date_histogram', DateHistogramParams>; +export type MinColumn = ColumnWithSourceField<'min', MinParams>; +export type MaxColumn = ColumnWithSourceField<'max', MaxParams>; +export type AvgColumn = ColumnWithSourceField<'average', AvgParams>; +export type SumColumn = ColumnWithSourceField<'sum', SumParams>; +export type MedianColumn = ColumnWithSourceField<'median', MedianParams>; +export type StandardDeviationColumn = ColumnWithSourceField< + 'standard_deviation', + StandardDeviationParams +>; +export type CardinalityColumn = ColumnWithSourceField<'unique_count', CardinalityParams>; +export type PercentileColumn = ColumnWithSourceField<'percentile', PercentileParams>; +export type PercentileRanksColumn = ColumnWithSourceField<'percentile_rank', PercentileRanksParams>; +export type CountColumn = ColumnWithSourceField<'count', CountParams>; +export type LastValueColumn = ColumnWithSourceField<'last_value', LastValueParams>; +export type CumulativeSumColumn = ColumnWithReferences<'cumulative_sum', CumulativeSumParams>; +export type CounterRateColumn = ColumnWithReferences<'counter_rate', CounterRateParams>; +export type DerivativeColumn = ColumnWithReferences<'differences', DerivativeParams>; +export type MovingAverageColumn = ColumnWithReferences<'moving_average', MovingAverageParams>; +export type FormulaColumn = ColumnWithReferences<'formula', FormulaParams>; +export type MathColumn = ColumnWithReferences<'math', MathParams>; +export type OverallSumColumn = ColumnWithReferences<'overall_sum'>; +export type OverallMinColumn = ColumnWithReferences<'overall_min'>; +export type OverallMaxColumn = ColumnWithReferences<'overall_max'>; +export type OverallAvgColumn = ColumnWithReferences<'overall_average'>; +export type StaticValueColumn = ColumnWithReferences<'static_value', StaticValueParams>; +export type TimeScaleColumn = ColumnWithReferences<'normalize_by_unit', TimeScaleParams>; + +export type AnyColumnWithSourceField = + | FitlersColumn + | RangeColumn + | TermsColumn + | DateHistogramColumn + | MinColumn + | MaxColumn + | AvgColumn + | SumColumn + | MedianColumn + | StandardDeviationColumn + | CardinalityColumn + | PercentileColumn + | PercentileRanksColumn + | CountColumn + | LastValueColumn; + +export type AnyColumnWithReferences = + | CumulativeSumColumn + | CounterRateColumn + | DerivativeColumn + | MovingAverageColumn + | FormulaColumn + | MathColumn + | OverallSumColumn + | OverallMinColumn + | OverallMaxColumn + | OverallAvgColumn + | StaticValueColumn + | TimeScaleColumn; + +export type Column = AnyColumnWithReferences | AnyColumnWithSourceField; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/common.ts b/src/plugins/visualizations/common/convert_to_lens/types/common.ts new file mode 100644 index 0000000000000..974326834ce2a --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/types/common.ts @@ -0,0 +1,47 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export type DataType = + | 'string' + | 'number' + | 'date' + | 'boolean' + | 'document' + | 'ip' + | 'histogram' + | 'geo_point' + | 'geo_shape' + | 'murmur3'; + +export type TimeScaleUnit = 's' | 'm' | 'h' | 'd'; + +export type SortingHint = 'version'; + +export interface FilterQuery { + query: string | { [key: string]: any }; + language: string; +} + +export interface Filter { + input: FilterQuery; + label: string; +} + +export interface Range { + from: number | null; + to: number | null; + label: string; +} + +export interface NumberValueFormat { + id: string; + params?: { + decimals: number; + suffix?: string; + }; +} diff --git a/src/plugins/visualizations/common/convert_to_lens/types/context.ts b/src/plugins/visualizations/common/convert_to_lens/types/context.ts new file mode 100644 index 0000000000000..cf36fbabc8bb7 --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/types/context.ts @@ -0,0 +1,22 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Column } from './columns'; + +export interface Layer { + indexPatternId: string; + layerId: string; + columns: Column[]; + columnOrder: string[]; +} + +export interface NavigateToLensContext { + layers: Record; + type: string; + configuration: unknown; +} diff --git a/src/plugins/visualizations/common/convert_to_lens/types/index.ts b/src/plugins/visualizations/common/convert_to_lens/types/index.ts new file mode 100644 index 0000000000000..f8fe0b88cab9d --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/types/index.ts @@ -0,0 +1,13 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './common'; +export * from './params'; +export * from './operations'; +export * from './columns'; +export * from './context'; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/operations.ts b/src/plugins/visualizations/common/convert_to_lens/types/operations.ts new file mode 100644 index 0000000000000..25226ed4fb83d --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/types/operations.ts @@ -0,0 +1,14 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { $Values } from '@kbn/utility-types'; +import { Operations, OperationsWithReferences, OperationsWithSourceField } from '../constants'; + +export type Operation = $Values; +export type OperationWithSourceField = $Values; +export type OperationWithReferences = $Values; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/params.ts b/src/plugins/visualizations/common/convert_to_lens/types/params.ts new file mode 100644 index 0000000000000..e040916e5e1c4 --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/types/params.ts @@ -0,0 +1,150 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { TinymathAST } from '@kbn/tinymath'; +import { Column } from './columns'; +import { Filter, NumberValueFormat } from './common'; + +export interface FiltersParams { + filters: Filter[]; +} + +export interface RangeParams { + type: 'histogram' | 'range'; + maxBars: 'auto' | number; + ranges: Range[]; + format?: NumberValueFormat; + includeEmptyRows?: boolean; + parentFormat?: { + id: string; + params?: { + id?: string; + template?: string; + replaceInfinity?: boolean; + }; + }; +} + +export interface TermsParams { + size: number; + accuracyMode?: boolean; + include?: string[] | number[]; + exclude?: string[] | number[]; + includeIsRegex?: boolean; + excludeIsRegex?: boolean; + orderBy: + | { type: 'alphabetical'; fallback?: boolean } + | { type: 'rare'; maxDocCount: number } + | { type: 'column'; columnId: string } + | { type: 'custom' }; + orderAgg?: Column; + orderDirection: 'asc' | 'desc'; + otherBucket?: boolean; + missingBucket?: boolean; + secondaryFields?: string[]; + format?: NumberValueFormat; + parentFormat?: { id: string }; +} + +export interface DateHistogramParams { + interval: string; + ignoreTimeRange?: boolean; + includeEmptyRows?: boolean; + dropPartials?: boolean; +} + +export interface MinParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface MaxParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface AvgParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface SumParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface MedianParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface StandardDeviationParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface CardinalityParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface PercentileParams { + percentile: number; + format?: NumberValueFormat; +} + +export interface PercentileRanksParams { + value: number; +} + +export interface CountParams { + emptyAsNull?: boolean; + format?: NumberValueFormat; +} + +export interface LastValueParams { + sortField: string; + showArrayValues: boolean; + format?: NumberValueFormat; +} + +export interface CumulativeSumParams { + format?: NumberValueFormat; +} + +export interface CounterRateParams { + format?: NumberValueFormat; +} + +export interface DerivativeParams { + format?: NumberValueFormat; +} + +export interface MovingAverageParams { + window: number; +} + +export interface FormulaParams { + formula?: string; + isFormulaBroken?: boolean; + format?: NumberValueFormat; +} + +export interface MathParams { + tinymathAst: TinymathAST | string; + format?: NumberValueFormat; +} + +export interface StaticValueParams { + value?: string; + format?: NumberValueFormat; +} + +export interface TimeScaleParams { + unit?: string; +} From de2b27b3d6d826584d085d64f443c488041a6342 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 16 Aug 2022 09:43:36 +0300 Subject: [PATCH 002/129] Removed math/overall* columns to be replaced by Formula. --- .../common/convert_to_lens/constants.ts | 5 ----- .../common/convert_to_lens/types/columns.ts | 11 ----------- .../common/convert_to_lens/types/operations.ts | 4 ++-- .../common/convert_to_lens/types/params.ts | 6 ------ 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/plugins/visualizations/common/convert_to_lens/constants.ts b/src/plugins/visualizations/common/convert_to_lens/constants.ts index 59f1ac09d0d32..bd312129c9779 100644 --- a/src/plugins/visualizations/common/convert_to_lens/constants.ts +++ b/src/plugins/visualizations/common/convert_to_lens/constants.ts @@ -30,11 +30,6 @@ export const OperationsWithReferences = { DIFFERENCES: 'differences', MOVING_AVERAGE: 'moving_average', FORMULA: 'formula', - MATH: 'math', - OVERALL_SUM: 'overall_sum', - OVERALL_MIN: 'overall_min', - OVERALL_MAX: 'overall_max', - OVERALL_AVERAGE: 'overall_average', STATIC_VALUE: 'static_value', NORMALIZE_BY_UNIT: 'normalize_by_unit', } as const; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index 4ddd4ef1cb9b5..a6c040e523da8 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -29,7 +29,6 @@ import { DerivativeParams, MovingAverageParams, FormulaParams, - MathParams, TimeScaleParams, StaticValueParams, } from './params'; @@ -83,11 +82,6 @@ export type CounterRateColumn = ColumnWithReferences<'counter_rate', CounterRate export type DerivativeColumn = ColumnWithReferences<'differences', DerivativeParams>; export type MovingAverageColumn = ColumnWithReferences<'moving_average', MovingAverageParams>; export type FormulaColumn = ColumnWithReferences<'formula', FormulaParams>; -export type MathColumn = ColumnWithReferences<'math', MathParams>; -export type OverallSumColumn = ColumnWithReferences<'overall_sum'>; -export type OverallMinColumn = ColumnWithReferences<'overall_min'>; -export type OverallMaxColumn = ColumnWithReferences<'overall_max'>; -export type OverallAvgColumn = ColumnWithReferences<'overall_average'>; export type StaticValueColumn = ColumnWithReferences<'static_value', StaticValueParams>; export type TimeScaleColumn = ColumnWithReferences<'normalize_by_unit', TimeScaleParams>; @@ -114,11 +108,6 @@ export type AnyColumnWithReferences = | DerivativeColumn | MovingAverageColumn | FormulaColumn - | MathColumn - | OverallSumColumn - | OverallMinColumn - | OverallMaxColumn - | OverallAvgColumn | StaticValueColumn | TimeScaleColumn; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/operations.ts b/src/plugins/visualizations/common/convert_to_lens/types/operations.ts index 25226ed4fb83d..a489bf6c0a974 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/operations.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/operations.ts @@ -10,5 +10,5 @@ import { $Values } from '@kbn/utility-types'; import { Operations, OperationsWithReferences, OperationsWithSourceField } from '../constants'; export type Operation = $Values; -export type OperationWithSourceField = $Values; -export type OperationWithReferences = $Values; +export type OperationWithSourceField = $Values; +export type OperationWithReferences = $Values; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/params.ts b/src/plugins/visualizations/common/convert_to_lens/types/params.ts index e040916e5e1c4..1f7444ebdd236 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/params.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/params.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { TinymathAST } from '@kbn/tinymath'; import { Column } from './columns'; import { Filter, NumberValueFormat } from './common'; @@ -135,11 +134,6 @@ export interface FormulaParams { format?: NumberValueFormat; } -export interface MathParams { - tinymathAst: TinymathAST | string; - format?: NumberValueFormat; -} - export interface StaticValueParams { value?: string; format?: NumberValueFormat; From f1a628aaa0d315f5af30dd055115f70faa5f5f20 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 16 Aug 2022 09:52:47 +0300 Subject: [PATCH 003/129] Removed Lens specific columns/fields. --- .../common/convert_to_lens/types/columns.ts | 6 +----- .../common/convert_to_lens/types/params.ts | 9 --------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index a6c040e523da8..d0a34d9a6a0c2 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -29,7 +29,6 @@ import { DerivativeParams, MovingAverageParams, FormulaParams, - TimeScaleParams, StaticValueParams, } from './params'; @@ -43,7 +42,6 @@ export interface BaseColumn timeScale?: TimeScaleUnit; // ? timeShift?: string; window?: string; - scale?: 'ordinal' | 'interval' | 'ratio'; // ? isStaticValue?: boolean; filter?: FilterQuery; params: Params; @@ -83,7 +81,6 @@ export type DerivativeColumn = ColumnWithReferences<'differences', DerivativePar export type MovingAverageColumn = ColumnWithReferences<'moving_average', MovingAverageParams>; export type FormulaColumn = ColumnWithReferences<'formula', FormulaParams>; export type StaticValueColumn = ColumnWithReferences<'static_value', StaticValueParams>; -export type TimeScaleColumn = ColumnWithReferences<'normalize_by_unit', TimeScaleParams>; export type AnyColumnWithSourceField = | FitlersColumn @@ -108,7 +105,6 @@ export type AnyColumnWithReferences = | DerivativeColumn | MovingAverageColumn | FormulaColumn - | StaticValueColumn - | TimeScaleColumn; + | StaticValueColumn; export type Column = AnyColumnWithReferences | AnyColumnWithSourceField; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/params.ts b/src/plugins/visualizations/common/convert_to_lens/types/params.ts index 1f7444ebdd236..a3bd11f32542e 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/params.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/params.ts @@ -31,7 +31,6 @@ export interface RangeParams { export interface TermsParams { size: number; - accuracyMode?: boolean; include?: string[] | number[]; exclude?: string[] | number[]; includeIsRegex?: boolean; @@ -58,37 +57,30 @@ export interface DateHistogramParams { } export interface MinParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } export interface MaxParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } export interface AvgParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } export interface SumParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } export interface MedianParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } export interface StandardDeviationParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } export interface CardinalityParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } @@ -102,7 +94,6 @@ export interface PercentileRanksParams { } export interface CountParams { - emptyAsNull?: boolean; format?: NumberValueFormat; } From 0733449c50afb993684b5337a168fe7412eb419b Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 16 Aug 2022 14:24:44 +0300 Subject: [PATCH 004/129] Added percentile column convertion. --- .../timeseries/common/types/index.ts | 2 +- .../timeseries/common/types/panel_model.ts | 2 +- .../convert_to_lens/lib/convert/column.ts | 34 +++++++++++ .../convert_to_lens/lib/convert/index.ts | 9 +++ .../convert_to_lens/lib/convert/percentile.ts | 59 +++++++++++++++++++ .../lib/datasource/get_datasource_info.ts | 16 +++-- .../convert_to_lens/lib/series/new.columns.ts | 33 +++++++++++ .../convert_to_lens/timeseries/new.index.ts | 51 ++++++++++++++++ .../public/convert_to_lens/types.ts | 10 +++- .../common/convert_to_lens/index.ts | 2 +- src/plugins/visualizations/common/index.ts | 2 + 11 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts diff --git a/src/plugins/vis_types/timeseries/common/types/index.ts b/src/plugins/vis_types/timeseries/common/types/index.ts index 4076ca1a0bb24..9f4f471d7a5a9 100644 --- a/src/plugins/vis_types/timeseries/common/types/index.ts +++ b/src/plugins/vis_types/timeseries/common/types/index.ts @@ -11,7 +11,7 @@ import { KBN_FIELD_TYPES, Query } from '@kbn/data-plugin/common'; import type { DataView } from '@kbn/data-views-plugin/public'; import { Panel } from './panel_model'; -export type { Metric, Series, Panel, MetricType } from './panel_model'; +export type { Metric, Series, Panel, MetricType, Percentile } from './panel_model'; export type { TimeseriesVisData, PanelData, diff --git a/src/plugins/vis_types/timeseries/common/types/panel_model.ts b/src/plugins/vis_types/timeseries/common/types/panel_model.ts index 33382b74b62ba..74ec934497703 100644 --- a/src/plugins/vis_types/timeseries/common/types/panel_model.ts +++ b/src/plugins/vis_types/timeseries/common/types/panel_model.ts @@ -22,7 +22,7 @@ interface MetricVariable { name?: string; } -interface Percentile { +export interface Percentile { id: string; mode: 'line' | 'band'; field?: string; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts new file mode 100644 index 0000000000000..2bef7ada3ad16 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -0,0 +1,34 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; +import { BaseColumn, Operation, DataType, Column } from '@kbn/visualizations-plugin/common'; +import uuid from 'uuid'; +import type { Metric, Series } from '../../../../common/types'; +import { ConvertToColumnsFn } from '../../types'; + +export const createColumn = ( + series: Series, + metric: Metric, + field: DataViewField, + isBucketed: boolean = false +): Omit, 'operationType' | 'params'> => ({ + columnId: uuid(), + dataType: field.type as DataType, + label: series.label ?? field.name, + customLabel: series.label ? true : false, + isBucketed, + window: metric.window?.toString(), + filter: series.filter, +}); + +export const convertMetricsToColumns = ( + series: Series, + metrics: Metric[], + dataView: DataView, + convertToFn: ConvertToColumnsFn +) => metrics.flatMap((metric) => convertToFn(series, metric, dataView)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts new file mode 100644 index 0000000000000..17c777258821f --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -0,0 +1,9 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { convertToPercentileColumns } from './percentile'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts new file mode 100644 index 0000000000000..00455682ca3ab --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -0,0 +1,59 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import { PercentileColumn, PercentileParams } from '@kbn/visualizations-plugin/common'; +import type { Metric, Percentile, Series } from '../../../../common/types'; +import { createColumn } from './column'; + +const convertToPercentileParams = ({ value }: Percentile): PercentileParams | null => + value !== undefined && !isNaN(Number(value)) + ? { + percentile: Number(value), + } + : null; + +const convertToPercentileColumn = ( + percentile: Percentile, + series: Series, + metric: Metric, + dataView: DataView +): PercentileColumn | null => { + const params = convertToPercentileParams(percentile); + if (!params) { + return null; + } + + const field = dataView.getFieldByName(metric.field ?? 'document'); + if (!field) { + return null; + } + + return { + operationType: 'percentile', + sourceField: field.name, + ...createColumn(series, metric, field), + params, + }; +}; + +export const convertToPercentileColumns = ( + series: Series, + metric: Metric, + dataView: DataView +): PercentileColumn[] => { + const { percentiles } = metric; + + if (!percentiles) { + return []; + } + + return percentiles + .map((p) => convertToPercentileColumn(p, series, metric, dataView)) + .filter((p): p is PercentileColumn => Boolean(p)); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts index 8377ddafe1926..5a9b74b7a41c3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import { DataView, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { fetchIndexPattern, isStringTypeIndexPattern, @@ -23,9 +23,12 @@ export const getDataSourceInfo = async ( modelIndexPattern && !isStringTypeIndexPattern(modelIndexPattern) ? modelIndexPattern.id : ''; let timeField = modelTimeField; + let indexPattern: DataView | null | undefined; // handle override index pattern if (isOverwritten) { - const { indexPattern } = await fetchIndexPattern(overwrittenIndexPattern, dataViews); + const fetchedIndexPattern = await fetchIndexPattern(overwrittenIndexPattern, dataViews); + indexPattern = fetchedIndexPattern.indexPattern; + if (indexPattern) { indexPatternId = indexPattern.id ?? ''; timeField = indexPattern.timeFieldName; @@ -33,17 +36,18 @@ export const getDataSourceInfo = async ( } if (!indexPatternId) { - const defaultIndex = await dataViews.getDefault(); - indexPatternId = defaultIndex?.id ?? ''; - timeField = defaultIndex?.timeFieldName; + indexPattern = await dataViews.getDefault(); + indexPatternId = indexPattern?.id ?? ''; + timeField = indexPattern?.timeFieldName; } if (!timeField) { - const indexPattern = await dataViews.get(indexPatternId); + indexPattern = await dataViews.get(indexPatternId); timeField = indexPattern.timeFieldName; } return { indexPatternId, timeField, + indexPattern, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts new file mode 100644 index 0000000000000..b58462c91e103 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -0,0 +1,33 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Column } from '@kbn/visualizations-plugin/common'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { Series } from '../../../../common/types'; +import { getSeriesAgg } from './get_series_agg'; +import { SUPPORTED_METRICS } from '../metrics'; +import { convertToPercentileColumns } from '../convert'; +import { convertMetricsToColumns } from '../convert/column'; + +export const getColumns = (series: Series, dataView: DataView): Column[] | null => { + const { metrics } = getSeriesAgg(series.metrics); + const metricIdx = metrics.length - 1; + const aggregation = metrics[metricIdx].type; + const aggregationMap = SUPPORTED_METRICS[aggregation]; + if (!aggregationMap) { + return null; + } + + switch (aggregation) { + case 'percentile': { + return convertMetricsToColumns(series, metrics, dataView, convertToPercentileColumns); + } + } + + return []; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts new file mode 100644 index 0000000000000..5d7bfe218494b --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -0,0 +1,51 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Layer, NavigateToLensContext } from '@kbn/visualizations-plugin/common'; +import uuid from 'uuid'; +import { Panel } from '../../../common/types'; +import { getDataViewsStart } from '../../services'; +import { getDataSourceInfo } from '../lib/datasource'; +import { getColumns } from '../lib/series/new.columns'; + +export const convertToLens = async (model: Panel): Promise => { + const dataViews = getDataViewsStart(); + const columns = []; + const layers: Record = {}; + // handle multiple layers/series + for (let layerIdx = 0; layerIdx < model.series.length; layerIdx++) { + const series = model.series[layerIdx]; + if (series.hidden) { + continue; + } + + const { indexPatternId, indexPattern } = await getDataSourceInfo( + model.index_pattern, + model.time_field, + Boolean(series.override_index_pattern), + series.series_index_pattern, + dataViews + ); + + // handle multiple metrics + const seriesColumns = getColumns(series, indexPattern!); + if (!seriesColumns) { + return null; + } + + columns.push(...seriesColumns); + const layerId = uuid(); + layers[layerIdx] = { indexPatternId, layerId, columns, columnOrder: [] }; // TODO: update later. + } + + return { + layers, + type: 'lnsXY', + configuration: {}, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index 8c17b9ec6ce57..ff359bd9427e4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -6,8 +6,10 @@ * Side Public License, v 1. */ +import { Column } from '@kbn/visualizations-plugin/common'; +import type { DataView } from '@kbn/data-views-plugin/common'; import { NavigateToLensContext } from '@kbn/visualizations-plugin/public'; -import type { Panel } from '../../common/types'; +import type { Metric, Panel, Series } from '../../common/types'; export type ConvertTsvbToLensVisualization = ( model: Panel @@ -17,3 +19,9 @@ export interface Filter { kql?: string | { [key: string]: any } | undefined; lucene?: string | { [key: string]: any } | undefined; } + +export type ConvertToColumnsFn = ( + series: Series, + metric: Metric, + dataView: DataView +) => C[]; diff --git a/src/plugins/visualizations/common/convert_to_lens/index.ts b/src/plugins/visualizations/common/convert_to_lens/index.ts index 8c1f7eaf9dd93..f47605f92719d 100644 --- a/src/plugins/visualizations/common/convert_to_lens/index.ts +++ b/src/plugins/visualizations/common/convert_to_lens/index.ts @@ -6,5 +6,5 @@ * Side Public License, v 1. */ -export type * from './types'; +export * from './types'; export * from './constants'; diff --git a/src/plugins/visualizations/common/index.ts b/src/plugins/visualizations/common/index.ts index 1dd9a0e90477c..dde60809ea593 100644 --- a/src/plugins/visualizations/common/index.ts +++ b/src/plugins/visualizations/common/index.ts @@ -13,4 +13,6 @@ export * from './types'; export * from './utils'; export * from './expression_functions'; +export * from './convert_to_lens'; + export { LegendSize, LegendSizeToPixels, DEFAULT_LEGEND_SIZE } from './constants'; From 1749b10019362c7e637a6975ae9615015412fe4b Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 16 Aug 2022 14:38:10 +0300 Subject: [PATCH 005/129] Fixed labels. --- .../timeseries/public/convert_to_lens/lib/convert/column.ts | 3 +-- .../visualizations/common/convert_to_lens/types/columns.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 2bef7ada3ad16..567bf3178d057 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -19,8 +19,7 @@ export const createColumn = ( ): Omit, 'operationType' | 'params'> => ({ columnId: uuid(), dataType: field.type as DataType, - label: series.label ?? field.name, - customLabel: series.label ? true : false, + label: series.label, isBucketed, window: metric.window?.toString(), filter: series.filter, diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index d0a34d9a6a0c2..f9fc2afcbd3db 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -35,8 +35,7 @@ import { export interface BaseColumn { columnId: string; operationType: OperationType; - customLabel?: boolean; - label: string; + label?: string; isBucketed: boolean; dataType: DataType; timeScale?: TimeScaleUnit; // ? From 15ab59a87bf0daffe4362cea4a7014a12bc71d7a Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Wed, 17 Aug 2022 10:30:07 +0300 Subject: [PATCH 006/129] Add percentile_rank converter --- .../convert_to_lens/lib/convert/index.ts | 1 + .../lib/convert/percentile_rank.ts | 59 +++++++++++++++++++ .../convert_to_lens/lib/series/new.columns.ts | 5 +- 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 17c777258821f..fb32e632b4fbc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -7,3 +7,4 @@ */ export { convertToPercentileColumns } from './percentile'; +export { convertToPercentileRankColumns } from './percentile_rank'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts new file mode 100644 index 0000000000000..d8578b396d707 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -0,0 +1,59 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import { PercentileRanksColumn, PercentileRanksParams } from '@kbn/visualizations-plugin/common'; +import type { Metric, Series } from '../../../../common/types'; +import { createColumn } from './column'; + +const convertToPercentileRankParams = (value: string): PercentileRanksParams | null => + value !== undefined && !isNaN(Number(value)) + ? { + value: Number(value), + } + : null; + +const convertToPercentileRankColumn = ( + value: string, + series: Series, + metric: Metric, + dataView: DataView +): PercentileRanksColumn | null => { + const params = convertToPercentileRankParams(value); + if (!params) { + return null; + } + + const field = dataView.getFieldByName(metric.field ?? 'document'); + if (!field) { + return null; + } + + return { + operationType: 'percentile_rank', + sourceField: field.name, + ...createColumn(series, metric, field), + params, + }; +}; + +export const convertToPercentileRankColumns = ( + series: Series, + metric: Metric, + dataView: DataView +): PercentileRanksColumn[] => { + const { values } = metric; + + if (!values) { + return []; + } + + return values + .map((p) => convertToPercentileRankColumn(p, series, metric, dataView)) + .filter((p): p is PercentileRanksColumn => Boolean(p)); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index b58462c91e103..95ce4c8c90b82 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -11,7 +11,7 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import type { Series } from '../../../../common/types'; import { getSeriesAgg } from './get_series_agg'; import { SUPPORTED_METRICS } from '../metrics'; -import { convertToPercentileColumns } from '../convert'; +import { convertToPercentileColumns, convertToPercentileRankColumns } from '../convert'; import { convertMetricsToColumns } from '../convert/column'; export const getColumns = (series: Series, dataView: DataView): Column[] | null => { @@ -27,6 +27,9 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null case 'percentile': { return convertMetricsToColumns(series, metrics, dataView, convertToPercentileColumns); } + case 'percentile_rank': { + return convertMetricsToColumns(series, metrics, dataView, convertToPercentileRankColumns); + } } return []; From 8f1ca404d63ef04c6972d1e5382c868f8731353b Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Wed, 17 Aug 2022 13:50:17 +0300 Subject: [PATCH 007/129] Added math formula and timeScale support. --- .../convert_to_lens/lib/convert/column.ts | 2 + .../convert_to_lens/lib/convert/formula.ts | 129 ++++++++++++++++++ .../convert_to_lens/lib/convert/index.ts | 2 + .../lib/metrics/metrics_helpers.ts | 17 ++- .../convert_to_lens/lib/series/new.columns.ts | 11 +- 5 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 567bf3178d057..56054061c0016 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -10,6 +10,7 @@ import { BaseColumn, Operation, DataType, Column } from '@kbn/visualizations-plu import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; import { ConvertToColumnsFn } from '../../types'; +import { getTimeScale } from '../metrics'; export const createColumn = ( series: Series, @@ -23,6 +24,7 @@ export const createColumn = ( isBucketed, window: metric.window?.toString(), filter: series.filter, + timeScale: getTimeScale(metric), }); export const convertMetricsToColumns = ( diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts new file mode 100644 index 0000000000000..0bf72641a4db2 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -0,0 +1,129 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import { FormulaColumn, FormulaParams } from '@kbn/visualizations-plugin/common'; +import type { Metric, Series } from '../../../../common/types'; +import { getFormulaEquivalent } from '../metrics'; +import { createColumn } from './column'; + +const convertToFormulaParams = (formula: string): FormulaParams | null => ({ + formula, +}); + +const createFormulaColumn = ( + mathScript: string, + series: Series, + metric: Metric, + dataView: DataView +): FormulaColumn | null => { + const params = convertToFormulaParams(mathScript); + if (!params) { + return null; + } + + const field = dataView.getFieldByName(metric.field ?? 'document'); + if (!field) { + return null; + } + + return { + operationType: 'formula', + references: [], + ...createColumn(series, metric, field), + params, + }; +}; + +const convertFormulaScriptForPercentileAggs = ( + mathScript: string, + variables: Exclude, + metric: Metric, + allAggMetrics: Metric[] +) => { + variables.forEach((variable) => { + const [_, meta] = variable?.field?.split('[') ?? []; + const metaValue = Number(meta?.replace(']', '')); + if (!metaValue) { + return; + } + const script = getFormulaEquivalent(metric, allAggMetrics, metaValue); + if (!script) { + return; + } + mathScript = mathScript?.replace(`params.${variable.name}`, script); + }); + return mathScript; +}; + +const convertFormulaScriptForAggs = ( + mathScript: string, + variables: Exclude, + metric: Metric, + allAggMetrics: Metric[] +) => { + const script = getFormulaEquivalent(metric, allAggMetrics); + if (!script) { + return null; + } + const variable = variables.find((v) => v.field === metric.id); + return mathScript?.replaceAll(`params.${variable?.name}`, script); +}; + +export const convertMathToFormulaColumn = ( + series: Series, + metrics: Metric[], + dataView: DataView +): FormulaColumn | null => { + // find the metric idx that has math expression + const mathMetric = metrics.find((metric) => metric.type === 'math'); + let script: string | null | undefined = metrics[metrics.length - 1].script; + + if (!mathMetric) { + return null; + } + + const { variables } = mathMetric; + + if (!script || !variables) { + return null; + } + + const metricsWithoutMath = metrics.filter((metric) => metric.type !== 'math'); + + // create the script + for (const notMathMetric of metricsWithoutMath) { + // We can only support top_hit with size 1 + if ( + (notMathMetric.type === 'top_hit' && + notMathMetric?.size && + Number(notMathMetric?.size) !== 1) || + notMathMetric?.order === 'asc' + ) { + return null; + } + + // should treat percentiles differently + if (notMathMetric.type === 'percentile' || notMathMetric.type === 'percentile_rank') { + script = convertFormulaScriptForPercentileAggs(script!, variables, notMathMetric, metrics); + } else { + script = convertFormulaScriptForAggs(script!, variables, notMathMetric, metrics); + } + } + + if (script === null) { + return null; + } + + const scripthasNoStaticNumber = isNaN(Number(script)); + if (script.includes('params') || !scripthasNoStaticNumber) { + return null; + } + + return createFormulaColumn(script, series, mathMetric, dataView); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index fb32e632b4fbc..7be9d5b8436e4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -6,5 +6,7 @@ * Side Public License, v 1. */ +export { convertMetricsToColumns } from './column'; export { convertToPercentileColumns } from './percentile'; export { convertToPercentileRankColumns } from './percentile_rank'; +export { convertMathToFormulaColumn } from './formula'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index fdc7f4ca2f6d0..b7c45721eabf7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { TimeScaleUnit } from '@kbn/visualizations-plugin/common'; import type { Metric } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; import { getFilterRatioFormula } from './filter_ratio_formula'; @@ -40,11 +41,17 @@ export const getPercentileRankSeries = ( }); }; -export const getTimeScale = (metric: Metric) => { - const supportedTimeScales = ['1s', '1m', '1h', '1d']; - let timeScale; - if (metric.unit && supportedTimeScales.includes(metric.unit)) { - timeScale = metric.unit.replace('1', ''); +type TimeScaleValue = `1${TimeScaleUnit}`; + +const isTimeScaleValue = (unit: string): unit is TimeScaleValue => { + const supportedTimeScales: TimeScaleValue[] = ['1s', '1m', '1h', '1d']; + return supportedTimeScales.includes(unit as TimeScaleValue); +}; + +export const getTimeScale = (metric: Metric): TimeScaleUnit | undefined => { + let timeScale: TimeScaleUnit | undefined; + if (metric.unit && isTimeScaleValue(metric.unit)) { + timeScale = metric.unit.replace('1', '') as TimeScaleUnit; } return timeScale; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index 95ce4c8c90b82..0695a2648056c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -11,8 +11,12 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import type { Series } from '../../../../common/types'; import { getSeriesAgg } from './get_series_agg'; import { SUPPORTED_METRICS } from '../metrics'; -import { convertToPercentileColumns, convertToPercentileRankColumns } from '../convert'; -import { convertMetricsToColumns } from '../convert/column'; +import { + convertMetricsToColumns, + convertToPercentileColumns, + convertToPercentileRankColumns, + convertMathToFormulaColumn, +} from '../convert'; export const getColumns = (series: Series, dataView: DataView): Column[] | null => { const { metrics } = getSeriesAgg(series.metrics); @@ -30,6 +34,9 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null case 'percentile_rank': { return convertMetricsToColumns(series, metrics, dataView, convertToPercentileRankColumns); } + case 'math': + const formulaColumn = convertMathToFormulaColumn(series, metrics, dataView); + return formulaColumn ? [formulaColumn] : null; } return []; From 6e3cfb916bc13357c6a043b5bee29553ff529863 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Thu, 18 Aug 2022 15:15:43 +0300 Subject: [PATCH 008/129] Added MovingAverage and Derivative support. --- .../convert_to_lens/lib/convert/formula.ts | 2 +- .../convert_to_lens/lib/convert/index.ts | 1 + .../lib/convert/moving_average.ts | 46 ++++ .../lib/convert/parent_pipeline.ts | 251 ++++++++++++++++++ .../convert_to_lens/lib/convert/percentile.ts | 4 +- .../lib/convert/percentile_rank.ts | 2 +- .../lib/metrics/filter_ratio_formula.ts | 8 +- .../lib/metrics/metrics_helpers.ts | 12 +- .../lib/metrics/parent_pipeline_formula.ts | 7 +- .../lib/metrics/parent_pipeline_series.ts | 14 +- .../lib/metrics/sibling_pipeline_formula.ts | 3 + .../lib/metrics/supported_metrics.ts | 77 +++++- .../convert_to_lens/lib/series/get_series.ts | 9 +- .../convert_to_lens/lib/series/new.columns.ts | 19 ++ 14 files changed, 419 insertions(+), 36 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 0bf72641a4db2..61349faef76c7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -16,7 +16,7 @@ const convertToFormulaParams = (formula: string): FormulaParams | null => ({ formula, }); -const createFormulaColumn = ( +export const createFormulaColumn = ( mathScript: string, series: Series, metric: Metric, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 7be9d5b8436e4..e74908360aebd 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -10,3 +10,4 @@ export { convertMetricsToColumns } from './column'; export { convertToPercentileColumns } from './percentile'; export { convertToPercentileRankColumns } from './percentile_rank'; export { convertMathToFormulaColumn } from './formula'; +export { convertParentPipelineAggToColumns } from './parent_pipeline'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts new file mode 100644 index 0000000000000..bde701ff3b52e --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts @@ -0,0 +1,46 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { + DerivativeColumn, + MovingAverageColumn, + MovingAverageParams, + Operations, +} from '@kbn/visualizations-plugin/common'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { Metric, Series } from '../../../../common/types'; +import { createColumn } from './column'; + +const convertToMovingAverageParams = ({ window }: Metric): MovingAverageParams => ({ + window: window ?? 0, +}); + +export const createMovingAverageOrDerivativeColumn = ( + aggregation: typeof Operations.DIFFERENCES | typeof Operations.MOVING_AVERAGE, + series: Series, + metric: Metric, + dataView: DataView, + references: string[] = [] +) => { + const params = convertToMovingAverageParams(metric); + if (!params) { + return null; + } + + const field = dataView.getFieldByName(metric.field ?? 'document'); + if (!field) { + return null; + } + + return { + operationType: aggregation, + references, + ...createColumn(series, metric, field), + params, + } as MovingAverageColumn | DerivativeColumn; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts new file mode 100644 index 0000000000000..7fa5de91bbe97 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -0,0 +1,251 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { + AvgColumn, + CardinalityColumn, + CountColumn, + CounterRateColumn, + LastValueColumn, + MaxColumn, + MinColumn, + Operations, + PercentileColumn, + PercentileRanksColumn, + SumColumn, +} from '@kbn/visualizations-plugin/common'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { Metric, Series } from '../../../../common/types'; +import { + getFilterRatioFormula, + getParentPipelineSeriesFormula, + getPipelineAgg, + SUPPORTED_METRICS, +} from '../metrics'; +import { createColumn } from './column'; +import { createFormulaColumn } from './formula'; +import { createMovingAverageOrDerivativeColumn } from './moving_average'; +import { convertToPercentileParams } from './percentile'; +import { convertToPercentileRankParams } from './percentile_rank'; + +type ParentPipelineAggregation = + | typeof Operations.AVERAGE + | typeof Operations.COUNT + | typeof Operations.UNIQUE_COUNT + | typeof Operations.COUNTER_RATE + | typeof Operations.MAX + | typeof Operations.MIN + | typeof Operations.SUM + | typeof Operations.LAST_VALUE + | typeof Operations.PERCENTILE + | typeof Operations.PERCENTILE_RANK; + +type ParentPipelineAggregationColumnWithParams = + | PercentileColumn + | PercentileRanksColumn + | LastValueColumn; + +type ParentPipelineAggregationColumnWithoutParams = + | AvgColumn + | CountColumn + | CardinalityColumn + | CounterRateColumn + | MaxColumn + | MinColumn + | SumColumn; + +type ParentPipelineAggregationColumn = + | ParentPipelineAggregationColumnWithoutParams + | ParentPipelineAggregationColumnWithParams; + +const SUPPORTED_PARENT_PIPELINE_AGGS: ParentPipelineAggregation[] = [ + Operations.AVERAGE, + Operations.COUNT, + Operations.UNIQUE_COUNT, + Operations.COUNTER_RATE, + Operations.MAX, + Operations.MIN, + Operations.SUM, + Operations.LAST_VALUE, + Operations.PERCENTILE, + Operations.PERCENTILE_RANK, +]; + +const isSupportedAggregation = (agg: string): agg is ParentPipelineAggregation => { + return !(SUPPORTED_PARENT_PIPELINE_AGGS as string[]).includes(agg); +}; + +export const convertParentPipelineAggToColumn = ( + aggregation: string, + series: Series, + parentPipelineMetric: Metric, + dataView: DataView, + meta?: number +): ParentPipelineAggregationColumn | null => { + if (!isSupportedAggregation(aggregation)) { + return null; + } + + const field = dataView.getFieldByName(parentPipelineMetric.field ?? 'document'); + if (!field) { + return null; + } + + if (aggregation === Operations.PERCENTILE) { + const params = convertToPercentileParams(meta); + return params + ? { + operationType: aggregation, + sourceField: field.name, + ...createColumn(series, parentPipelineMetric, field), + params, + } + : null; + } + + if (aggregation === Operations.PERCENTILE_RANK) { + const params = convertToPercentileRankParams(meta?.toString() ?? ''); + return params + ? { + operationType: aggregation, + sourceField: field.name, + ...createColumn(series, parentPipelineMetric, field), + params, + } + : null; + } + + if (aggregation === Operations.LAST_VALUE) { + return null; + } + + return { + operationType: aggregation, + sourceField: field.name, + ...createColumn(series, parentPipelineMetric, field), + params: {}, + } as ParentPipelineAggregationColumnWithoutParams; +}; + +export const computeParentPipelineColumns = ( + aggregation: typeof Operations.MOVING_AVERAGE | typeof Operations.DIFFERENCES, + series: Series, + currentMetric: Metric, + dataView: DataView, + subFunctionMetric: Metric, + pipelineAgg: string, + meta?: number +) => { + const aggregationMap = SUPPORTED_METRICS[currentMetric.type]; + if (!aggregationMap) { + return null; + } + + if (subFunctionMetric.type === 'filter_ratio') { + const script = getFilterRatioFormula(subFunctionMetric); + if (!script) { + return null; + } + const formula = `${aggregationMap.name}(${script})`; + return createFormulaColumn(formula, series, currentMetric, dataView); + } + + const parentPipelineAggColumn = convertParentPipelineAggToColumn( + pipelineAgg, + series, + subFunctionMetric, + dataView, + meta + ); + + if (!parentPipelineAggColumn) { + return null; + } + + // should build moving_average column + pipelineAgg column + return [ + parentPipelineAggColumn, + createMovingAverageOrDerivativeColumn(aggregation, series, currentMetric, dataView, [ + parentPipelineAggColumn.columnId, + ]), + ]; +}; + +const convertMovingAvgOrDerivativeToColumns = ( + aggregation: typeof METRIC_TYPES.DERIVATIVE | typeof TSVB_METRIC_TYPES.MOVING_AVERAGE, + currentMetric: Metric, + series: Series, + metrics: Metric[], + dataView: DataView +) => { + // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] + const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; + const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); + if (!subFunctionMetric || subFunctionMetric.type === 'static') { + return null; + } + + const pipelineAgg = getPipelineAgg(subFunctionMetric.type); + if (!pipelineAgg) { + return null; + } + const metaValue = Number(meta?.replace(']', '')); + const subMetricField = subFunctionMetric.field; + const [nestedFieldId, _] = subMetricField?.split('[') ?? []; + // support nested aggs with formula + const additionalSubFunction = metrics.find((metric) => metric.id === nestedFieldId); + if (additionalSubFunction) { + const formula = getParentPipelineSeriesFormula( + metrics, + subFunctionMetric, + pipelineAgg.name, + currentMetric.type, + metaValue + ); + if (!formula) { + return null; + } + + return createFormulaColumn(formula, series, currentMetric, dataView); + } else { + const agg = SUPPORTED_METRICS[aggregation]; + if (!agg) { + return null; + } + + return computeParentPipelineColumns( + agg.name, + series, + currentMetric, + dataView, + subFunctionMetric, + pipelineAgg.name, + metaValue + ); + } +}; + +export const convertParentPipelineAggToColumns = ( + series: Series, + metrics: Metric[], + dataView: DataView +) => { + const currentMetric = metrics[metrics.length - 1]; + + if (currentMetric.type === 'moving_average' || currentMetric.type === 'derivative') { + return convertMovingAvgOrDerivativeToColumns( + currentMetric.type, + currentMetric, + series, + metrics, + dataView + ); + } +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 00455682ca3ab..d6fc1bfc80382 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -11,7 +11,7 @@ import { PercentileColumn, PercentileParams } from '@kbn/visualizations-plugin/c import type { Metric, Percentile, Series } from '../../../../common/types'; import { createColumn } from './column'; -const convertToPercentileParams = ({ value }: Percentile): PercentileParams | null => +export const convertToPercentileParams = (value?: string | number): PercentileParams | null => value !== undefined && !isNaN(Number(value)) ? { percentile: Number(value), @@ -24,7 +24,7 @@ const convertToPercentileColumn = ( metric: Metric, dataView: DataView ): PercentileColumn | null => { - const params = convertToPercentileParams(percentile); + const params = convertToPercentileParams(percentile.value); if (!params) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index d8578b396d707..dea5ad58c279a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -11,7 +11,7 @@ import { PercentileRanksColumn, PercentileRanksParams } from '@kbn/visualization import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; -const convertToPercentileRankParams = (value: string): PercentileRanksParams | null => +export const convertToPercentileRankParams = (value: string): PercentileRanksParams | null => value !== undefined && !isNaN(Number(value)) ? { value: Number(value), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index a132b861889fa..bcdecf7d00412 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -7,8 +7,8 @@ */ import type { Query } from '@kbn/es-query'; -import type { Metric } from '../../../../common/types'; -import { SUPPORTED_METRICS } from './supported_metrics'; +import type { Metric, MetricType } from '../../../../common/types'; +import { SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; const escapeQuotes = (str: string) => { return str?.replace(/'/g, "\\'"); @@ -25,9 +25,9 @@ const constructFilterRationFormula = (operation: string, metric?: Query) => { export const getFilterRatioFormula = (currentMetric: Metric) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; - let aggregation = SUPPORTED_METRICS.count; + let aggregation: SupportedMetric | null | undefined = SUPPORTED_METRICS.count; if (metric_agg) { - aggregation = SUPPORTED_METRICS[metric_agg]; + aggregation = SUPPORTED_METRICS[metric_agg as MetricType]; if (!aggregation) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index b7c45721eabf7..f1b7a007dff92 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -7,7 +7,7 @@ */ import { TimeScaleUnit } from '@kbn/visualizations-plugin/common'; -import type { Metric } from '../../../../common/types'; +import type { Metric, MetricType } from '../../../../common/types'; import { SUPPORTED_METRICS } from './supported_metrics'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; @@ -67,12 +67,12 @@ export const getFormulaSeries = (script: string) => { ]; }; -export const getPipelineAgg = (subFunctionMetric: Metric) => { - const pipelineAggMap = SUPPORTED_METRICS[subFunctionMetric.type]; +export const getPipelineAgg = (agg: MetricType) => { + const pipelineAggMap = SUPPORTED_METRICS[agg]; if (!pipelineAggMap) { return null; } - return pipelineAggMap.name; + return pipelineAggMap; }; export const getFormulaEquivalent = ( @@ -108,14 +108,14 @@ export const getFormulaEquivalent = ( if (!subFunctionMetric) { return null; } - const pipelineAgg = getPipelineAgg(subFunctionMetric); + const pipelineAgg = getPipelineAgg(subFunctionMetric.type); if (!pipelineAgg) { return null; } return getParentPipelineSeriesFormula( metrics, subFunctionMetric, - pipelineAgg, + pipelineAgg.name, currentMetric.type, metaValue ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index e00fe505df1fd..45c511494a0f6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -19,6 +19,10 @@ export const getParentPipelineSeriesFormula = ( ) => { let formula = ''; const aggregationMap = SUPPORTED_METRICS[aggregation]; + if (!aggregationMap) { + return null; + } + const subMetricField = subFunctionMetric.field; const [nestedFieldId, nestedMeta] = subMetricField?.split('[') ?? []; // support nested aggs @@ -30,7 +34,6 @@ export const getParentPipelineSeriesFormula = ( return null; } const nestedMetaValue = Number(nestedMeta?.replace(']', '')); - const aggMap = SUPPORTED_METRICS[aggregation]; let additionalFunctionArgs; if (additionalPipelineAggMap.name === 'percentile' && nestedMetaValue) { additionalFunctionArgs = `, percentile=${nestedMetaValue}`; @@ -38,7 +41,7 @@ export const getParentPipelineSeriesFormula = ( if (additionalPipelineAggMap.name === 'percentile_rank' && nestedMetaValue) { additionalFunctionArgs = `, value=${nestedMetaValue}`; } - formula = `${aggMap.name}(${pipelineAgg}(${additionalPipelineAggMap.name}(${ + formula = `${aggregationMap.name}(${pipelineAgg}(${additionalPipelineAggMap.name}(${ additionalSubFunction.field ?? '' }${additionalFunctionArgs ?? ''})))`; } else { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index 6a263ca8bb44d..91aab38198314 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -25,14 +25,14 @@ export const computeParentSeries = ( if (!script) { return null; } - const formula = `${aggregationMap.name}(${script})`; + const formula = `${aggregationMap!.name}(${script})`; return getFormulaSeries(formula); } const timeScale = getTimeScale(currentMetric); return [ { - agg: aggregationMap.name, - isFullReference: aggregationMap.isFullReference, + agg: aggregationMap!.name, + isFullReference: aggregationMap!.isFullReference, pipelineAggType: pipelineAgg, fieldName: subFunctionMetric?.field && pipelineAgg !== 'count' ? subFunctionMetric?.field : 'document', @@ -55,10 +55,11 @@ export const getParentPipelineSeries = ( // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); + if (!subFunctionMetric || subFunctionMetric.type === 'static') { return null; } - const pipelineAgg = getPipelineAgg(subFunctionMetric); + const pipelineAgg = getPipelineAgg(subFunctionMetric.type); if (!pipelineAgg) { return null; } @@ -67,11 +68,12 @@ export const getParentPipelineSeries = ( const [nestedFieldId, _] = subMetricField?.split('[') ?? []; // support nested aggs with formula const additionalSubFunction = metrics.find((metric) => metric.id === nestedFieldId); + if (additionalSubFunction) { const formula = getParentPipelineSeriesFormula( metrics, subFunctionMetric, - pipelineAgg, + pipelineAgg.name, aggregation, metaValue ); @@ -84,7 +86,7 @@ export const getParentPipelineSeries = ( aggregation, currentMetric, subFunctionMetric, - pipelineAgg, + pipelineAgg.name, metaValue ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts index b3e141b11e598..8599539bd4bfe 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts @@ -24,6 +24,9 @@ export const getSiblingPipelineSeriesFormula = ( return null; } const aggregationMap = SUPPORTED_METRICS[aggregation]; + if (!aggregationMap) { + return null; + } const subMetricField = subFunctionMetric.type !== 'count' ? subFunctionMetric.field : ''; // support nested aggs with formula const additionalSubFunction = metrics.find((metric) => metric.id === subMetricField); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts index 29bf2008e208d..3ad3b6d58d313 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts @@ -6,16 +6,59 @@ * Side Public License, v 1. */ -interface AggOptions { - name: string; +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { Operation, Operations } from '@kbn/visualizations-plugin/common'; +import { MetricType } from '../../../../common/types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; + +export type AggOptions = { isFullReference: boolean; -} +} & (T extends Exclude + ? { + isFormula?: false; + } + : { + isFormula: true; + formula: string; + }); // list of supported TSVB aggregation types in Lens // some of them are supported on the quick functions tab and some of them // are supported with formulas -export const SUPPORTED_METRICS: { [key: string]: AggOptions } = { +export type SupportedMetric = { name: T } & AggOptions; +interface LocalSupportedMetrics { + [METRIC_TYPES.AVG]: SupportedMetric; + [METRIC_TYPES.CARDINALITY]: SupportedMetric; + [METRIC_TYPES.COUNT]: SupportedMetric; + [METRIC_TYPES.DERIVATIVE]: SupportedMetric; + [METRIC_TYPES.CUMULATIVE_SUM]: SupportedMetric; + [METRIC_TYPES.AVG_BUCKET]: SupportedMetric; + [METRIC_TYPES.MAX_BUCKET]: SupportedMetric; + [METRIC_TYPES.MIN_BUCKET]: SupportedMetric; + [METRIC_TYPES.SUM_BUCKET]: SupportedMetric; + [METRIC_TYPES.MAX]: SupportedMetric; + [METRIC_TYPES.MIN]: SupportedMetric; + [METRIC_TYPES.SUM]: SupportedMetric; + [TSVB_METRIC_TYPES.PERCENTILE]: SupportedMetric; + [TSVB_METRIC_TYPES.PERCENTILE_RANK]: SupportedMetric; + [TSVB_METRIC_TYPES.PERCENTILE_RANK]: SupportedMetric; + [TSVB_METRIC_TYPES.FILTER_RATIO]: SupportedMetric; + [TSVB_METRIC_TYPES.TOP_HIT]: SupportedMetric; + [TSVB_METRIC_TYPES.MATH]: SupportedMetric; + [TSVB_METRIC_TYPES.POSITIVE_ONLY]: SupportedMetric; + [TSVB_METRIC_TYPES.STATIC]: SupportedMetric; + + [TSVB_METRIC_TYPES.POSITIVE_RATE]: SupportedMetric; + [TSVB_METRIC_TYPES.MOVING_AVERAGE]: SupportedMetric; +} + +type UnsupportedSupportedMetrics = Exclude; +export type SupportedMetrics = LocalSupportedMetrics & { + [Key in UnsupportedSupportedMetrics]?: null; +}; + +export const SUPPORTED_METRICS: SupportedMetrics = { avg: { name: 'average', isFullReference: false, @@ -45,20 +88,28 @@ export const SUPPORTED_METRICS: { [key: string]: AggOptions } = { isFullReference: true, }, avg_bucket: { - name: 'overall_average', + name: 'formula', isFullReference: true, + isFormula: true, + formula: 'overall_average', }, max_bucket: { - name: 'overall_max', + name: 'formula', isFullReference: true, + isFormula: true, + formula: 'overall_max', }, min_bucket: { - name: 'overall_min', + name: 'formula', isFullReference: true, + isFormula: true, + formula: 'overall_min', }, sum_bucket: { - name: 'overall_sum', + name: 'formula', isFullReference: true, + isFormula: true, + formula: 'overall_sum', }, max: { name: 'max', @@ -81,8 +132,10 @@ export const SUPPORTED_METRICS: { [key: string]: AggOptions } = { isFullReference: false, }, filter_ratio: { - name: 'filter_ratio', + name: 'formula', isFullReference: false, + isFormula: true, + formula: 'filter_ratio', }, top_hit: { name: 'last_value', @@ -91,10 +144,14 @@ export const SUPPORTED_METRICS: { [key: string]: AggOptions } = { math: { name: 'formula', isFullReference: true, + isFormula: true, + formula: 'math', }, positive_only: { - name: 'pick_max', + name: 'formula', isFullReference: true, + isFormula: true, + formula: 'pick_max', }, static: { name: 'static_value', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 0db270b465719..60aba951c9c8a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -124,18 +124,18 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis if (!subFunctionMetric || subFunctionMetric.type === 'static') { return null; } - const pipelineAgg = getPipelineAgg(subFunctionMetric); + const pipelineAgg = getPipelineAgg(subFunctionMetric.type); if (!pipelineAgg) { return null; } // lens supports cumulative sum for count and sum as quick function // and everything else as formula - if (pipelineAgg !== 'count' && pipelineAgg !== 'sum') { + if (pipelineAgg.name !== 'count' && pipelineAgg.name !== 'sum') { const metaValue = Number(meta?.replace(']', '')); const formula = getParentPipelineSeriesFormula( metrics, subFunctionMetric, - pipelineAgg, + pipelineAgg.name, aggregation, metaValue ); @@ -146,7 +146,7 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis aggregation, metrics[metricIdx], subFunctionMetric, - pipelineAgg + pipelineAgg.name ); if (!series) return null; metricsArray = series; @@ -235,5 +235,6 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis ]; } } + return { metrics: metricsArray, seriesAgg }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index 0695a2648056c..8e9b6b52d2d34 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -16,8 +16,11 @@ import { convertToPercentileColumns, convertToPercentileRankColumns, convertMathToFormulaColumn, + convertParentPipelineAggToColumns, } from '../convert'; +type UnwrapArray = T extends Array ? P : T; + export const getColumns = (series: Series, dataView: DataView): Column[] | null => { const { metrics } = getSeriesAgg(series.metrics); const metricIdx = metrics.length - 1; @@ -37,6 +40,22 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null case 'math': const formulaColumn = convertMathToFormulaColumn(series, metrics, dataView); return formulaColumn ? [formulaColumn] : null; + + case 'moving_average': + const result = convertParentPipelineAggToColumns(series, metrics, dataView); + if (result && Array.isArray(result)) { + const nonNullColumns = result.filter( + (c): c is Exclude, null> => c !== null + ); + + if (nonNullColumns.length !== result.length) { + return null; + } + + return nonNullColumns; + } + + return result ? [result] : null; } return []; From d0e7722e1c9a95e4f7fface2875d4a1caa3517d2 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Thu, 18 Aug 2022 18:35:21 +0300 Subject: [PATCH 009/129] Updated formula and supported metrics. --- .../lib/convert/moving_average.ts | 5 +- .../lib/convert/parent_pipeline.ts | 35 +++++---- .../lib/metrics/filter_ratio_formula.ts | 13 ++-- .../lib/metrics/metrics_helpers.ts | 24 +++--- .../lib/metrics/parent_pipeline_formula.ts | 24 +++--- .../lib/metrics/parent_pipeline_series.ts | 14 +++- .../lib/metrics/sibling_pipeline_formula.ts | 14 +++- .../lib/metrics/supported_metrics.ts | 75 +++++++++++-------- .../convert_to_lens/lib/series/get_series.ts | 7 +- 9 files changed, 126 insertions(+), 85 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts index bde701ff3b52e..a5bcb39b01487 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts @@ -27,8 +27,9 @@ export const createMovingAverageOrDerivativeColumn = ( dataView: DataView, references: string[] = [] ) => { - const params = convertToMovingAverageParams(metric); - if (!params) { + const params = + aggregation === 'moving_average' ? convertToMovingAverageParams(metric) : undefined; + if (params === null) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 7fa5de91bbe97..9e8f012367f0f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -25,8 +25,10 @@ import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { Metric, Series } from '../../../../common/types'; import { getFilterRatioFormula, + getFormulaFromMetric, getParentPipelineSeriesFormula, getPipelineAgg, + SupportedMetric, SUPPORTED_METRICS, } from '../metrics'; import { createColumn } from './column'; @@ -79,17 +81,17 @@ const SUPPORTED_PARENT_PIPELINE_AGGS: ParentPipelineAggregation[] = [ ]; const isSupportedAggregation = (agg: string): agg is ParentPipelineAggregation => { - return !(SUPPORTED_PARENT_PIPELINE_AGGS as string[]).includes(agg); + return (SUPPORTED_PARENT_PIPELINE_AGGS as string[]).includes(agg); }; export const convertParentPipelineAggToColumn = ( - aggregation: string, + aggregation: SupportedMetric, series: Series, parentPipelineMetric: Metric, dataView: DataView, meta?: number ): ParentPipelineAggregationColumn | null => { - if (!isSupportedAggregation(aggregation)) { + if (!isSupportedAggregation(aggregation.name)) { return null; } @@ -98,11 +100,11 @@ export const convertParentPipelineAggToColumn = ( return null; } - if (aggregation === Operations.PERCENTILE) { + if (aggregation.name === Operations.PERCENTILE) { const params = convertToPercentileParams(meta); return params ? { - operationType: aggregation, + operationType: aggregation.name, sourceField: field.name, ...createColumn(series, parentPipelineMetric, field), params, @@ -110,11 +112,11 @@ export const convertParentPipelineAggToColumn = ( : null; } - if (aggregation === Operations.PERCENTILE_RANK) { + if (aggregation.name === Operations.PERCENTILE_RANK) { const params = convertToPercentileRankParams(meta?.toString() ?? ''); return params ? { - operationType: aggregation, + operationType: aggregation.name, sourceField: field.name, ...createColumn(series, parentPipelineMetric, field), params, @@ -122,12 +124,12 @@ export const convertParentPipelineAggToColumn = ( : null; } - if (aggregation === Operations.LAST_VALUE) { + if (aggregation.name === Operations.LAST_VALUE) { return null; } return { - operationType: aggregation, + operationType: aggregation.name, sourceField: field.name, ...createColumn(series, parentPipelineMetric, field), params: {}, @@ -140,20 +142,22 @@ export const computeParentPipelineColumns = ( currentMetric: Metric, dataView: DataView, subFunctionMetric: Metric, - pipelineAgg: string, + pipelineAgg: SupportedMetric, meta?: number ) => { - const aggregationMap = SUPPORTED_METRICS[currentMetric.type]; - if (!aggregationMap) { + const agg = SUPPORTED_METRICS[currentMetric.type]; + if (!agg) { return null; } + const aggFormula = getFormulaFromMetric(agg); + if (subFunctionMetric.type === 'filter_ratio') { const script = getFilterRatioFormula(subFunctionMetric); if (!script) { return null; } - const formula = `${aggregationMap.name}(${script})`; + const formula = `${aggFormula}(${script})`; return createFormulaColumn(formula, series, currentMetric, dataView); } @@ -169,7 +173,6 @@ export const computeParentPipelineColumns = ( return null; } - // should build moving_average column + pipelineAgg column return [ parentPipelineAggColumn, createMovingAverageOrDerivativeColumn(aggregation, series, currentMetric, dataView, [ @@ -205,7 +208,7 @@ const convertMovingAvgOrDerivativeToColumns = ( const formula = getParentPipelineSeriesFormula( metrics, subFunctionMetric, - pipelineAgg.name, + pipelineAgg, currentMetric.type, metaValue ); @@ -226,7 +229,7 @@ const convertMovingAvgOrDerivativeToColumns = ( currentMetric, dataView, subFunctionMetric, - pipelineAgg.name, + pipelineAgg, metaValue ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index bcdecf7d00412..a90c30eefc6cb 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -8,7 +8,7 @@ import type { Query } from '@kbn/es-query'; import type { Metric, MetricType } from '../../../../common/types'; -import { SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; +import { getFormulaFromMetric, SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; const escapeQuotes = (str: string) => { return str?.replace(/'/g, "\\'"); @@ -25,23 +25,24 @@ const constructFilterRationFormula = (operation: string, metric?: Query) => { export const getFilterRatioFormula = (currentMetric: Metric) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; - let aggregation: SupportedMetric | null | undefined = SUPPORTED_METRICS.count; + let aggregation: SupportedMetric | null | undefined = SUPPORTED_METRICS.count; if (metric_agg) { aggregation = SUPPORTED_METRICS[metric_agg as MetricType]; if (!aggregation) { return null; } } - const operation = - metric_agg && metric_agg !== 'count' ? `${aggregation.name}('${field}',` : 'count('; + const aggFormula = getFormulaFromMetric(aggregation); + + const operation = metric_agg && metric_agg !== 'count' ? `${aggFormula}('${field}',` : 'count('; if (aggregation.name === 'counter_rate') { const numeratorFormula = constructFilterRationFormula( - `${aggregation.name}(max('${field}',`, + `${aggFormula}(max('${field}',`, numerator ); const denominatorFormula = constructFilterRationFormula( - `${aggregation.name}(max('${field}',`, + `${aggFormula}(max('${field}',`, denominator ); return `${numeratorFormula}) / ${denominatorFormula})`; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index f1b7a007dff92..8b661ccb2d34a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -8,7 +8,7 @@ import { TimeScaleUnit } from '@kbn/visualizations-plugin/common'; import type { Metric, MetricType } from '../../../../common/types'; -import { SUPPORTED_METRICS } from './supported_metrics'; +import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; @@ -80,7 +80,13 @@ export const getFormulaEquivalent = ( metrics: Metric[], metaValue?: number ) => { - const aggregation = SUPPORTED_METRICS[currentMetric.type]?.name; + const aggregation = SUPPORTED_METRICS[currentMetric.type]; + if (!aggregation) { + return null; + } + + const aggFormula = getFormulaFromMetric(aggregation); + switch (currentMetric.type) { case 'avg_bucket': case 'max_bucket': @@ -90,15 +96,13 @@ export const getFormulaEquivalent = ( return getSiblingPipelineSeriesFormula(currentMetric.type, currentMetric, metrics); } case 'count': { - return `${aggregation}()`; + return `${aggFormula}()`; } case 'percentile': { - return `${aggregation}(${currentMetric.field}${ - metaValue ? `, percentile=${metaValue}` : '' - })`; + return `${aggFormula}(${currentMetric.field}${metaValue ? `, percentile=${metaValue}` : ''})`; } case 'percentile_rank': { - return `${aggregation}(${currentMetric.field}${metaValue ? `, value=${metaValue}` : ''})`; + return `${aggFormula}(${currentMetric.field}${metaValue ? `, value=${metaValue}` : ''})`; } case 'cumulative_sum': case 'derivative': @@ -115,13 +119,13 @@ export const getFormulaEquivalent = ( return getParentPipelineSeriesFormula( metrics, subFunctionMetric, - pipelineAgg.name, + pipelineAgg, currentMetric.type, metaValue ); } case 'positive_rate': { - return `${aggregation}(max(${currentMetric.field}))`; + return `${aggFormula}(max(${currentMetric.field}))`; } case 'filter_ratio': { return getFilterRatioFormula(currentMetric); @@ -130,7 +134,7 @@ export const getFormulaEquivalent = ( return `${currentMetric.value}`; } default: { - return `${aggregation}(${currentMetric.field})`; + return `${aggFormula}(${currentMetric.field})`; } } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index 45c511494a0f6..b33f49cde65e7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -7,13 +7,13 @@ */ import type { Metric, MetricType } from '../../../../common/types'; -import { SUPPORTED_METRICS } from './supported_metrics'; +import { SUPPORTED_METRICS, getFormulaFromMetric, SupportedMetric } from './supported_metrics'; import { getFilterRatioFormula } from './filter_ratio_formula'; export const getParentPipelineSeriesFormula = ( metrics: Metric[], subFunctionMetric: Metric, - pipelineAgg: string, + pipelineAgg: SupportedMetric, aggregation: MetricType, percentileValue?: number ) => { @@ -22,6 +22,8 @@ export const getParentPipelineSeriesFormula = ( if (!aggregationMap) { return null; } + const aggFormula = getFormulaFromMetric(aggregationMap); + const pipelineFormula = getFormulaFromMetric(pipelineAgg); const subMetricField = subFunctionMetric.field; const [nestedFieldId, nestedMeta] = subMetricField?.split('[') ?? []; @@ -33,6 +35,8 @@ export const getParentPipelineSeriesFormula = ( if (!additionalPipelineAggMap) { return null; } + const additionalPipelineAggFormula = getFormulaFromMetric(additionalPipelineAggMap); + const nestedMetaValue = Number(nestedMeta?.replace(']', '')); let additionalFunctionArgs; if (additionalPipelineAggMap.name === 'percentile' && nestedMetaValue) { @@ -41,29 +45,29 @@ export const getParentPipelineSeriesFormula = ( if (additionalPipelineAggMap.name === 'percentile_rank' && nestedMetaValue) { additionalFunctionArgs = `, value=${nestedMetaValue}`; } - formula = `${aggregationMap.name}(${pipelineAgg}(${additionalPipelineAggMap.name}(${ + formula = `${aggFormula}(${pipelineFormula}(${additionalPipelineAggFormula}(${ additionalSubFunction.field ?? '' }${additionalFunctionArgs ?? ''})))`; } else { let additionalFunctionArgs; - if (pipelineAgg === 'percentile' && percentileValue) { + if (pipelineAgg.name === 'percentile' && percentileValue) { additionalFunctionArgs = `, percentile=${percentileValue}`; } - if (pipelineAgg === 'percentile_rank' && percentileValue) { + if (pipelineAgg.name === 'percentile_rank' && percentileValue) { additionalFunctionArgs = `, value=${percentileValue}`; } - if (pipelineAgg === 'filter_ratio') { + if (pipelineAgg.isFormula && pipelineAgg.formula === 'filter_ratio') { const script = getFilterRatioFormula(subFunctionMetric); if (!script) { return null; } - formula = `${aggregationMap.name}(${script}${additionalFunctionArgs ?? ''})`; - } else if (pipelineAgg === 'counter_rate') { - formula = `${aggregationMap.name}(${pipelineAgg}(max(${subFunctionMetric.field}${ + formula = `${aggFormula}(${script}${additionalFunctionArgs ?? ''})`; + } else if (pipelineAgg.name === 'counter_rate') { + formula = `${aggFormula}(${pipelineFormula}(max(${subFunctionMetric.field}${ additionalFunctionArgs ? `${additionalFunctionArgs}` : '' })))`; } else { - formula = `${aggregationMap.name}(${pipelineAgg}(${subFunctionMetric.field}${ + formula = `${aggFormula}(${pipelineFormula}(${subFunctionMetric.field}${ additionalFunctionArgs ? `${additionalFunctionArgs}` : '' }))`; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index 91aab38198314..d25b827559a39 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -7,7 +7,7 @@ */ import type { Metric, MetricType } from '../../../../common/types'; -import { SUPPORTED_METRICS } from './supported_metrics'; +import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getFormulaSeries, getTimeScale, getPipelineAgg } from './metrics_helpers'; @@ -20,18 +20,24 @@ export const computeParentSeries = ( meta?: number ) => { const aggregationMap = SUPPORTED_METRICS[aggregation]; + if (!aggregationMap) { + return null; + } + if (subFunctionMetric.type === 'filter_ratio') { const script = getFilterRatioFormula(subFunctionMetric); if (!script) { return null; } - const formula = `${aggregationMap!.name}(${script})`; + + const aggFormula = getFormulaFromMetric(aggregationMap); + const formula = `${aggFormula}(${script})`; return getFormulaSeries(formula); } const timeScale = getTimeScale(currentMetric); return [ { - agg: aggregationMap!.name, + agg: aggregationMap.name, isFullReference: aggregationMap!.isFullReference, pipelineAggType: pipelineAgg, fieldName: @@ -73,7 +79,7 @@ export const getParentPipelineSeries = ( const formula = getParentPipelineSeriesFormula( metrics, subFunctionMetric, - pipelineAgg.name, + pipelineAgg, aggregation, metaValue ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts index 8599539bd4bfe..708daabc7f501 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts @@ -7,7 +7,7 @@ */ import type { Metric, MetricType } from '../../../../common/types'; -import { SUPPORTED_METRICS } from './supported_metrics'; +import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; export const getSiblingPipelineSeriesFormula = ( aggregation: MetricType, @@ -23,14 +23,18 @@ export const getSiblingPipelineSeriesFormula = ( if (!pipelineAggMap) { return null; } + const pipelineAggFormula = getFormulaFromMetric(pipelineAggMap); + const aggregationMap = SUPPORTED_METRICS[aggregation]; if (!aggregationMap) { return null; } + const aggFormula = getFormulaFromMetric(aggregationMap); + const subMetricField = subFunctionMetric.type !== 'count' ? subFunctionMetric.field : ''; // support nested aggs with formula const additionalSubFunction = metrics.find((metric) => metric.id === subMetricField); - let formula = `${aggregationMap.name}(`; + let formula = `${aggFormula}(`; let minimumValue = ''; if (currentMetric.type === 'positive_only') { minimumValue = `, 0`; @@ -40,9 +44,11 @@ export const getSiblingPipelineSeriesFormula = ( if (!additionalPipelineAggMap) { return null; } + const additionalPipelineAggFormula = getFormulaFromMetric(additionalPipelineAggMap); + const additionalSubFunctionField = additionalSubFunction.type !== 'count' ? additionalSubFunction.field : ''; - formula += `${pipelineAggMap.name}(${additionalPipelineAggMap.name}(${ + formula += `${pipelineAggFormula}(${additionalPipelineAggFormula}(${ additionalSubFunctionField ?? '' }))${minimumValue})`; } else { @@ -55,7 +61,7 @@ export const getSiblingPipelineSeriesFormula = ( if (pipelineAggMap.name === 'percentile_rank' && nestedMetaValue) { additionalFunctionArgs = `, value=${nestedMetaValue}`; } - formula += `${pipelineAggMap.name}(${subMetricField ?? ''}${ + formula += `${pipelineAggFormula}(${subMetricField ?? ''}${ additionalFunctionArgs ? `${additionalFunctionArgs}` : '' })${minimumValue})`; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts index 3ad3b6d58d313..65e59feb1a25c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts @@ -11,46 +11,48 @@ import { Operation, Operations } from '@kbn/visualizations-plugin/common'; import { MetricType } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +interface Agg { + isFormula?: false; +}; + +interface AggWithFormula { + isFormula: true; + formula: string; +} + export type AggOptions = { isFullReference: boolean; -} & (T extends Exclude - ? { - isFormula?: false; - } - : { - isFormula: true; - formula: string; - }); +} & (T extends Exclude ? Agg : AggWithFormula); // list of supported TSVB aggregation types in Lens // some of them are supported on the quick functions tab and some of them // are supported with formulas -export type SupportedMetric = { name: T } & AggOptions; +export type Metric = { name: T } & AggOptions; interface LocalSupportedMetrics { - [METRIC_TYPES.AVG]: SupportedMetric; - [METRIC_TYPES.CARDINALITY]: SupportedMetric; - [METRIC_TYPES.COUNT]: SupportedMetric; - [METRIC_TYPES.DERIVATIVE]: SupportedMetric; - [METRIC_TYPES.CUMULATIVE_SUM]: SupportedMetric; - [METRIC_TYPES.AVG_BUCKET]: SupportedMetric; - [METRIC_TYPES.MAX_BUCKET]: SupportedMetric; - [METRIC_TYPES.MIN_BUCKET]: SupportedMetric; - [METRIC_TYPES.SUM_BUCKET]: SupportedMetric; - [METRIC_TYPES.MAX]: SupportedMetric; - [METRIC_TYPES.MIN]: SupportedMetric; - [METRIC_TYPES.SUM]: SupportedMetric; - [TSVB_METRIC_TYPES.PERCENTILE]: SupportedMetric; - [TSVB_METRIC_TYPES.PERCENTILE_RANK]: SupportedMetric; - [TSVB_METRIC_TYPES.PERCENTILE_RANK]: SupportedMetric; - [TSVB_METRIC_TYPES.FILTER_RATIO]: SupportedMetric; - [TSVB_METRIC_TYPES.TOP_HIT]: SupportedMetric; - [TSVB_METRIC_TYPES.MATH]: SupportedMetric; - [TSVB_METRIC_TYPES.POSITIVE_ONLY]: SupportedMetric; - [TSVB_METRIC_TYPES.STATIC]: SupportedMetric; + [METRIC_TYPES.AVG]: Metric; + [METRIC_TYPES.CARDINALITY]: Metric; + [METRIC_TYPES.COUNT]: Metric; + [METRIC_TYPES.DERIVATIVE]: Metric; + [METRIC_TYPES.CUMULATIVE_SUM]: Metric; + [METRIC_TYPES.AVG_BUCKET]: Metric; + [METRIC_TYPES.MAX_BUCKET]: Metric; + [METRIC_TYPES.MIN_BUCKET]: Metric; + [METRIC_TYPES.SUM_BUCKET]: Metric; + [METRIC_TYPES.MAX]: Metric; + [METRIC_TYPES.MIN]: Metric; + [METRIC_TYPES.SUM]: Metric; + [TSVB_METRIC_TYPES.PERCENTILE]: Metric; + [TSVB_METRIC_TYPES.PERCENTILE_RANK]: Metric; + [TSVB_METRIC_TYPES.PERCENTILE_RANK]: Metric; + [TSVB_METRIC_TYPES.FILTER_RATIO]: Metric; + [TSVB_METRIC_TYPES.TOP_HIT]: Metric; + [TSVB_METRIC_TYPES.MATH]: Metric; + [TSVB_METRIC_TYPES.POSITIVE_ONLY]: Metric; + [TSVB_METRIC_TYPES.STATIC]: Metric; - [TSVB_METRIC_TYPES.POSITIVE_RATE]: SupportedMetric; - [TSVB_METRIC_TYPES.MOVING_AVERAGE]: SupportedMetric; + [TSVB_METRIC_TYPES.POSITIVE_RATE]: Metric; + [TSVB_METRIC_TYPES.MOVING_AVERAGE]: Metric; } type UnsupportedSupportedMetrics = Exclude; @@ -157,4 +159,15 @@ export const SUPPORTED_METRICS: SupportedMetrics = { name: 'static_value', isFullReference: true, }, +} as const; + +type SupportedMetricsKeys = keyof LocalSupportedMetrics; + +export type SupportedMetric = typeof SUPPORTED_METRICS[SupportedMetricsKeys]; + +export const getFormulaFromMetric = (metric: SupportedMetric) => { + if (metric.isFormula) { + return metric.formula; + } + return metric.name; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 60aba951c9c8a..551410a223b26 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -135,7 +135,7 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis const formula = getParentPipelineSeriesFormula( metrics, subFunctionMetric, - pipelineAgg.name, + pipelineAgg, aggregation, metaValue ); @@ -223,13 +223,16 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis } default: { const timeScale = getTimeScale(metrics[metricIdx]); + + const field = aggregation !== 'count' && fieldName ? fieldName : 'document'; metricsArray = [ { agg: aggregationMap.name, isFullReference: aggregationMap.isFullReference, - fieldName: aggregation !== 'count' && fieldName ? fieldName : 'document', + fieldName: field, params: { ...(timeScale && { timeScale }), + ...(aggregationMap.isFormula ? { formula: `${aggregationMap.formula}(${field})` } : {}), }, }, ]; From e982ac74f7ef3e4f3e7ef85341fa1406f76a77c4 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Thu, 18 Aug 2022 18:41:37 +0300 Subject: [PATCH 010/129] Fixed pipeline aggs. --- .../timeseries/public/convert_to_lens/lib/series/get_series.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 551410a223b26..6b0bc5be8c4c5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -21,6 +21,7 @@ import { getParentPipelineSeriesFormula, getFilterRatioFormula, getTimeScale, + getFormulaFromMetric, } from '../metrics'; export interface VisSeries { @@ -146,7 +147,7 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis aggregation, metrics[metricIdx], subFunctionMetric, - pipelineAgg.name + getFormulaFromMetric(pipelineAgg) ); if (!series) return null; metricsArray = series; From 471f91ae25830020a9bd49b332b2e999183cfa8c Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Thu, 18 Aug 2022 18:44:22 +0300 Subject: [PATCH 011/129] Another fix. --- .../lib/metrics/parent_pipeline_series.ts | 17 ++++++++++------- .../convert_to_lens/lib/series/get_series.ts | 3 +-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index d25b827559a39..e12bf2e31d9e7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -7,7 +7,7 @@ */ import type { Metric, MetricType } from '../../../../common/types'; -import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; +import { getFormulaFromMetric, SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getFormulaSeries, getTimeScale, getPipelineAgg } from './metrics_helpers'; @@ -16,7 +16,7 @@ export const computeParentSeries = ( aggregation: MetricType, currentMetric: Metric, subFunctionMetric: Metric, - pipelineAgg: string, + pipelineAgg: SupportedMetric, meta?: number ) => { const aggregationMap = SUPPORTED_METRICS[aggregation]; @@ -39,14 +39,17 @@ export const computeParentSeries = ( { agg: aggregationMap.name, isFullReference: aggregationMap!.isFullReference, - pipelineAggType: pipelineAgg, + pipelineAggType: pipelineAgg.name, fieldName: - subFunctionMetric?.field && pipelineAgg !== 'count' ? subFunctionMetric?.field : 'document', + subFunctionMetric?.field && pipelineAgg.name !== 'count' + ? subFunctionMetric?.field + : 'document', params: { ...(currentMetric.window && { window: currentMetric.window }), ...(timeScale && { timeScale }), - ...(pipelineAgg === 'percentile' && meta && { percentile: meta }), - ...(pipelineAgg === 'percentile_rank' && meta && { value: meta }), + ...(pipelineAgg.name === 'percentile' && meta && { percentile: meta }), + ...(pipelineAgg.name === 'percentile_rank' && meta && { value: meta }), + ...(pipelineAgg.name === 'formula' ? { formula: pipelineAgg.formula } : {}), }, }, ]; @@ -92,7 +95,7 @@ export const getParentPipelineSeries = ( aggregation, currentMetric, subFunctionMetric, - pipelineAgg.name, + pipelineAgg, metaValue ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 6b0bc5be8c4c5..7b650a04f40c3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -21,7 +21,6 @@ import { getParentPipelineSeriesFormula, getFilterRatioFormula, getTimeScale, - getFormulaFromMetric, } from '../metrics'; export interface VisSeries { @@ -147,7 +146,7 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis aggregation, metrics[metricIdx], subFunctionMetric, - getFormulaFromMetric(pipelineAgg) + pipelineAgg ); if (!series) return null; metricsArray = series; From 537d33ace54e3f5b1d94b177e59b396690ff7b24 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Thu, 18 Aug 2022 18:49:36 +0300 Subject: [PATCH 012/129] One more fix. --- .../lib/metrics/parent_pipeline_series.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index e12bf2e31d9e7..c7f5156d54006 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -35,21 +35,25 @@ export const computeParentSeries = ( return getFormulaSeries(formula); } const timeScale = getTimeScale(currentMetric); + const fieldName = + subFunctionMetric?.field && pipelineAgg.name !== 'count' + ? subFunctionMetric?.field + : 'document'; + return [ { agg: aggregationMap.name, isFullReference: aggregationMap!.isFullReference, pipelineAggType: pipelineAgg.name, - fieldName: - subFunctionMetric?.field && pipelineAgg.name !== 'count' - ? subFunctionMetric?.field - : 'document', + fieldName, params: { ...(currentMetric.window && { window: currentMetric.window }), ...(timeScale && { timeScale }), ...(pipelineAgg.name === 'percentile' && meta && { percentile: meta }), ...(pipelineAgg.name === 'percentile_rank' && meta && { value: meta }), - ...(pipelineAgg.name === 'formula' ? { formula: pipelineAgg.formula } : {}), + ...(pipelineAgg.name === 'formula' + ? { formula: `${pipelineAgg.formula}(${fieldName})` } + : {}), }, }, ]; From 59db5532faf116de365db13dd603336cec69fdc4 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Thu, 18 Aug 2022 19:39:27 +0300 Subject: [PATCH 013/129] CumulativeSum added. --- .../lib/convert/cumulative_sum.ts | 68 ++++++++++++++++++ .../convert_to_lens/lib/convert/index.ts | 1 + .../lib/convert/moving_average.ts | 39 +--------- .../lib/convert/parent_pipeline.ts | 72 ++++++++++++++----- .../convert_to_lens/lib/series/get_series.ts | 9 +-- .../convert_to_lens/lib/series/new.columns.ts | 35 +++++---- 6 files changed, 149 insertions(+), 75 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts new file mode 100644 index 0000000000000..083e241a0e712 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -0,0 +1,68 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { Metric, Series } from '../../../../common/types'; +import { SUPPORTED_METRICS, getParentPipelineSeriesFormula } from '../metrics'; +import { createFormulaColumn } from './formula'; +import { computeParentPipelineColumns } from './parent_pipeline'; + +export const convertToCumulativeSumColumns = ( + series: Series, + metrics: Metric[], + dataView: DataView +) => { + const currentMetric = metrics[metrics.length - 1]; + if (!currentMetric) { + return null; + } + + // percentile and percentile_rank value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] + const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; + const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); + if (!subFunctionMetric || subFunctionMetric.type === 'static') { + return null; + } + const pipelineAgg = SUPPORTED_METRICS[subFunctionMetric.type]; + if (!pipelineAgg) { + return null; + } + let formula; + // lens supports cumulative sum for count and sum as quick function + // and everything else as formula + if (pipelineAgg.name !== 'count' && pipelineAgg.name !== 'sum') { + const metaValue = Number(meta?.replace(']', '')); + formula = getParentPipelineSeriesFormula( + metrics, + subFunctionMetric, + pipelineAgg, + currentMetric.type, + metaValue + ); + if (!formula) { + return null; + } + + return createFormulaColumn(formula, series, currentMetric, dataView); + } else { + const agg = SUPPORTED_METRICS[METRIC_TYPES.CUMULATIVE_SUM]; + if (!agg) { + return null; + } + + return computeParentPipelineColumns( + agg.name, + series, + currentMetric, + dataView, + subFunctionMetric, + pipelineAgg + ); + } +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index e74908360aebd..7bc2b4ea476a6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -11,3 +11,4 @@ export { convertToPercentileColumns } from './percentile'; export { convertToPercentileRankColumns } from './percentile_rank'; export { convertMathToFormulaColumn } from './formula'; export { convertParentPipelineAggToColumns } from './parent_pipeline'; +export { convertToCumulativeSumColumns } from './cumulative_sum'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts index a5bcb39b01487..5359f67d4e1c6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts @@ -6,42 +6,9 @@ * Side Public License, v 1. */ -import { - DerivativeColumn, - MovingAverageColumn, - MovingAverageParams, - Operations, -} from '@kbn/visualizations-plugin/common'; -import type { DataView } from '@kbn/data-views-plugin/common'; -import { Metric, Series } from '../../../../common/types'; -import { createColumn } from './column'; +import { MovingAverageParams } from '@kbn/visualizations-plugin/common'; +import { Metric } from '../../../../common/types'; -const convertToMovingAverageParams = ({ window }: Metric): MovingAverageParams => ({ +export const convertToMovingAverageParams = ({ window }: Metric): MovingAverageParams => ({ window: window ?? 0, }); - -export const createMovingAverageOrDerivativeColumn = ( - aggregation: typeof Operations.DIFFERENCES | typeof Operations.MOVING_AVERAGE, - series: Series, - metric: Metric, - dataView: DataView, - references: string[] = [] -) => { - const params = - aggregation === 'moving_average' ? convertToMovingAverageParams(metric) : undefined; - if (params === null) { - return null; - } - - const field = dataView.getFieldByName(metric.field ?? 'document'); - if (!field) { - return null; - } - - return { - operationType: aggregation, - references, - ...createColumn(series, metric, field), - params, - } as MovingAverageColumn | DerivativeColumn; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 9e8f012367f0f..3b4a40afa925e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -13,9 +13,12 @@ import { CardinalityColumn, CountColumn, CounterRateColumn, + CumulativeSumColumn, + DerivativeColumn, LastValueColumn, MaxColumn, MinColumn, + MovingAverageColumn, Operations, PercentileColumn, PercentileRanksColumn, @@ -33,11 +36,11 @@ import { } from '../metrics'; import { createColumn } from './column'; import { createFormulaColumn } from './formula'; -import { createMovingAverageOrDerivativeColumn } from './moving_average'; +import { convertToMovingAverageParams } from './moving_average'; import { convertToPercentileParams } from './percentile'; import { convertToPercentileRankParams } from './percentile_rank'; -type ParentPipelineAggregation = +type PipelineAggregation = | typeof Operations.AVERAGE | typeof Operations.COUNT | typeof Operations.UNIQUE_COUNT @@ -49,12 +52,12 @@ type ParentPipelineAggregation = | typeof Operations.PERCENTILE | typeof Operations.PERCENTILE_RANK; -type ParentPipelineAggregationColumnWithParams = +type PipelineAggregationColumnWithParams = | PercentileColumn | PercentileRanksColumn | LastValueColumn; -type ParentPipelineAggregationColumnWithoutParams = +type PipelineAggregationColumnWithoutParams = | AvgColumn | CountColumn | CardinalityColumn @@ -63,11 +66,18 @@ type ParentPipelineAggregationColumnWithoutParams = | MinColumn | SumColumn; -type ParentPipelineAggregationColumn = - | ParentPipelineAggregationColumnWithoutParams - | ParentPipelineAggregationColumnWithParams; +type PipelineAggregationColumn = + | PipelineAggregationColumnWithoutParams + | PipelineAggregationColumnWithParams; + +type ParentPipelineAggregation = + | typeof Operations.MOVING_AVERAGE + | typeof Operations.DIFFERENCES + | typeof Operations.CUMULATIVE_SUM; -const SUPPORTED_PARENT_PIPELINE_AGGS: ParentPipelineAggregation[] = [ +type ParentPipelineAggColumn = MovingAverageColumn | DerivativeColumn | CumulativeSumColumn; + +const SUPPORTED_PARENT_PIPELINE_AGGS: PipelineAggregation[] = [ Operations.AVERAGE, Operations.COUNT, Operations.UNIQUE_COUNT, @@ -80,17 +90,17 @@ const SUPPORTED_PARENT_PIPELINE_AGGS: ParentPipelineAggregation[] = [ Operations.PERCENTILE_RANK, ]; -const isSupportedAggregation = (agg: string): agg is ParentPipelineAggregation => { +const isSupportedAggregation = (agg: string): agg is PipelineAggregation => { return (SUPPORTED_PARENT_PIPELINE_AGGS as string[]).includes(agg); }; -export const convertParentPipelineAggToColumn = ( +export const convertPipelineAggToColumn = ( aggregation: SupportedMetric, series: Series, parentPipelineMetric: Metric, dataView: DataView, meta?: number -): ParentPipelineAggregationColumn | null => { +): PipelineAggregationColumn | null => { if (!isSupportedAggregation(aggregation.name)) { return null; } @@ -133,11 +143,11 @@ export const convertParentPipelineAggToColumn = ( sourceField: field.name, ...createColumn(series, parentPipelineMetric, field), params: {}, - } as ParentPipelineAggregationColumnWithoutParams; + } as PipelineAggregationColumnWithoutParams; }; export const computeParentPipelineColumns = ( - aggregation: typeof Operations.MOVING_AVERAGE | typeof Operations.DIFFERENCES, + aggregation: ParentPipelineAggregation, series: Series, currentMetric: Metric, dataView: DataView, @@ -161,7 +171,7 @@ export const computeParentPipelineColumns = ( return createFormulaColumn(formula, series, currentMetric, dataView); } - const parentPipelineAggColumn = convertParentPipelineAggToColumn( + const pipelineAggColumn = convertPipelineAggToColumn( pipelineAgg, series, subFunctionMetric, @@ -169,14 +179,14 @@ export const computeParentPipelineColumns = ( meta ); - if (!parentPipelineAggColumn) { + if (!pipelineAggColumn) { return null; } return [ - parentPipelineAggColumn, - createMovingAverageOrDerivativeColumn(aggregation, series, currentMetric, dataView, [ - parentPipelineAggColumn.columnId, + pipelineAggColumn, + createPipelineAggregationColumn(aggregation, series, currentMetric, dataView, [ + pipelineAggColumn.columnId, ]), ]; }; @@ -252,3 +262,29 @@ export const convertParentPipelineAggToColumns = ( ); } }; + +export const createPipelineAggregationColumn = ( + aggregation: ParentPipelineAggregation, + series: Series, + metric: Metric, + dataView: DataView, + references: string[] = [] +) => { + const params = + aggregation === 'moving_average' ? convertToMovingAverageParams(metric) : undefined; + if (params === null) { + return null; + } + + const field = dataView.getFieldByName(metric.field ?? 'document'); + if (!field) { + return null; + } + + return { + operationType: aggregation, + references, + ...createColumn(series, metric, field), + params, + } as ParentPipelineAggColumn; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 7b650a04f40c3..e2b149c53bb00 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -153,14 +153,7 @@ export const getSeries = (initialMetrics: Metric[], totalSeriesNum: number): Vis } break; } - case 'positive_only': { - const formula = getSiblingPipelineSeriesFormula(aggregation, metrics[metricIdx], metrics); - if (!formula) { - return null; - } - metricsArray = getFormulaSeries(formula) as VisualizeEditorLayersContext['metrics']; - break; - } + case 'positive_only': case 'avg_bucket': case 'max_bucket': case 'min_bucket': diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index 8e9b6b52d2d34..92e0b33fab951 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -17,10 +17,27 @@ import { convertToPercentileRankColumns, convertMathToFormulaColumn, convertParentPipelineAggToColumns, + convertToCumulativeSumColumns, } from '../convert'; type UnwrapArray = T extends Array ? P : T; +const getValidColumns = (columns: Array | Column | null | undefined) => { + if (columns && Array.isArray(columns)) { + const nonNullColumns = columns.filter( + (c): c is Exclude, null> => c !== null + ); + + if (nonNullColumns.length !== columns.length) { + return null; + } + + return nonNullColumns; + } + + return columns ? [columns] : null; +}; + export const getColumns = (series: Series, dataView: DataView): Column[] | null => { const { metrics } = getSeriesAgg(series.metrics); const metricIdx = metrics.length - 1; @@ -42,20 +59,12 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null return formulaColumn ? [formulaColumn] : null; case 'moving_average': - const result = convertParentPipelineAggToColumns(series, metrics, dataView); - if (result && Array.isArray(result)) { - const nonNullColumns = result.filter( - (c): c is Exclude, null> => c !== null - ); - - if (nonNullColumns.length !== result.length) { - return null; - } - - return nonNullColumns; - } + const movingAverageColumns = convertParentPipelineAggToColumns(series, metrics, dataView); + return getValidColumns(movingAverageColumns); - return result ? [result] : null; + case 'cumulative_sum': + const cumulativeSumColumns = convertToCumulativeSumColumns(series, metrics, dataView); + return getValidColumns(cumulativeSumColumns); } return []; From c19acc701385baa47fec44e8c77b68c4e0275bfb Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 11:55:04 +0300 Subject: [PATCH 014/129] Fixed formula, timeScale and etc. --- .../convert_to_lens/lib/convert/column.ts | 11 +++++++--- .../lib/convert/cumulative_sum.ts | 2 +- .../convert_to_lens/lib/convert/formula.ts | 14 ++++--------- .../lib/convert/moving_average.ts | 2 +- .../lib/convert/parent_pipeline.ts | 20 ++++++++----------- .../convert_to_lens/lib/convert/percentile.ts | 5 ++++- .../lib/convert/percentile_rank.ts | 5 ++++- .../lib/metrics/metrics_helpers.ts | 2 +- .../common/convert_to_lens/types/columns.ts | 2 +- .../common/convert_to_lens/types/common.ts | 2 +- src/plugins/visualizations/kibana.json | 2 +- 11 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 56054061c0016..b5fa86a22e8a8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -6,7 +6,12 @@ * Side Public License, v 1. */ import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; -import { BaseColumn, Operation, DataType, Column } from '@kbn/visualizations-plugin/common'; +import { + BaseColumn, + Operation, + DataType, + Column, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; import { ConvertToColumnsFn } from '../../types'; @@ -15,11 +20,11 @@ import { getTimeScale } from '../metrics'; export const createColumn = ( series: Series, metric: Metric, - field: DataViewField, + field?: DataViewField, isBucketed: boolean = false ): Omit, 'operationType' | 'params'> => ({ columnId: uuid(), - dataType: field.type as DataType, + dataType: (field?.type as DataType) ?? undefined, label: series.label, isBucketed, window: metric.window?.toString(), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index 083e241a0e712..59b6d5b291979 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -49,7 +49,7 @@ export const convertToCumulativeSumColumns = ( return null; } - return createFormulaColumn(formula, series, currentMetric, dataView); + return createFormulaColumn(formula, series, currentMetric); } else { const agg = SUPPORTED_METRICS[METRIC_TYPES.CUMULATIVE_SUM]; if (!agg) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 61349faef76c7..1764e3539871e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -7,7 +7,7 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; -import { FormulaColumn, FormulaParams } from '@kbn/visualizations-plugin/common'; +import { FormulaColumn, FormulaParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Series } from '../../../../common/types'; import { getFormulaEquivalent } from '../metrics'; import { createColumn } from './column'; @@ -19,23 +19,17 @@ const convertToFormulaParams = (formula: string): FormulaParams | null => ({ export const createFormulaColumn = ( mathScript: string, series: Series, - metric: Metric, - dataView: DataView + metric: Metric ): FormulaColumn | null => { const params = convertToFormulaParams(mathScript); if (!params) { return null; } - const field = dataView.getFieldByName(metric.field ?? 'document'); - if (!field) { - return null; - } - return { operationType: 'formula', references: [], - ...createColumn(series, metric, field), + ...createColumn(series, metric), params, }; }; @@ -125,5 +119,5 @@ export const convertMathToFormulaColumn = ( return null; } - return createFormulaColumn(script, series, mathMetric, dataView); + return createFormulaColumn(script, series, mathMetric); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts index 5359f67d4e1c6..3b6491ac475ca 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { MovingAverageParams } from '@kbn/visualizations-plugin/common'; +import { MovingAverageParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { Metric } from '../../../../common/types'; export const convertToMovingAverageParams = ({ window }: Metric): MovingAverageParams => ({ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 3b4a40afa925e..0ab003fdf0420 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -23,7 +23,7 @@ import { PercentileColumn, PercentileRanksColumn, SumColumn, -} from '@kbn/visualizations-plugin/common'; +} from '@kbn/visualizations-plugin/common/convert_to_lens'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { Metric, Series } from '../../../../common/types'; import { @@ -168,7 +168,7 @@ export const computeParentPipelineColumns = ( return null; } const formula = `${aggFormula}(${script})`; - return createFormulaColumn(formula, series, currentMetric, dataView); + return createFormulaColumn(formula, series, currentMetric); } const pipelineAggColumn = convertPipelineAggToColumn( @@ -185,7 +185,7 @@ export const computeParentPipelineColumns = ( return [ pipelineAggColumn, - createPipelineAggregationColumn(aggregation, series, currentMetric, dataView, [ + createParentPipelineAggregationColumn(aggregation, series, currentMetric, [ pipelineAggColumn.columnId, ]), ]; @@ -198,6 +198,7 @@ const convertMovingAvgOrDerivativeToColumns = ( metrics: Metric[], dataView: DataView ) => { + console.log('here'); // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); @@ -226,7 +227,7 @@ const convertMovingAvgOrDerivativeToColumns = ( return null; } - return createFormulaColumn(formula, series, currentMetric, dataView); + return createFormulaColumn(formula, series, currentMetric); } else { const agg = SUPPORTED_METRICS[aggregation]; if (!agg) { @@ -261,13 +262,13 @@ export const convertParentPipelineAggToColumns = ( dataView ); } + return null; }; -export const createPipelineAggregationColumn = ( +export const createParentPipelineAggregationColumn = ( aggregation: ParentPipelineAggregation, series: Series, metric: Metric, - dataView: DataView, references: string[] = [] ) => { const params = @@ -276,15 +277,10 @@ export const createPipelineAggregationColumn = ( return null; } - const field = dataView.getFieldByName(metric.field ?? 'document'); - if (!field) { - return null; - } - return { operationType: aggregation, references, - ...createColumn(series, metric, field), + ...createColumn(series, metric), params, } as ParentPipelineAggColumn; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index d6fc1bfc80382..45c21532d2b9e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -7,7 +7,10 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; -import { PercentileColumn, PercentileParams } from '@kbn/visualizations-plugin/common'; +import { + PercentileColumn, + PercentileParams, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Percentile, Series } from '../../../../common/types'; import { createColumn } from './column'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index dea5ad58c279a..ff6da02e49d5a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -7,7 +7,10 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; -import { PercentileRanksColumn, PercentileRanksParams } from '@kbn/visualizations-plugin/common'; +import { + PercentileRanksColumn, + PercentileRanksParams, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 8b661ccb2d34a..60a8202fcffe8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -44,7 +44,7 @@ export const getPercentileRankSeries = ( type TimeScaleValue = `1${TimeScaleUnit}`; const isTimeScaleValue = (unit: string): unit is TimeScaleValue => { - const supportedTimeScales: TimeScaleValue[] = ['1s', '1m', '1h', '1d']; + const supportedTimeScales: TimeScaleValue[] = ['1ms', '1s', '1m', '1h', '1d']; return supportedTimeScales.includes(unit as TimeScaleValue); }; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index f9fc2afcbd3db..3e7abc1e04276 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -37,7 +37,7 @@ export interface BaseColumn operationType: OperationType; label?: string; isBucketed: boolean; - dataType: DataType; + dataType?: DataType; timeScale?: TimeScaleUnit; // ? timeShift?: string; window?: string; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/common.ts b/src/plugins/visualizations/common/convert_to_lens/types/common.ts index 974326834ce2a..7cf68761751f7 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/common.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/common.ts @@ -18,7 +18,7 @@ export type DataType = | 'geo_shape' | 'murmur3'; -export type TimeScaleUnit = 's' | 'm' | 'h' | 'd'; +export type TimeScaleUnit = 'ms' | 's' | 'm' | 'h' | 'd'; export type SortingHint = 'version'; diff --git a/src/plugins/visualizations/kibana.json b/src/plugins/visualizations/kibana.json index 69b9eb6c2b090..bdabcba097422 100644 --- a/src/plugins/visualizations/kibana.json +++ b/src/plugins/visualizations/kibana.json @@ -20,7 +20,7 @@ ], "optionalPlugins": ["home", "share", "spaces", "savedObjectsTaggingOss"], "requiredBundles": ["kibanaUtils", "savedSearch", "kibanaReact"], - "extraPublicDirs": ["common/constants", "common/utils", "common/expression_functions"], + "extraPublicDirs": ["common/constants", "common/utils", "common/expression_functions", "common/convert_to_lens"], "owner": { "name": "Vis Editors", "githubTeam": "kibana-vis-editors" From a2d51eb7be566959328fbfb517a72ade32bef927 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 12:26:33 +0300 Subject: [PATCH 015/129] Removed console.log. --- .../public/convert_to_lens/lib/convert/parent_pipeline.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 0ab003fdf0420..980cda8038581 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -198,7 +198,6 @@ const convertMovingAvgOrDerivativeToColumns = ( metrics: Metric[], dataView: DataView ) => { - console.log('here'); // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); From 78b715db45259bb00652e206e24e9108559c2d32 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 13:53:09 +0300 Subject: [PATCH 016/129] Other aggs to formula convertion added. --- .../convert_to_lens/lib/convert/formula.ts | 29 ++++++++++++++++--- .../convert_to_lens/lib/convert/index.ts | 2 +- .../convert_to_lens/lib/series/new.columns.ts | 11 ++++++- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 1764e3539871e..c1f9bec6ed949 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -6,12 +6,20 @@ * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-views-plugin/common'; +import { METRIC_TYPES } from '@kbn/data-plugin/public'; import { FormulaColumn, FormulaParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric, Series } from '../../../../common/types'; -import { getFormulaEquivalent } from '../metrics'; +import { getFormulaEquivalent, getSiblingPipelineSeriesFormula } from '../metrics'; import { createColumn } from './column'; +type OtherFormulaAggregations = + | typeof TSVB_METRIC_TYPES.POSITIVE_ONLY + | typeof METRIC_TYPES.AVG_BUCKET + | typeof METRIC_TYPES.MAX_BUCKET + | typeof METRIC_TYPES.MIN_BUCKET + | typeof METRIC_TYPES.SUM_BUCKET; + const convertToFormulaParams = (formula: string): FormulaParams | null => ({ formula, }); @@ -71,8 +79,7 @@ const convertFormulaScriptForAggs = ( export const convertMathToFormulaColumn = ( series: Series, - metrics: Metric[], - dataView: DataView + metrics: Metric[] ): FormulaColumn | null => { // find the metric idx that has math expression const mathMetric = metrics.find((metric) => metric.type === 'math'); @@ -121,3 +128,17 @@ export const convertMathToFormulaColumn = ( return createFormulaColumn(script, series, mathMetric); }; + +export const convertOtherAggsToFormulaColumn = ( + aggregation: OtherFormulaAggregations, + series: Series, + metrics: Metric[] +): FormulaColumn | null => { + const currentMetric = metrics[metrics.length - 1]; + + const formula = getSiblingPipelineSeriesFormula(aggregation, currentMetric, metrics); + if (!formula) { + return null; + } + return createFormulaColumn(formula, series, currentMetric); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 7bc2b4ea476a6..fc922ee573b66 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -9,6 +9,6 @@ export { convertMetricsToColumns } from './column'; export { convertToPercentileColumns } from './percentile'; export { convertToPercentileRankColumns } from './percentile_rank'; -export { convertMathToFormulaColumn } from './formula'; +export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './formula'; export { convertParentPipelineAggToColumns } from './parent_pipeline'; export { convertToCumulativeSumColumns } from './cumulative_sum'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index 92e0b33fab951..2917ca38b9b77 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -18,6 +18,7 @@ import { convertMathToFormulaColumn, convertParentPipelineAggToColumns, convertToCumulativeSumColumns, + convertOtherAggsToFormulaColumn, } from '../convert'; type UnwrapArray = T extends Array ? P : T; @@ -55,7 +56,7 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null return convertMetricsToColumns(series, metrics, dataView, convertToPercentileRankColumns); } case 'math': - const formulaColumn = convertMathToFormulaColumn(series, metrics, dataView); + const formulaColumn = convertMathToFormulaColumn(series, metrics); return formulaColumn ? [formulaColumn] : null; case 'moving_average': @@ -65,6 +66,14 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null case 'cumulative_sum': const cumulativeSumColumns = convertToCumulativeSumColumns(series, metrics, dataView); return getValidColumns(cumulativeSumColumns); + case 'positive_only': + case 'avg_bucket': + case 'max_bucket': + case 'min_bucket': + case 'sum_bucket': { + const otherFormulaColumn = convertOtherAggsToFormulaColumn(aggregation, series, metrics); + return getValidColumns(otherFormulaColumn); + } } return []; From 0549bddc4f33110bde3791f1e4b7af75081e2294 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 14:09:21 +0300 Subject: [PATCH 017/129] Filter ratio added. --- .../lib/convert/filter_ratio.ts | 32 +++++++++++++++++++ .../convert_to_lens/lib/convert/index.ts | 1 + .../convert_to_lens/lib/series/new.columns.ts | 20 ++++++++---- 3 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts new file mode 100644 index 0000000000000..e5e08c0dadcfe --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -0,0 +1,32 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FormulaColumn } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import type { Metric, Series } from '../../../../common/types'; +import { getSiblingPipelineSeriesFormula } from '../metrics'; +import { createFormulaColumn } from './formula'; + +export const convertFilterRatioToFormulaColumn = ( + series: Series, + metrics: Metric[] +): FormulaColumn | null => { + const currentMetric = metrics[metrics.length - 1]; + + const formula = getSiblingPipelineSeriesFormula( + TSVB_METRIC_TYPES.FILTER_RATIO, + currentMetric, + metrics + ); + + if (!formula) { + return null; + } + + return createFormulaColumn(formula, series, currentMetric); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index fc922ee573b66..3b8aa4441ff4a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -12,3 +12,4 @@ export { convertToPercentileRankColumns } from './percentile_rank'; export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './formula'; export { convertParentPipelineAggToColumns } from './parent_pipeline'; export { convertToCumulativeSumColumns } from './cumulative_sum'; +export { convertFilterRatioToFormulaColumn } from './filter_ratio'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index 2917ca38b9b77..c5aa82f2f8e81 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -19,6 +19,7 @@ import { convertParentPipelineAggToColumns, convertToCumulativeSumColumns, convertOtherAggsToFormulaColumn, + convertFilterRatioToFormulaColumn, } from '../convert'; type UnwrapArray = T extends Array ? P : T; @@ -55,24 +56,29 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null case 'percentile_rank': { return convertMetricsToColumns(series, metrics, dataView, convertToPercentileRankColumns); } - case 'math': + case 'math': { const formulaColumn = convertMathToFormulaColumn(series, metrics); return formulaColumn ? [formulaColumn] : null; - - case 'moving_average': + } + case 'moving_average': { const movingAverageColumns = convertParentPipelineAggToColumns(series, metrics, dataView); return getValidColumns(movingAverageColumns); - - case 'cumulative_sum': + } + case 'cumulative_sum': { const cumulativeSumColumns = convertToCumulativeSumColumns(series, metrics, dataView); return getValidColumns(cumulativeSumColumns); + } + case 'filter_ratio': { + const formulaColumn = convertFilterRatioToFormulaColumn(series, metrics); + return getValidColumns(formulaColumn); + } case 'positive_only': case 'avg_bucket': case 'max_bucket': case 'min_bucket': case 'sum_bucket': { - const otherFormulaColumn = convertOtherAggsToFormulaColumn(aggregation, series, metrics); - return getValidColumns(otherFormulaColumn); + const formulaColumn = convertOtherAggsToFormulaColumn(aggregation, series, metrics); + return getValidColumns(formulaColumn); } } From 9d1b9c987440df1405bce69df87e49b4ac029c4d Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Fri, 19 Aug 2022 15:41:27 +0300 Subject: [PATCH 018/129] Add XY Configuration --- .../lib/configurations/index.ts | 9 ++ .../lib/configurations/xy/chart_type.ts | 41 +++++ .../{ => configurations}/xy/extents.test.ts | 2 +- .../lib/{ => configurations}/xy/extents.ts | 10 +- .../lib/{ => configurations}/xy/index.ts | 1 + .../lib/configurations/xy/layers.ts | 100 ++++++++++++ .../convert_to_lens/lib/convert/column.ts | 6 +- .../convert_to_lens/lib/convert/index.ts | 4 +- .../convert_to_lens/lib/convert/percentile.ts | 24 ++- .../lib/convert/percentile_rank.ts | 24 ++- .../lib/metrics/metrics_helpers.ts | 2 +- .../lib/metrics/supported_metrics.ts | 4 +- .../convert_to_lens/lib/series/new.columns.ts | 2 +- .../convert_to_lens/lib/xy/chart_type.ts | 23 --- .../convert_to_lens/timeseries/index.ts | 4 +- .../convert_to_lens/timeseries/new.index.ts | 33 +++- .../public/convert_to_lens/types.ts | 2 +- .../common/convert_to_lens/types/columns.ts | 12 +- .../convert_to_lens/types/configurations.ts | 142 ++++++++++++++++++ .../common/convert_to_lens/types/context.ts | 5 +- .../common/convert_to_lens/types/index.ts | 1 + 21 files changed, 396 insertions(+), 55 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/index.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts rename src/plugins/vis_types/timeseries/public/convert_to_lens/lib/{ => configurations}/xy/extents.test.ts (98%) rename src/plugins/vis_types/timeseries/public/convert_to_lens/lib/{ => configurations}/xy/extents.ts (93%) rename src/plugins/vis_types/timeseries/public/convert_to_lens/lib/{ => configurations}/xy/index.ts (94%) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/chart_type.ts create mode 100644 src/plugins/visualizations/common/convert_to_lens/types/configurations.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/index.ts new file mode 100644 index 0000000000000..42d0c8eee7379 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/index.ts @@ -0,0 +1,9 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './xy'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts new file mode 100644 index 0000000000000..ff1dbdf55cadd --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts @@ -0,0 +1,41 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { SeriesType, SeriesTypes } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { Series } from '../../../../../common/types'; +import { PANEL_TYPES } from '../../../../../common/enums'; + +export const getChartType = (series: Series, type: PANEL_TYPES): SeriesType => { + let layerChartType: SeriesType = SeriesTypes.LINE; + switch (series.chart_type) { + case SeriesTypes.LINE: + layerChartType = Number(series.fill) > 0 ? SeriesTypes.AREA : SeriesTypes.LINE; + break; + case SeriesTypes.AREA: + layerChartType = SeriesTypes.AREA; + break; + case SeriesTypes.BAR: + layerChartType = SeriesTypes.BAR; + break; + } + + if (type === PANEL_TYPES.TOP_N) { + return 'bar_horizontal'; + } + + if (series.stacked !== 'none' && series.stacked !== 'percent') { + return layerChartType !== SeriesTypes.LINE ? `${layerChartType}_stacked` : SeriesTypes.LINE; + } + if (series.stacked === 'percent') { + return layerChartType !== SeriesTypes.LINE + ? `${layerChartType}_percentage_stacked` + : SeriesTypes.LINE; + } + + return layerChartType; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/extents.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/extents.test.ts similarity index 98% rename from src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/extents.test.ts rename to src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/extents.test.ts index e07aff3d3427f..6536e1dfde6d3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/extents.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/extents.test.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { Panel } from '../../../../common/types'; +import type { Panel } from '../../../../../common/types'; import { getYExtents } from './extents'; const model = { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/extents.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/extents.ts similarity index 93% rename from src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/extents.ts rename to src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/extents.ts index 5e1b0ac4cac8e..1ee1054c56b55 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/extents.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/extents.ts @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -import type { Panel, Series } from '../../../../common/types'; +import { AxisExtentConfig } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import type { Panel, Series } from '../../../../../common/types'; const lowerBoundShouldBeZero = ( lowerBound: number | null, @@ -45,7 +46,12 @@ const getLowerValue = ( * In Lens, we only allow 2 axis, one left and one right. We need an assumption here. * We will transfer in Lens the "collapsed" axes with both bounds. */ -export const getYExtents = (model: Panel) => { +export const getYExtents = ( + model: Panel +): { + yLeftExtent?: AxisExtentConfig; + yRightExtent?: AxisExtentConfig; +} => { let lowerBoundLeft: number | null = null; let upperBoundLeft: number | null = null; let lowerBoundRight: number | null = null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/index.ts similarity index 94% rename from src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/index.ts rename to src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/index.ts index 08adee9f984a0..7a2586d4c45da 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/index.ts @@ -6,5 +6,6 @@ * Side Public License, v 1. */ +export * from './layers'; export * from './extents'; export * from './chart_type'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts new file mode 100644 index 0000000000000..06db4e0949003 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts @@ -0,0 +1,100 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { + Column, + FillType, + Layer, + XYLayerConfig, + YAxisMode, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { PaletteOutput } from '@kbn/coloring'; +import { SUPPORTED_METRICS } from '../../metrics'; +import type { Metric, Panel } from '../../../../../common/types'; +import { getSeriesAgg } from '../../series'; +import { isPercentileRanksColumnWithMeta, isPercentileColumnWithMeta } from '../../convert'; +import { getChartType } from './chart_type'; + +function getPalette(palette: PaletteOutput): PaletteOutput { + return !palette || palette.name === 'gradient' || palette.name === 'rainbow' + ? { name: 'default', type: 'palette' } + : palette; +} + +function getColor( + metricColumn: Column, + metric: Metric, + seriesColor: string, + splitAccessor?: string +) { + if (isPercentileColumnWithMeta(metricColumn) && !splitAccessor) { + const [_, percentileIndex] = metricColumn.meta.reference.split('.'); + return metric.percentiles?.[parseInt(percentileIndex, 10)]?.color; + } + if (isPercentileRanksColumnWithMeta(metricColumn) && !splitAccessor) { + const [_, percentileRankIndex] = metricColumn.meta.reference.split('.'); + return metric.colors?.[parseInt(percentileRankIndex, 10)]; + } + + return seriesColor; +} + +export const getLayers = ( + dataSourceLayers: Record, + model: Panel +): XYLayerConfig[] => { + return Object.keys(dataSourceLayers).map((key) => { + const series = model.series[parseInt(key, 10)]; + const { metrics, seriesAgg } = getSeriesAgg(series.metrics); + const dataSourceLayer = dataSourceLayers[parseInt(key, 10)]; + const metricColumns = dataSourceLayer.columns.filter((l) => !l.isBucketed); + const isReferenceLine = metrics.length === 1 && metrics[0].type === 'static'; + const splitAccessor = dataSourceLayer.columns.find( + (column) => column.isBucketed && column.isSplit + )?.columnId; + const chartType = getChartType(series, model.type); + const commonProps = { + seriesType: chartType, + layerId: dataSourceLayer.layerId, + accessors: metricColumns.map((metricColumn) => { + return metricColumn.columnId; + }), + yConfig: metricColumns.map((metricColumn) => { + const metric = metrics.find( + (m) => SUPPORTED_METRICS[m.type]?.name === metricColumn.operationType + ); + return { + forAccessor: metricColumn.columnId, + color: getColor(metricColumn, metric!, series.color, splitAccessor), + axisMode: (series.separate_axis + ? series.axis_position + : model.axis_position) as YAxisMode, + ...(isReferenceLine && { + fill: (chartType === 'area' ? 'below' : 'none') as FillType, + }), + }; + }), + xAccessor: dataSourceLayer.columns.find((column) => column.isBucketed && !column.isSplit) + ?.columnId, + splitAccessor, + collapseFn: seriesAgg, + palette: getPalette(series.palette as PaletteOutput), + }; + if (isReferenceLine) { + return { + layerType: 'referenceLine', + ...commonProps, + }; + } else { + return { + layerType: 'data', + ...commonProps, + }; + } + }); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index b5fa86a22e8a8..264f56efbbf67 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -20,13 +20,15 @@ import { getTimeScale } from '../metrics'; export const createColumn = ( series: Series, metric: Metric, - field?: DataViewField, - isBucketed: boolean = false + field: DataViewField, + isBucketed: boolean = false, + isSplit: boolean = false ): Omit, 'operationType' | 'params'> => ({ columnId: uuid(), dataType: (field?.type as DataType) ?? undefined, label: series.label, isBucketed, + isSplit, window: metric.window?.toString(), filter: series.filter, timeScale: getTimeScale(metric), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 3b8aa4441ff4a..617337eb0faa7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -7,8 +7,8 @@ */ export { convertMetricsToColumns } from './column'; -export { convertToPercentileColumns } from './percentile'; -export { convertToPercentileRankColumns } from './percentile_rank'; +export { convertToPercentileColumns, isPercentileColumnWithMeta } from './percentile'; +export { convertToPercentileRankColumns, isPercentileRanksColumnWithMeta } from './percentile_rank'; export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './formula'; export { convertParentPipelineAggToColumns } from './parent_pipeline'; export { convertToCumulativeSumColumns } from './cumulative_sum'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 45c21532d2b9e..16fb2bbebbe6c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -8,12 +8,20 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { - PercentileColumn, + Column, + ColumnWithMeta, + Operations, + PercentileColumnWithMeta, PercentileParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Percentile, Series } from '../../../../common/types'; import { createColumn } from './column'; +export const isPercentileColumnWithMeta = ( + column: Column | ColumnWithMeta +): column is PercentileColumnWithMeta => + column.operationType === Operations.PERCENTILE && Boolean((column as ColumnWithMeta).meta); + export const convertToPercentileParams = (value?: string | number): PercentileParams | null => value !== undefined && !isNaN(Number(value)) ? { @@ -25,8 +33,9 @@ const convertToPercentileColumn = ( percentile: Percentile, series: Series, metric: Metric, - dataView: DataView -): PercentileColumn | null => { + dataView: DataView, + index: number +): PercentileColumnWithMeta | null => { const params = convertToPercentileParams(percentile.value); if (!params) { return null; @@ -42,6 +51,9 @@ const convertToPercentileColumn = ( sourceField: field.name, ...createColumn(series, metric, field), params, + meta: { + reference: `${metric.id}.${index}`, + }, }; }; @@ -49,7 +61,7 @@ export const convertToPercentileColumns = ( series: Series, metric: Metric, dataView: DataView -): PercentileColumn[] => { +): PercentileColumnWithMeta[] => { const { percentiles } = metric; if (!percentiles) { @@ -57,6 +69,6 @@ export const convertToPercentileColumns = ( } return percentiles - .map((p) => convertToPercentileColumn(p, series, metric, dataView)) - .filter((p): p is PercentileColumn => Boolean(p)); + .map((p, index) => convertToPercentileColumn(p, series, metric, dataView, index)) + .filter((p): p is PercentileColumnWithMeta => Boolean(p)); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index ff6da02e49d5a..02e19d47becd8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -8,12 +8,20 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { - PercentileRanksColumn, + Column, + ColumnWithMeta, + Operations, + PercentileRanksColumnWithMeta, PercentileRanksParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; +export const isPercentileRanksColumnWithMeta = ( + column: Column | ColumnWithMeta +): column is PercentileRanksColumnWithMeta => + column.operationType === Operations.PERCENTILE_RANK && Boolean((column as ColumnWithMeta).meta); + export const convertToPercentileRankParams = (value: string): PercentileRanksParams | null => value !== undefined && !isNaN(Number(value)) ? { @@ -25,8 +33,9 @@ const convertToPercentileRankColumn = ( value: string, series: Series, metric: Metric, - dataView: DataView -): PercentileRanksColumn | null => { + dataView: DataView, + index: number +): PercentileRanksColumnWithMeta | null => { const params = convertToPercentileRankParams(value); if (!params) { return null; @@ -42,6 +51,9 @@ const convertToPercentileRankColumn = ( sourceField: field.name, ...createColumn(series, metric, field), params, + meta: { + reference: `${metric.id}.${index}`, + }, }; }; @@ -49,7 +61,7 @@ export const convertToPercentileRankColumns = ( series: Series, metric: Metric, dataView: DataView -): PercentileRanksColumn[] => { +): PercentileRanksColumnWithMeta[] => { const { values } = metric; if (!values) { @@ -57,6 +69,6 @@ export const convertToPercentileRankColumns = ( } return values - .map((p) => convertToPercentileRankColumn(p, series, metric, dataView)) - .filter((p): p is PercentileRanksColumn => Boolean(p)); + .map((p, index) => convertToPercentileRankColumn(p, series, metric, dataView, index)) + .filter((p): p is PercentileRanksColumnWithMeta => Boolean(p)); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 60a8202fcffe8..4978592f0e032 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { TimeScaleUnit } from '@kbn/visualizations-plugin/common'; +import { TimeScaleUnit } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, MetricType } from '../../../../common/types'; import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; import { getFilterRatioFormula } from './filter_ratio_formula'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts index 65e59feb1a25c..9b153c136f1e2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts @@ -7,13 +7,13 @@ */ import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import { Operation, Operations } from '@kbn/visualizations-plugin/common'; +import { Operation, Operations } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { MetricType } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; interface Agg { isFormula?: false; -}; +} interface AggWithFormula { isFormula: true; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index c5aa82f2f8e81..e110084647533 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { Column } from '@kbn/visualizations-plugin/common'; +import { Column } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { Series } from '../../../../common/types'; import { getSeriesAgg } from './get_series_agg'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/chart_type.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/chart_type.ts deleted file mode 100644 index f389568eed668..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/xy/chart_type.ts +++ /dev/null @@ -1,23 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { Series } from '../../../../common/types'; - -export const convertChartType = (series: Series) => { - const layerChartType = - series.chart_type === 'line' && Number(series.fill) > 0 ? 'area' : series.chart_type; - - if (series.stacked !== 'none' && series.stacked !== 'percent') { - return layerChartType !== 'line' ? `${layerChartType}_stacked` : 'line'; - } - if (series.stacked === 'percent') { - return layerChartType !== 'line' ? `${layerChartType}_percentage_stacked` : 'line'; - } - - return layerChartType; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index 2996ad19c42d9..482ea2d055eba 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -12,7 +12,7 @@ import { getDataSourceInfo } from '../lib/datasource'; import { getSeries } from '../lib/series'; import { getFieldsForTerms } from '../../../common/fields_utils'; import { ConvertTsvbToLensVisualization } from '../types'; -import { convertChartType, getYExtents } from '../lib/xy'; +import { getChartType, getYExtents } from '../lib/configurations/xy'; import { getLayerConfiguration } from '../lib/layers'; import { isSplitWithDateHistogram } from '../lib/split_chart'; @@ -58,7 +58,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { return null; } - const chartType = convertChartType(layer); + const chartType = getChartType(layer, model.type); layersConfiguration[layerIdx] = getLayerConfiguration( indexPatternId, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 5d7bfe218494b..9b92a08b87e85 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -6,14 +6,22 @@ * Side Public License, v 1. */ -import { Layer, NavigateToLensContext } from '@kbn/visualizations-plugin/common'; +import { Position } from '@elastic/charts'; +import { + Layer, + NavigateToLensContext, + XYConfiguration, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import { Panel } from '../../../common/types'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getColumns } from '../lib/series/new.columns'; +import { getLayers, getYExtents } from '../lib/configurations/xy'; -export const convertToLens = async (model: Panel): Promise => { +export const convertToLens = async ( + model: Panel +): Promise | null> => { const dataViews = getDataViewsStart(); const columns = []; const layers: Record = {}; @@ -43,9 +51,28 @@ export const convertToLens = async (model: Panel): Promise operationType: OperationType; label?: string; isBucketed: boolean; - dataType?: DataType; + isSplit: boolean; + dataType: DataType; timeScale?: TimeScaleUnit; // ? timeShift?: string; window?: string; @@ -107,3 +108,12 @@ export type AnyColumnWithReferences = | StaticValueColumn; export type Column = AnyColumnWithReferences | AnyColumnWithSourceField; + +export type PercentileColumnWithMeta = PercentileColumn & { + meta: { reference: `${string}.${number}` }; +}; +export type PercentileRanksColumnWithMeta = PercentileRanksColumn & { + meta: { reference: `${string}.${number}` }; +}; + +export type ColumnWithMeta = PercentileColumnWithMeta | PercentileRanksColumnWithMeta; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts b/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts new file mode 100644 index 0000000000000..a7176f3d1fe44 --- /dev/null +++ b/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts @@ -0,0 +1,142 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { HorizontalAlignment, Position, VerticalAlignment } from '@elastic/charts'; +import { $Values } from '@kbn/utility-types'; +import type { PaletteOutput } from '@kbn/coloring'; +import { LegendSize } from '../../constants'; + +export const XYCurveTypes = { + LINEAR: 'LINEAR', + CURVE_MONOTONE_X: 'CURVE_MONOTONE_X', + CURVE_STEP_AFTER: 'CURVE_STEP_AFTER', +} as const; + +export type XYCurveType = $Values; + +export const YAxisModes = { + AUTO: 'auto', + LEFT: 'left', + RIGHT: 'right', + BOTTOM: 'bottom', +} as const; + +export type YAxisMode = $Values; + +export const SeriesTypes = { + BAR: 'bar', + LINE: 'line', + AREA: 'area', + BAR_STACKED: 'bar_stacked', + AREA_STACKED: 'area_stacked', + BAR_HORIZONTAL: 'bar_horizontal', + BAR_PERCENTAGE_STACKED: 'bar_percentage_stacked', + BAR_HORIZONTAL_STACKED: 'bar_horizontal_stacked', + AREA_PERCENTAGE_STACKED: 'area_percentage_stacked', + BAR_HORIZONTAL_PERCENTAGE_STACKED: 'bar_horizontal_percentage_stacked', +} as const; + +export type FillType = 'none' | 'above' | 'below'; +export type SeriesType = $Values; + +export interface AxisExtentConfig { + mode: 'full' | 'custom' | 'dataBounds'; + lowerBound?: number; + upperBound?: number; + enforce?: boolean; +} + +export interface YConfig { + forAccessor: string; + color?: string; + icon?: string; + lineWidth?: number; + lineStyle?: 'solid' | 'dashed' | 'dotted' | 'dot-dashed'; + fill?: FillType; + iconPosition?: 'auto' | 'left' | 'right' | 'above' | 'below'; + textVisibility?: boolean; + axisMode?: YAxisMode; +} + +export interface XYDataLayerConfig { + layerId: string; + accessors: string[]; + layerType: 'data'; + seriesType: SeriesType; + xAccessor?: string; + simpleView?: boolean; + yConfig?: YConfig[]; + splitAccessor?: string; + palette?: PaletteOutput; + collapseFn?: string; + xScaleType?: 'time' | 'linear' | 'ordinal'; + isHistogram?: boolean; + columnToLabel?: string; +} + +export interface XYReferenceLineLayerConfig { + layerId: string; + accessors: string[]; + yConfig?: YConfig[]; + layerType: 'referenceLine'; +} + +export type XYLayerConfig = XYDataLayerConfig | XYReferenceLineLayerConfig; + +export interface AxesSettingsConfig { + x: boolean; + yRight: boolean; + yLeft: boolean; +} + +export interface LabelsOrientationConfig { + x: number; + yLeft: number; + yRight: number; +} + +export interface LegendConfig { + isVisible: boolean; + position: Position; + showSingleSeries?: boolean; + isInside?: boolean; + horizontalAlignment?: typeof HorizontalAlignment.Right | typeof HorizontalAlignment.Left; + verticalAlignment?: typeof VerticalAlignment.Top | typeof VerticalAlignment.Bottom; + floatingColumns?: number; + maxLines?: number; + shouldTruncate?: boolean; + legendSize?: LegendSize; +} + +export interface XYConfiguration { + preferredSeriesType?: SeriesType; + legend?: LegendConfig; + valueLabels?: 'hide' | 'show'; + fittingFunction?: 'None' | 'Zero' | 'Linear' | 'Carry' | 'Lookahead' | 'Average' | 'Nearest'; + emphasizeFitting?: boolean; + endValue?: 'None' | 'Zero' | 'Nearest'; + xExtent?: AxisExtentConfig; + yLeftExtent?: AxisExtentConfig; + yRightExtent?: AxisExtentConfig; + layers: XYLayerConfig[]; + xTitle?: string; + yTitle?: string; + yRightTitle?: string; + yLeftScale?: 'time' | 'linear' | 'log' | 'sqrt'; + yRightScale?: 'time' | 'linear' | 'log' | 'sqrt'; + axisTitlesVisibilitySettings?: AxesSettingsConfig; + tickLabelsVisibilitySettings?: AxesSettingsConfig; + gridlinesVisibilitySettings?: AxesSettingsConfig; + labelsOrientation?: LabelsOrientationConfig; + curveType?: XYCurveType; + fillOpacity?: number; + hideEndzones?: boolean; + valuesInLegend?: boolean; +} + +export type Configuration = XYConfiguration; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/context.ts b/src/plugins/visualizations/common/convert_to_lens/types/context.ts index cf36fbabc8bb7..f3cc17b19e639 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/context.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/context.ts @@ -7,6 +7,7 @@ */ import { Column } from './columns'; +import { Configuration } from './configurations'; export interface Layer { indexPatternId: string; @@ -15,8 +16,8 @@ export interface Layer { columnOrder: string[]; } -export interface NavigateToLensContext { +export interface NavigateToLensContext { layers: Record; type: string; - configuration: unknown; + configuration: T; } diff --git a/src/plugins/visualizations/common/convert_to_lens/types/index.ts b/src/plugins/visualizations/common/convert_to_lens/types/index.ts index f8fe0b88cab9d..e2f2834b0ab89 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/index.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/index.ts @@ -11,3 +11,4 @@ export * from './params'; export * from './operations'; export * from './columns'; export * from './context'; +export * from './configurations'; From 7b8786f73e9a94347983f65e1e8882b14faf1dcb Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 15:41:51 +0300 Subject: [PATCH 019/129] Added last_value convertion. --- .../convert_to_lens/lib/convert/index.ts | 1 + .../convert_to_lens/lib/convert/last_value.ts | 55 +++++++++++++++++++ .../convert_to_lens/lib/series/new.columns.ts | 5 ++ 3 files changed, 61 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 3b8aa4441ff4a..8c406b6b37597 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -13,3 +13,4 @@ export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './f export { convertParentPipelineAggToColumns } from './parent_pipeline'; export { convertToCumulativeSumColumns } from './cumulative_sum'; export { convertFilterRatioToFormulaColumn } from './filter_ratio'; +export { convertToLastValueColumn } from './last_value'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts new file mode 100644 index 0000000000000..7a98202f94685 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -0,0 +1,55 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import { + LastValueColumn, + LastValueParams, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import type { Metric, Series } from '../../../../common/types'; +import { createColumn } from './column'; + +const convertToLastValueParams = (metric: Metric): LastValueParams | null => + metric.order_by + ? { + sortField: metric.order_by, + showArrayValues: false, + } + : null; + +export const convertToLastValueColumn = ( + series: Series, + metrics: Metric[], + dataView: DataView +): LastValueColumn | null => { + const currentMetric = metrics[metrics.length - 1]; + // We can only support top_hit with size 1 + if ( + (currentMetric?.size && Number(currentMetric?.size) !== 1) || + currentMetric?.order === 'asc' + ) { + return null; + } + + const params = convertToLastValueParams(currentMetric); + if (!params) { + return null; + } + + const field = dataView.getFieldByName(currentMetric.field ?? 'document'); + if (!field) { + return null; + } + + return { + operationType: 'last_value', + sourceField: field.name ?? 'document', + ...createColumn(series, currentMetric), + params, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index c5aa82f2f8e81..23ebe3177ffaa 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -20,6 +20,7 @@ import { convertToCumulativeSumColumns, convertOtherAggsToFormulaColumn, convertFilterRatioToFormulaColumn, + convertToLastValueColumn, } from '../convert'; type UnwrapArray = T extends Array ? P : T; @@ -80,6 +81,10 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null const formulaColumn = convertOtherAggsToFormulaColumn(aggregation, series, metrics); return getValidColumns(formulaColumn); } + case 'top_hit': { + const column = convertToLastValueColumn(series, metrics, dataView); + return getValidColumns(column); + } } return []; From 6766d813c78127092f10bc1fef0d1cbc8443ebb0 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 16:08:10 +0300 Subject: [PATCH 020/129] Updated ColumnWithMeta types. --- .../convert_to_lens/lib/convert/percentile.ts | 8 +++---- .../lib/convert/percentile_rank.ts | 8 +++---- .../convert_to_lens/lib/convert/types.ts | 23 +++++++++++++++++++ .../common/convert_to_lens/types/columns.ts | 10 ++------ 4 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 16fb2bbebbe6c..cc77389477318 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -9,18 +9,18 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { Column, - ColumnWithMeta, Operations, - PercentileColumnWithMeta, PercentileParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Percentile, Series } from '../../../../common/types'; import { createColumn } from './column'; +import { CommonPercentileColumnWithMeta, PercentileColumnWithMeta } from './types'; export const isPercentileColumnWithMeta = ( - column: Column | ColumnWithMeta + column: Column | CommonPercentileColumnWithMeta ): column is PercentileColumnWithMeta => - column.operationType === Operations.PERCENTILE && Boolean((column as ColumnWithMeta).meta); + column.operationType === Operations.PERCENTILE && + Boolean((column as CommonPercentileColumnWithMeta).meta); export const convertToPercentileParams = (value?: string | number): PercentileParams | null => value !== undefined && !isNaN(Number(value)) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index 02e19d47becd8..12b9018d4d1ba 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -9,18 +9,18 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { Column, - ColumnWithMeta, Operations, - PercentileRanksColumnWithMeta, PercentileRanksParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; +import { CommonPercentileColumnWithMeta, PercentileRanksColumnWithMeta } from './types'; export const isPercentileRanksColumnWithMeta = ( - column: Column | ColumnWithMeta + column: Column | CommonPercentileColumnWithMeta ): column is PercentileRanksColumnWithMeta => - column.operationType === Operations.PERCENTILE_RANK && Boolean((column as ColumnWithMeta).meta); + column.operationType === Operations.PERCENTILE_RANK && + Boolean((column as CommonPercentileColumnWithMeta).meta); export const convertToPercentileRankParams = (value: string): PercentileRanksParams | null => value !== undefined && !isNaN(Number(value)) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts new file mode 100644 index 0000000000000..70a32b31e53cf --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts @@ -0,0 +1,23 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { + ColumnWithMeta, + PercentileColumn, + PercentileRanksColumn, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; + +export interface PercentileMeta { + reference: `${string}.${number}`; +} + +export type PercentileColumnWithMeta = ColumnWithMeta; +export type PercentileRanksColumnWithMeta = ColumnWithMeta; +export type CommonPercentileColumnWithMeta = + | PercentileColumnWithMeta + | PercentileRanksColumnWithMeta; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index 8dd1a03ab32d7..06e5daf201dbb 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -109,11 +109,5 @@ export type AnyColumnWithReferences = export type Column = AnyColumnWithReferences | AnyColumnWithSourceField; -export type PercentileColumnWithMeta = PercentileColumn & { - meta: { reference: `${string}.${number}` }; -}; -export type PercentileRanksColumnWithMeta = PercentileRanksColumn & { - meta: { reference: `${string}.${number}` }; -}; - -export type ColumnWithMeta = PercentileColumnWithMeta | PercentileRanksColumnWithMeta; +export type ColumnWithMeta = Col & + (Meta extends undefined ? undefined : { meta: Meta }); From edbeea05f6e0b83a79bac9549a2083108ef3c11d Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 16:22:22 +0300 Subject: [PATCH 021/129] Fixed for loop. --- .../timeseries/public/convert_to_lens/timeseries/new.index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 9b92a08b87e85..a4f7b656d8a54 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -26,8 +26,7 @@ export const convertToLens = async ( const columns = []; const layers: Record = {}; // handle multiple layers/series - for (let layerIdx = 0; layerIdx < model.series.length; layerIdx++) { - const series = model.series[layerIdx]; + for (const [layerIdx, series] of model.series.entries()) { if (series.hidden) { continue; } From 5221a014d8333d48bd16d2711c49c6c02b5a1f5e Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 16:55:37 +0300 Subject: [PATCH 022/129] Added StaticValue convertion. --- .../convert_to_lens/lib/convert/column.ts | 2 +- .../lib/convert/static_value.ts | 35 +++++++++++++++++++ .../convert_to_lens/lib/series/new.columns.ts | 11 +++++- .../convert_to_lens/timeseries/new.index.ts | 4 ++- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 264f56efbbf67..feaf1d15975ae 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -20,7 +20,7 @@ import { getTimeScale } from '../metrics'; export const createColumn = ( series: Series, metric: Metric, - field: DataViewField, + field?: DataViewField, isBucketed: boolean = false, isSplit: boolean = false ): Omit, 'operationType' | 'params'> => ({ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts new file mode 100644 index 0000000000000..b109ca9a67892 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -0,0 +1,35 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { + StaticValueColumn, + StaticValueParams, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import type { Metric, Series } from '../../../../common/types'; +import { createColumn } from './column'; + +export const convertToStaticValueParams = ({ value }: Metric): StaticValueParams => ({ + value, +}); + +export const convertToStaticValueColumn = ( + series: Series, + metrics: Metric[], + visibleSeriesCount: number +): StaticValueColumn | null => { + if (visibleSeriesCount === 1) { + return null; + } + const currentMetric = metrics[metrics.length - 1]; + return { + operationType: 'static_value', + references: [], + ...createColumn(series, currentMetric), + params: convertToStaticValueParams(currentMetric), + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index bcad5b5d78377..016a7cfaf1ff7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -22,6 +22,7 @@ import { convertFilterRatioToFormulaColumn, convertToLastValueColumn, } from '../convert'; +import { convertToStaticValueColumn } from '../convert/static_value'; type UnwrapArray = T extends Array ? P : T; @@ -41,7 +42,11 @@ const getValidColumns = (columns: Array | Column | null | undefin return columns ? [columns] : null; }; -export const getColumns = (series: Series, dataView: DataView): Column[] | null => { +export const getColumns = ( + series: Series, + dataView: DataView, + visibleSeriesCount: number +): Column[] | null => { const { metrics } = getSeriesAgg(series.metrics); const metricIdx = metrics.length - 1; const aggregation = metrics[metricIdx].type; @@ -85,6 +90,10 @@ export const getColumns = (series: Series, dataView: DataView): Column[] | null const column = convertToLastValueColumn(series, metrics, dataView); return getValidColumns(column); } + case 'static': { + const column = convertToStaticValueColumn(series, metrics, visibleSeriesCount); + return getValidColumns(column); + } } return []; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index a4f7b656d8a54..07f2d35ca9d2d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -25,6 +25,8 @@ export const convertToLens = async ( const dataViews = getDataViewsStart(); const columns = []; const layers: Record = {}; + const seriesNum = model.series.filter((series) => !series.hidden).length; + // handle multiple layers/series for (const [layerIdx, series] of model.series.entries()) { if (series.hidden) { @@ -40,7 +42,7 @@ export const convertToLens = async ( ); // handle multiple metrics - const seriesColumns = getColumns(series, indexPattern!); + const seriesColumns = getColumns(series, indexPattern!, seriesNum); if (!seriesColumns) { return null; } From ecdf3e28430143846157a88ad1de1ed360ded0d6 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 18:05:42 +0300 Subject: [PATCH 023/129] Added default agg convertion. --- .../convert_to_lens/lib/convert/index.ts | 6 +- .../lib/convert/parent_pipeline.ts | 94 +++++++++++++------ .../convert_to_lens/lib/series/new.columns.ts | 12 ++- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 34f59d71c95db..73d7b7495f78d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -10,7 +10,11 @@ export { convertMetricsToColumns } from './column'; export { convertToPercentileColumns, isPercentileColumnWithMeta } from './percentile'; export { convertToPercentileRankColumns, isPercentileRanksColumnWithMeta } from './percentile_rank'; export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './formula'; -export { convertParentPipelineAggToColumns } from './parent_pipeline'; +export { + convertParentPipelineAggToColumns, + convertMetricAggregationColumnWithoutParams, +} from './parent_pipeline'; export { convertToCumulativeSumColumns } from './cumulative_sum'; export { convertFilterRatioToFormulaColumn } from './filter_ratio'; export { convertToLastValueColumn } from './last_value'; +export { convertToStaticValueColumn } from './static_value'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 980cda8038581..45d2f7a95578a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -25,7 +25,7 @@ import { SumColumn, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; -import { Metric, Series } from '../../../../common/types'; +import { Metric, MetricType, Series } from '../../../../common/types'; import { getFilterRatioFormula, getFormulaFromMetric, @@ -40,24 +40,24 @@ import { convertToMovingAverageParams } from './moving_average'; import { convertToPercentileParams } from './percentile'; import { convertToPercentileRankParams } from './percentile_rank'; -type PipelineAggregation = +type MetricAggregationWithoutParams = | typeof Operations.AVERAGE | typeof Operations.COUNT | typeof Operations.UNIQUE_COUNT | typeof Operations.COUNTER_RATE | typeof Operations.MAX | typeof Operations.MIN - | typeof Operations.SUM + | typeof Operations.SUM; + +type MetricAggregation = + | MetricAggregationWithoutParams | typeof Operations.LAST_VALUE | typeof Operations.PERCENTILE | typeof Operations.PERCENTILE_RANK; -type PipelineAggregationColumnWithParams = - | PercentileColumn - | PercentileRanksColumn - | LastValueColumn; +type MetricAggregationColumnWithParams = PercentileColumn | PercentileRanksColumn | LastValueColumn; -type PipelineAggregationColumnWithoutParams = +type MetricAggregationColumnWithoutParams = | AvgColumn | CountColumn | CardinalityColumn @@ -66,9 +66,9 @@ type PipelineAggregationColumnWithoutParams = | MinColumn | SumColumn; -type PipelineAggregationColumn = - | PipelineAggregationColumnWithoutParams - | PipelineAggregationColumnWithParams; +type MetricAggregationColumn = + | MetricAggregationColumnWithoutParams + | MetricAggregationColumnWithParams; type ParentPipelineAggregation = | typeof Operations.MOVING_AVERAGE @@ -77,7 +77,7 @@ type ParentPipelineAggregation = type ParentPipelineAggColumn = MovingAverageColumn | DerivativeColumn | CumulativeSumColumn; -const SUPPORTED_PARENT_PIPELINE_AGGS: PipelineAggregation[] = [ +const SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS: MetricAggregationWithoutParams[] = [ Operations.AVERAGE, Operations.COUNT, Operations.UNIQUE_COUNT, @@ -85,27 +85,66 @@ const SUPPORTED_PARENT_PIPELINE_AGGS: PipelineAggregation[] = [ Operations.MAX, Operations.MIN, Operations.SUM, +]; + +const SUPPORTED_METRIC_AGGS: MetricAggregation[] = [ + ...SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS, Operations.LAST_VALUE, Operations.PERCENTILE, Operations.PERCENTILE_RANK, ]; -const isSupportedAggregation = (agg: string): agg is PipelineAggregation => { - return (SUPPORTED_PARENT_PIPELINE_AGGS as string[]).includes(agg); +const isSupportedAggregation = (agg: string): agg is MetricAggregation => { + return (SUPPORTED_METRIC_AGGS as string[]).includes(agg); +}; + +const isSupportedAggregationWithoutParams = ( + agg: string +): agg is MetricAggregationWithoutParams => { + return (SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS as string[]).includes(agg); +}; + +export const convertMetricAggregationColumnWithoutParams = ( + aggregation: MetricType, + series: Series, + metric: Metric, + dataView: DataView +): MetricAggregationColumnWithoutParams | null => { + const supportedAgg = SUPPORTED_METRICS[aggregation]; + if (!supportedAgg) { + return null; + } + if (!isSupportedAggregationWithoutParams(supportedAgg.name)) { + return null; + } + + const sourceField = aggregation !== 'count' && metric.field ? metric.field : 'document'; + + const field = dataView.getFieldByName(sourceField); + if (!field && aggregation !== 'count') { + return null; + } + + return { + operationType: supportedAgg.name, + sourceField, + ...createColumn(series, metric, field), + params: {}, + } as MetricAggregationColumnWithoutParams; }; -export const convertPipelineAggToColumn = ( +export const convertMetricAggregationToColumn = ( aggregation: SupportedMetric, series: Series, - parentPipelineMetric: Metric, + metric: Metric, dataView: DataView, meta?: number -): PipelineAggregationColumn | null => { +): MetricAggregationColumn | null => { if (!isSupportedAggregation(aggregation.name)) { return null; } - const field = dataView.getFieldByName(parentPipelineMetric.field ?? 'document'); + const field = dataView.getFieldByName(metric.field ?? 'document'); if (!field) { return null; } @@ -116,7 +155,7 @@ export const convertPipelineAggToColumn = ( ? { operationType: aggregation.name, sourceField: field.name, - ...createColumn(series, parentPipelineMetric, field), + ...createColumn(series, metric, field), params, } : null; @@ -128,7 +167,7 @@ export const convertPipelineAggToColumn = ( ? { operationType: aggregation.name, sourceField: field.name, - ...createColumn(series, parentPipelineMetric, field), + ...createColumn(series, metric, field), params, } : null; @@ -138,12 +177,7 @@ export const convertPipelineAggToColumn = ( return null; } - return { - operationType: aggregation.name, - sourceField: field.name, - ...createColumn(series, parentPipelineMetric, field), - params: {}, - } as PipelineAggregationColumnWithoutParams; + return convertMetricAggregationColumnWithoutParams(aggregation.name, series, metric, dataView); }; export const computeParentPipelineColumns = ( @@ -171,7 +205,7 @@ export const computeParentPipelineColumns = ( return createFormulaColumn(formula, series, currentMetric); } - const pipelineAggColumn = convertPipelineAggToColumn( + const metricAggregationColumn = convertMetricAggregationToColumn( pipelineAgg, series, subFunctionMetric, @@ -179,14 +213,14 @@ export const computeParentPipelineColumns = ( meta ); - if (!pipelineAggColumn) { + if (!metricAggregationColumn) { return null; } return [ - pipelineAggColumn, + metricAggregationColumn, createParentPipelineAggregationColumn(aggregation, series, currentMetric, [ - pipelineAggColumn.columnId, + metricAggregationColumn.columnId, ]), ]; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts index 016a7cfaf1ff7..c47fb35f58053 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts @@ -21,8 +21,9 @@ import { convertOtherAggsToFormulaColumn, convertFilterRatioToFormulaColumn, convertToLastValueColumn, + convertToStaticValueColumn, + convertMetricAggregationColumnWithoutParams, } from '../convert'; -import { convertToStaticValueColumn } from '../convert/static_value'; type UnwrapArray = T extends Array ? P : T; @@ -94,6 +95,15 @@ export const getColumns = ( const column = convertToStaticValueColumn(series, metrics, visibleSeriesCount); return getValidColumns(column); } + default: { + const column = convertMetricAggregationColumnWithoutParams( + aggregation, + series, + metrics[metricIdx], + dataView + ); + return getValidColumns(column); + } } return []; From faab8102cde8b7872a9ac2aee6c4514615215196 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Fri, 19 Aug 2022 18:11:00 +0300 Subject: [PATCH 024/129] Add filters column --- .../lib/configurations/xy/chart_type.ts | 2 +- .../convert_to_lens/lib/convert/filters.ts | 51 +++++++++++++++++++ .../convert_to_lens/lib/convert/index.ts | 1 + .../convert_to_lens/timeseries/new.index.ts | 10 ++++ .../common/convert_to_lens/types/columns.ts | 2 +- 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts index ff1dbdf55cadd..b03a0ffeff650 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/chart_type.ts @@ -25,7 +25,7 @@ export const getChartType = (series: Series, type: PANEL_TYPES): SeriesType => { } if (type === PANEL_TYPES.TOP_N) { - return 'bar_horizontal'; + return SeriesTypes.BAR_HORIZONTAL; } if (series.stacked !== 'none' && series.stacked !== 'percent') { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts new file mode 100644 index 0000000000000..a5dbe1936c781 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts @@ -0,0 +1,51 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import uuid from 'uuid'; +import { FiltersParams, FitlersColumn } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import type { Series } from '../../../../common/types'; + +export const convertToFiltersParams = (series: Series): FiltersParams => { + const splitFilters = []; + if (series.split_mode === 'filter' && series.filter) { + splitFilters.push({ filter: series.filter }); + } + if (series.split_filters) { + splitFilters.push(...series.split_filters); + } + + return { + filters: splitFilters?.map((param) => { + const query = param.filter ? param.filter.query : ''; + const language = param.filter ? param.filter.language : 'kuery'; + return { + input: { + query, + language, + }, + label: param.label ?? '', + }; + }), + }; +}; + +export const convertToFiltersColumn = (series: Series, isSplit: boolean): FitlersColumn | null => { + const params = convertToFiltersParams(series); + if (!params.filters.length) { + return null; + } + + return { + columnId: uuid(), + operationType: 'filters', + dataType: 'string', + isBucketed: true, + isSplit, + params, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 73d7b7495f78d..c26ba07320fd9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -18,3 +18,4 @@ export { convertToCumulativeSumColumns } from './cumulative_sum'; export { convertFilterRatioToFormulaColumn } from './filter_ratio'; export { convertToLastValueColumn } from './last_value'; export { convertToStaticValueColumn } from './static_value'; +export { convertToFiltersColumn } from './filters'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 07f2d35ca9d2d..89bff4bb579a1 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -18,6 +18,7 @@ import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getColumns } from '../lib/series/new.columns'; import { getLayers, getYExtents } from '../lib/configurations/xy'; +import { convertToFiltersColumn } from '../lib/convert'; export const convertToLens = async ( model: Panel @@ -48,6 +49,15 @@ export const convertToLens = async ( } columns.push(...seriesColumns); + + if (series.split_mode === 'filters' || series.split_mode === 'filter') { + const filterColumn = convertToFiltersColumn(series, true); + if (!filterColumn) { + return null; + } + columns.push(filterColumn); + } + const layerId = uuid(); layers[layerIdx] = { indexPatternId, layerId, columns, columnOrder: [] }; // TODO: update later. } diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index 06e5daf201dbb..20631171a1d1d 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -57,7 +57,7 @@ export interface ColumnWithReferences; +export type FitlersColumn = BaseColumn<'filters', FiltersParams>; export type RangeColumn = ColumnWithSourceField<'range', RangeParams>; export type TermsColumn = ColumnWithSourceField<'terms', TermsParams>; export type DateHistogramColumn = ColumnWithSourceField<'date_histogram', DateHistogramParams>; From 08a05394af38e01af01b33ca3f701b167d8d6d68 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 19 Aug 2022 18:48:39 +0300 Subject: [PATCH 025/129] Refactored filter part. --- .../convert_to_lens/lib/series/index.ts | 2 ++ .../{new.columns.ts => metrics_columns.ts} | 2 +- .../lib/series/split_columns.ts | 21 +++++++++++++++++++ .../convert_to_lens/timeseries/new.index.ts | 20 ++++++++---------- 4 files changed, 33 insertions(+), 12 deletions(-) rename src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/{new.columns.ts => metrics_columns.ts} (99%) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts index 6c111d50493e6..b02865d24257d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts @@ -8,3 +8,5 @@ export * from './get_series'; export * from './get_series_agg'; +export * from './metrics_columns'; +export * from './split_columns'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts similarity index 99% rename from src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts rename to src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index c47fb35f58053..0c3f8c4e88234 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/new.columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -43,7 +43,7 @@ const getValidColumns = (columns: Array | Column | null | undefin return columns ? [columns] : null; }; -export const getColumns = ( +export const getMetricsColumns = ( series: Series, dataView: DataView, visibleSeriesCount: number diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts new file mode 100644 index 0000000000000..4ad60a144cc5d --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts @@ -0,0 +1,21 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Series } from '../../../../common/types'; +import { convertToFiltersColumn } from '../convert'; + +export const getFiltersOrTermColumns = (series: Series) => { + if (series.split_mode === 'filters' || series.split_mode === 'filter') { + const filterColumn = convertToFiltersColumn(series, true); + if (!filterColumn) { + return null; + } + return [filterColumn]; + } + return []; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 89bff4bb579a1..e23cd1c8a9fd6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -16,9 +16,8 @@ import uuid from 'uuid'; import { Panel } from '../../../common/types'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; -import { getColumns } from '../lib/series/new.columns'; +import { getMetricsColumns, getFiltersOrTermColumns } from '../lib/series'; import { getLayers, getYExtents } from '../lib/configurations/xy'; -import { convertToFiltersColumn } from '../lib/convert'; export const convertToLens = async ( model: Panel @@ -43,21 +42,20 @@ export const convertToLens = async ( ); // handle multiple metrics - const seriesColumns = getColumns(series, indexPattern!, seriesNum); - if (!seriesColumns) { + const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum); + if (!metricsColumns) { return null; } - columns.push(...seriesColumns); + columns.push(...metricsColumns); - if (series.split_mode === 'filters' || series.split_mode === 'filter') { - const filterColumn = convertToFiltersColumn(series, true); - if (!filterColumn) { - return null; - } - columns.push(filterColumn); + const filtersOrTermColumns = getFiltersOrTermColumns(series); + if (filtersOrTermColumns === null) { + return null; } + columns.push(...filtersOrTermColumns); + const layerId = uuid(); layers[layerIdx] = { indexPatternId, layerId, columns, columnOrder: [] }; // TODO: update later. } From defc3a0db5c31ee2aa1e959fbe0d89e56c483aa0 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 22 Aug 2022 13:23:46 +0300 Subject: [PATCH 026/129] Added meta to all the cols. --- .../lib/configurations/xy/layers.ts | 9 +- .../convert_to_lens/lib/convert/column.ts | 8 +- .../lib/convert/filter_ratio.ts | 2 +- .../convert_to_lens/lib/convert/filters.ts | 5 +- .../convert_to_lens/lib/convert/formula.ts | 3 +- .../convert_to_lens/lib/convert/index.ts | 1 + .../convert_to_lens/lib/convert/last_value.ts | 6 +- .../lib/convert/parent_pipeline.ts | 46 +++------ .../convert_to_lens/lib/convert/percentile.ts | 44 ++++----- .../lib/convert/percentile_rank.ts | 32 ++++--- .../lib/convert/static_value.ts | 6 +- .../convert_to_lens/lib/convert/types.ts | 96 +++++++++++++++++-- .../lib/series/metrics_columns.ts | 4 +- .../convert_to_lens/timeseries/new.index.ts | 35 +++++-- .../common/convert_to_lens/types/columns.ts | 7 +- .../visualizations/public/vis_types/types.ts | 4 +- 16 files changed, 200 insertions(+), 108 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts index 06db4e0949003..b2ca9b7590b75 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts @@ -7,9 +7,7 @@ */ import { - Column, FillType, - Layer, XYLayerConfig, YAxisMode, } from '@kbn/visualizations-plugin/common/convert_to_lens'; @@ -17,7 +15,12 @@ import { PaletteOutput } from '@kbn/coloring'; import { SUPPORTED_METRICS } from '../../metrics'; import type { Metric, Panel } from '../../../../../common/types'; import { getSeriesAgg } from '../../series'; -import { isPercentileRanksColumnWithMeta, isPercentileColumnWithMeta } from '../../convert'; +import { + isPercentileRanksColumnWithMeta, + isPercentileColumnWithMeta, + Column, + Layer, +} from '../../convert'; import { getChartType } from './chart_type'; function getPalette(palette: PaletteOutput): PaletteOutput { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index feaf1d15975ae..1803ae3e0ff96 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -11,11 +11,16 @@ import { Operation, DataType, Column, + ColumnWithMeta, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; import { ConvertToColumnsFn } from '../../types'; import { getTimeScale } from '../metrics'; +import { Meta } from './types'; + +type GeneralColumn = Omit, 'operationType' | 'params'>; +type GeneralColumnWithMeta = ColumnWithMeta; export const createColumn = ( series: Series, @@ -23,7 +28,7 @@ export const createColumn = ( field?: DataViewField, isBucketed: boolean = false, isSplit: boolean = false -): Omit, 'operationType' | 'params'> => ({ +): GeneralColumnWithMeta => ({ columnId: uuid(), dataType: (field?.type as DataType) ?? undefined, label: series.label, @@ -32,6 +37,7 @@ export const createColumn = ( window: metric.window?.toString(), filter: series.filter, timeScale: getTimeScale(metric), + meta: { metricId: metric.id }, }); export const convertMetricsToColumns = ( diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts index e5e08c0dadcfe..ff6e3868ef871 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import { FormulaColumn } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric, Series } from '../../../../common/types'; import { getSiblingPipelineSeriesFormula } from '../metrics'; import { createFormulaColumn } from './formula'; +import { FormulaColumn } from './types'; export const convertFilterRatioToFormulaColumn = ( series: Series, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts index a5dbe1936c781..9134504813b68 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.ts @@ -7,7 +7,8 @@ */ import uuid from 'uuid'; -import { FiltersParams, FitlersColumn } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { FiltersParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { FiltersColumn } from './types'; import type { Series } from '../../../../common/types'; export const convertToFiltersParams = (series: Series): FiltersParams => { @@ -34,7 +35,7 @@ export const convertToFiltersParams = (series: Series): FiltersParams => { }; }; -export const convertToFiltersColumn = (series: Series, isSplit: boolean): FitlersColumn | null => { +export const convertToFiltersColumn = (series: Series, isSplit: boolean): FiltersColumn | null => { const params = convertToFiltersParams(series); if (!params.filters.length) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index c1f9bec6ed949..8f9e7f0e041d2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -7,7 +7,8 @@ */ import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import { FormulaColumn, FormulaParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { FormulaParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { FormulaColumn } from './types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric, Series } from '../../../../common/types'; import { getFormulaEquivalent, getSiblingPipelineSeriesFormula } from '../metrics'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index c26ba07320fd9..d03d8b4a8f749 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -19,3 +19,4 @@ export { convertFilterRatioToFormulaColumn } from './filter_ratio'; export { convertToLastValueColumn } from './last_value'; export { convertToStaticValueColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; +export * from './types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index 7a98202f94685..297b6bf972661 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -7,10 +7,8 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; -import { - LastValueColumn, - LastValueParams, -} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { LastValueParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { LastValueColumn } from './types'; import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 45d2f7a95578a..d0ce3559e014e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -8,6 +8,7 @@ import { METRIC_TYPES } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/common'; +import { Operations } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { AvgColumn, CardinalityColumn, @@ -19,13 +20,12 @@ import { MaxColumn, MinColumn, MovingAverageColumn, - Operations, PercentileColumn, PercentileRanksColumn, SumColumn, -} from '@kbn/visualizations-plugin/common/convert_to_lens'; +} from './types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; -import { Metric, MetricType, Series } from '../../../../common/types'; +import { Metric, Series } from '../../../../common/types'; import { getFilterRatioFormula, getFormulaFromMetric, @@ -37,8 +37,8 @@ import { import { createColumn } from './column'; import { createFormulaColumn } from './formula'; import { convertToMovingAverageParams } from './moving_average'; -import { convertToPercentileParams } from './percentile'; -import { convertToPercentileRankParams } from './percentile_rank'; +import { convertToPercentileColumn } from './percentile'; +import { convertToPercentileRankColumn } from './percentile_rank'; type MetricAggregationWithoutParams = | typeof Operations.AVERAGE @@ -105,28 +105,24 @@ const isSupportedAggregationWithoutParams = ( }; export const convertMetricAggregationColumnWithoutParams = ( - aggregation: MetricType, + aggregation: SupportedMetric, series: Series, metric: Metric, dataView: DataView ): MetricAggregationColumnWithoutParams | null => { - const supportedAgg = SUPPORTED_METRICS[aggregation]; - if (!supportedAgg) { - return null; - } - if (!isSupportedAggregationWithoutParams(supportedAgg.name)) { + if (!isSupportedAggregationWithoutParams(aggregation.name)) { return null; } - const sourceField = aggregation !== 'count' && metric.field ? metric.field : 'document'; + const sourceField = aggregation.name !== 'count' && metric.field ? metric.field : 'document'; const field = dataView.getFieldByName(sourceField); - if (!field && aggregation !== 'count') { + if (!field && aggregation.name !== 'count') { return null; } return { - operationType: supportedAgg.name, + operationType: aggregation.name, sourceField, ...createColumn(series, metric, field), params: {}, @@ -150,34 +146,18 @@ export const convertMetricAggregationToColumn = ( } if (aggregation.name === Operations.PERCENTILE) { - const params = convertToPercentileParams(meta); - return params - ? { - operationType: aggregation.name, - sourceField: field.name, - ...createColumn(series, metric, field), - params, - } - : null; + return convertToPercentileColumn(meta, series, metric, dataView); } if (aggregation.name === Operations.PERCENTILE_RANK) { - const params = convertToPercentileRankParams(meta?.toString() ?? ''); - return params - ? { - operationType: aggregation.name, - sourceField: field.name, - ...createColumn(series, metric, field), - params, - } - : null; + return convertToPercentileRankColumn(meta?.toString() ?? '', series, metric, dataView); } if (aggregation.name === Operations.LAST_VALUE) { return null; } - return convertMetricAggregationColumnWithoutParams(aggregation.name, series, metric, dataView); + return convertMetricAggregationColumnWithoutParams(aggregation, series, metric, dataView); }; export const computeParentPipelineColumns = ( diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index cc77389477318..918ea14ee9b75 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -7,20 +7,16 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; -import { - Column, - Operations, - PercentileParams, -} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { Operations, PercentileParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Percentile, Series } from '../../../../common/types'; import { createColumn } from './column'; -import { CommonPercentileColumnWithMeta, PercentileColumnWithMeta } from './types'; +import { PercentileColumnWithExtendedMeta, PercentileColumn, Column } from './types'; export const isPercentileColumnWithMeta = ( - column: Column | CommonPercentileColumnWithMeta -): column is PercentileColumnWithMeta => + column: Column +): column is PercentileColumnWithExtendedMeta => column.operationType === Operations.PERCENTILE && - Boolean((column as CommonPercentileColumnWithMeta).meta); + Boolean((column as PercentileColumnWithExtendedMeta)?.meta?.reference); export const convertToPercentileParams = (value?: string | number): PercentileParams | null => value !== undefined && !isNaN(Number(value)) @@ -29,14 +25,14 @@ export const convertToPercentileParams = (value?: string | number): PercentilePa } : null; -const convertToPercentileColumn = ( - percentile: Percentile, +export const convertToPercentileColumn = ( + percentile: Percentile['value'], series: Series, metric: Metric, dataView: DataView, - index: number -): PercentileColumnWithMeta | null => { - const params = convertToPercentileParams(percentile.value); + index?: number +): PercentileColumn | null => { + const params = convertToPercentileParams(percentile); if (!params) { return null; } @@ -45,15 +41,19 @@ const convertToPercentileColumn = ( if (!field) { return null; } - + const commonColumnParams = createColumn(series, metric, field); return { operationType: 'percentile', sourceField: field.name, - ...createColumn(series, metric, field), + ...commonColumnParams, params, - meta: { - reference: `${metric.id}.${index}`, - }, + meta: + index !== undefined + ? { + reference: `${metric.id}.${index}`, + ...commonColumnParams.meta, + } + : commonColumnParams.meta, }; }; @@ -61,7 +61,7 @@ export const convertToPercentileColumns = ( series: Series, metric: Metric, dataView: DataView -): PercentileColumnWithMeta[] => { +): PercentileColumn[] => { const { percentiles } = metric; if (!percentiles) { @@ -69,6 +69,6 @@ export const convertToPercentileColumns = ( } return percentiles - .map((p, index) => convertToPercentileColumn(p, series, metric, dataView, index)) - .filter((p): p is PercentileColumnWithMeta => Boolean(p)); + .map((p, index) => convertToPercentileColumn(p.value, series, metric, dataView, index)) + .filter((p): p is PercentileColumn => Boolean(p)); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index 12b9018d4d1ba..5c87d9d4051fc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -8,19 +8,18 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { - Column, Operations, PercentileRanksParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; -import { CommonPercentileColumnWithMeta, PercentileRanksColumnWithMeta } from './types'; +import { PercentileRanksColumn, Column, PercentileRanksColumnWithExtendedMeta } from './types'; export const isPercentileRanksColumnWithMeta = ( - column: Column | CommonPercentileColumnWithMeta -): column is PercentileRanksColumnWithMeta => + column: Column +): column is PercentileRanksColumnWithExtendedMeta => column.operationType === Operations.PERCENTILE_RANK && - Boolean((column as CommonPercentileColumnWithMeta).meta); + Boolean((column as PercentileRanksColumnWithExtendedMeta).meta?.reference); export const convertToPercentileRankParams = (value: string): PercentileRanksParams | null => value !== undefined && !isNaN(Number(value)) @@ -29,13 +28,13 @@ export const convertToPercentileRankParams = (value: string): PercentileRanksPar } : null; -const convertToPercentileRankColumn = ( +export const convertToPercentileRankColumn = ( value: string, series: Series, metric: Metric, dataView: DataView, - index: number -): PercentileRanksColumnWithMeta | null => { + index?: number +): PercentileRanksColumn | null => { const params = convertToPercentileRankParams(value); if (!params) { return null; @@ -46,14 +45,19 @@ const convertToPercentileRankColumn = ( return null; } + const commonColumnParams = createColumn(series, metric, field); return { operationType: 'percentile_rank', sourceField: field.name, - ...createColumn(series, metric, field), + ...commonColumnParams, params, - meta: { - reference: `${metric.id}.${index}`, - }, + meta: + index !== undefined + ? { + reference: `${metric.id}.${index}`, + ...commonColumnParams.meta, + } + : commonColumnParams.meta, }; }; @@ -61,7 +65,7 @@ export const convertToPercentileRankColumns = ( series: Series, metric: Metric, dataView: DataView -): PercentileRanksColumnWithMeta[] => { +): PercentileRanksColumn[] => { const { values } = metric; if (!values) { @@ -70,5 +74,5 @@ export const convertToPercentileRankColumns = ( return values .map((p, index) => convertToPercentileRankColumn(p, series, metric, dataView, index)) - .filter((p): p is PercentileRanksColumnWithMeta => Boolean(p)); + .filter((p): p is PercentileRanksColumn => Boolean(p)); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index b109ca9a67892..c6e657d01acc4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -6,10 +6,8 @@ * Side Public License, v 1. */ -import { - StaticValueColumn, - StaticValueParams, -} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { StaticValueParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { StaticValueColumn } from './types'; import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts index 70a32b31e53cf..d8f6d34557619 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts @@ -7,17 +7,93 @@ */ import { - ColumnWithMeta, - PercentileColumn, - PercentileRanksColumn, + Layer as BaseLayer, + Column as BaseColumn, + ColumnWithMeta as GenericColumnWithMeta, + PercentileColumn as BasePercentileColumn, + PercentileRanksColumn as BasePercentileRanksColumn, + FiltersColumn, + TermsColumn, + RangeColumn as BaseRangeColumn, + DateHistogramColumn as BaseDateHistogramColumn, + MinColumn as BaseMinColumn, + MaxColumn as BaseMaxColumn, + AvgColumn as BaseAvgColumn, + SumColumn as BaseSumColumn, + MedianColumn as BaseMedianColumn, + StandardDeviationColumn as BaseStandardDeviationColumn, + CardinalityColumn as BaseCardinalityColumn, + CountColumn as BaseCountColumn, + LastValueColumn as BaseLastValueColumn, + CumulativeSumColumn as BaseCumulativeSumColumn, + CounterRateColumn as BaseCounterRateColumn, + DerivativeColumn as BaseDerivativeColumn, + MovingAverageColumn as BaseMovingAverageColumn, + FormulaColumn as BaseFormulaColumn, + StaticValueColumn as BaseStaticValueColumn, } from '@kbn/visualizations-plugin/common/convert_to_lens'; -export interface PercentileMeta { - reference: `${string}.${number}`; +export interface Meta { + metricId: string; } -export type PercentileColumnWithMeta = ColumnWithMeta; -export type PercentileRanksColumnWithMeta = ColumnWithMeta; -export type CommonPercentileColumnWithMeta = - | PercentileColumnWithMeta - | PercentileRanksColumnWithMeta; +export type PercentileMeta = { + reference: `${string}.${number}`; +} & Meta; + +export type PercentileColumnWithCommonMeta = GenericColumnWithMeta; +export type PercentileColumnWithExtendedMeta = GenericColumnWithMeta< + BasePercentileColumn, + PercentileMeta +>; +export type PercentileColumn = PercentileColumnWithCommonMeta | PercentileColumnWithExtendedMeta; + +export type PercentileRanksColumnWithCommonMeta = GenericColumnWithMeta< + BasePercentileRanksColumn, + Meta +>; +export type PercentileRanksColumnWithExtendedMeta = GenericColumnWithMeta< + BasePercentileRanksColumn, + PercentileMeta +>; + +export type PercentileRanksColumn = + | PercentileRanksColumnWithCommonMeta + | PercentileRanksColumnWithExtendedMeta; + +export type CommonPercentileColumnWithExtendedMeta = + | PercentileColumnWithExtendedMeta + | PercentileRanksColumnWithExtendedMeta; + +export type RangeColumn = GenericColumnWithMeta; +export type DateHistogramColumn = GenericColumnWithMeta; +export type MinColumn = GenericColumnWithMeta; +export type MaxColumn = GenericColumnWithMeta; +export type AvgColumn = GenericColumnWithMeta; +export type SumColumn = GenericColumnWithMeta; +export type MedianColumn = GenericColumnWithMeta; +export type StandardDeviationColumn = GenericColumnWithMeta; +export type CardinalityColumn = GenericColumnWithMeta; +export type CountColumn = GenericColumnWithMeta; +export type LastValueColumn = GenericColumnWithMeta; +export type CumulativeSumColumn = GenericColumnWithMeta; +export type CounterRateColumn = GenericColumnWithMeta; +export type DerivativeColumn = GenericColumnWithMeta; +export type MovingAverageColumn = GenericColumnWithMeta; +export type FormulaColumn = GenericColumnWithMeta; +export type StaticValueColumn = GenericColumnWithMeta; + +type ColumnsWithoutMeta = FiltersColumn | TermsColumn; + +type CommonColumns = Exclude; +export type ColumnWithMeta = + | GenericColumnWithMeta + | CommonPercentileColumnWithExtendedMeta; + +export type Column = ColumnWithMeta | ColumnsWithoutMeta; + +export { FiltersColumn, TermsColumn }; + +export type Layer = Omit & { + columns: Column[]; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 0c3f8c4e88234..977da92b374c5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -6,12 +6,12 @@ * Side Public License, v 1. */ -import { Column } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { Series } from '../../../../common/types'; import { getSeriesAgg } from './get_series_agg'; import { SUPPORTED_METRICS } from '../metrics'; import { + Column, convertMetricsToColumns, convertToPercentileColumns, convertToPercentileRankColumns, @@ -97,7 +97,7 @@ export const getMetricsColumns = ( } default: { const column = convertMetricAggregationColumnWithoutParams( - aggregation, + aggregationMap, series, metrics[metricIdx], dataView diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index e23cd1c8a9fd6..acf7e91912056 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -18,13 +18,38 @@ import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getMetricsColumns, getFiltersOrTermColumns } from '../lib/series'; import { getLayers, getYExtents } from '../lib/configurations/xy'; +import { Layer as ExtendedLayer, ColumnWithMeta, Column } from '../lib/convert'; + +const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { + if ((column as ColumnWithMeta).meta) { + return true; + } + return false; +}; + +const excludeMetaFromLayers = (layers: Record): Record => { + const newLayers: Record = {}; + Object.entries(layers).forEach(([layerId, layer]) => { + const columns = layer.columns.map((column) => { + if (isColumnWithMeta(column)) { + const { meta, ...rest } = column; + return rest; + } + return column; + }); + + newLayers[layerId] = { ...layer, columns }; + }); + + return newLayers; +}; export const convertToLens = async ( model: Panel ): Promise | null> => { const dataViews = getDataViewsStart(); const columns = []; - const layers: Record = {}; + const extendedLayers: Record = {}; const seriesNum = model.series.filter((series) => !series.hidden).length; // handle multiple layers/series @@ -46,27 +71,25 @@ export const convertToLens = async ( if (!metricsColumns) { return null; } - columns.push(...metricsColumns); const filtersOrTermColumns = getFiltersOrTermColumns(series); if (filtersOrTermColumns === null) { return null; } - columns.push(...filtersOrTermColumns); const layerId = uuid(); - layers[layerIdx] = { indexPatternId, layerId, columns, columnOrder: [] }; // TODO: update later. + extendedLayers[layerIdx] = { indexPatternId, layerId, columns, columnOrder: [] }; // TODO: update later. } const extents = getYExtents(model); return { - layers, type: 'lnsXY', + layers: excludeMetaFromLayers(extendedLayers), configuration: { - layers: getLayers(layers, model), + layers: getLayers(extendedLayers, model), fillOpacity: Number(model.series[0].fill) ?? 0.3, legend: { isVisible: Boolean(model.show_legend), diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index 20631171a1d1d..d1e407170b70f 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -57,7 +57,7 @@ export interface ColumnWithReferences; +export type FiltersColumn = BaseColumn<'filters', FiltersParams>; export type RangeColumn = ColumnWithSourceField<'range', RangeParams>; export type TermsColumn = ColumnWithSourceField<'terms', TermsParams>; export type DateHistogramColumn = ColumnWithSourceField<'date_histogram', DateHistogramParams>; @@ -75,6 +75,7 @@ export type PercentileColumn = ColumnWithSourceField<'percentile', PercentilePar export type PercentileRanksColumn = ColumnWithSourceField<'percentile_rank', PercentileRanksParams>; export type CountColumn = ColumnWithSourceField<'count', CountParams>; export type LastValueColumn = ColumnWithSourceField<'last_value', LastValueParams>; + export type CumulativeSumColumn = ColumnWithReferences<'cumulative_sum', CumulativeSumParams>; export type CounterRateColumn = ColumnWithReferences<'counter_rate', CounterRateParams>; export type DerivativeColumn = ColumnWithReferences<'differences', DerivativeParams>; @@ -83,7 +84,7 @@ export type FormulaColumn = ColumnWithReferences<'formula', FormulaParams>; export type StaticValueColumn = ColumnWithReferences<'static_value', StaticValueParams>; export type AnyColumnWithSourceField = - | FitlersColumn + | FiltersColumn | RangeColumn | TermsColumn | DateHistogramColumn @@ -109,5 +110,5 @@ export type AnyColumnWithReferences = export type Column = AnyColumnWithReferences | AnyColumnWithSourceField; -export type ColumnWithMeta = Col & +export type ColumnWithMeta = Col & (Meta extends undefined ? undefined : { meta: Meta }); diff --git a/src/plugins/visualizations/public/vis_types/types.ts b/src/plugins/visualizations/public/vis_types/types.ts index 4267e6a0d8aef..cdc0ac3518f5e 100644 --- a/src/plugins/visualizations/public/vis_types/types.ts +++ b/src/plugins/visualizations/public/vis_types/types.ts @@ -135,8 +135,8 @@ export interface NavigateToLensContext { yRight: boolean; }; extents: { - yLeftExtent: AxisExtents; - yRightExtent: AxisExtents; + yLeftExtent?: AxisExtents; + yRightExtent?: AxisExtents; }; }; } From 0da77f16834e9f013992e4174e07b8110867fd03 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 22 Aug 2022 13:27:55 +0300 Subject: [PATCH 027/129] Fixed problem with columns. --- .../public/convert_to_lens/timeseries/new.index.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index acf7e91912056..7f6cf4f1b137f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -48,7 +48,6 @@ export const convertToLens = async ( model: Panel ): Promise | null> => { const dataViews = getDataViewsStart(); - const columns = []; const extendedLayers: Record = {}; const seriesNum = model.series.filter((series) => !series.hidden).length; @@ -71,16 +70,19 @@ export const convertToLens = async ( if (!metricsColumns) { return null; } - columns.push(...metricsColumns); const filtersOrTermColumns = getFiltersOrTermColumns(series); if (filtersOrTermColumns === null) { return null; } - columns.push(...filtersOrTermColumns); const layerId = uuid(); - extendedLayers[layerIdx] = { indexPatternId, layerId, columns, columnOrder: [] }; // TODO: update later. + extendedLayers[layerIdx] = { + indexPatternId, + layerId, + columns: [...metricsColumns, ...filtersOrTermColumns], + columnOrder: [], + }; // TODO: update later. } const extents = getYExtents(model); From fcdcb41821c586a77277a1347305b0b9fccf608d Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 22 Aug 2022 13:54:03 +0300 Subject: [PATCH 028/129] Added date_histogram column, fixed layer configuration --- .../lib/configurations/xy/layers.ts | 18 +++++- .../lib/convert/date_histogram.ts | 57 +++++++++++++++++++ .../convert_to_lens/lib/convert/index.ts | 1 + .../convert_to_lens/lib/convert/types.ts | 11 ++-- .../lib/series/split_columns.ts | 51 ++++++++++++++++- .../convert_to_lens/timeseries/new.index.ts | 29 ++++++++-- .../convert_to_lens/types/configurations.ts | 14 +++-- 7 files changed, 160 insertions(+), 21 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts index b2ca9b7590b75..0f411cc9d8fe6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.ts @@ -7,7 +7,7 @@ */ import { - FillType, + FillTypes, XYLayerConfig, YAxisMode, } from '@kbn/visualizations-plugin/common/convert_to_lens'; @@ -20,9 +20,13 @@ import { isPercentileColumnWithMeta, Column, Layer, + AnyColumnWithReferences, } from '../../convert'; import { getChartType } from './chart_type'; +export const isColumnWithReference = (column: Column): column is AnyColumnWithReferences => + Boolean((column as AnyColumnWithReferences).references); + function getPalette(palette: PaletteOutput): PaletteOutput { return !palette || palette.name === 'gradient' || palette.name === 'rainbow' ? { name: 'default', type: 'palette' } @@ -55,7 +59,15 @@ export const getLayers = ( const series = model.series[parseInt(key, 10)]; const { metrics, seriesAgg } = getSeriesAgg(series.metrics); const dataSourceLayer = dataSourceLayers[parseInt(key, 10)]; - const metricColumns = dataSourceLayer.columns.filter((l) => !l.isBucketed); + const referenceColumn = dataSourceLayer.columns.find( + (column): column is AnyColumnWithReferences => isColumnWithReference(column) + ); + // as pipiline aggregation has only one reference id + const referenceColumnId = referenceColumn?.references[0]; + // we should not include columns which using as reference for pipeline aggs + const metricColumns = dataSourceLayer.columns.filter( + (l) => !l.isBucketed && l.columnId !== referenceColumnId + ); const isReferenceLine = metrics.length === 1 && metrics[0].type === 'static'; const splitAccessor = dataSourceLayer.columns.find( (column) => column.isBucketed && column.isSplit @@ -78,7 +90,7 @@ export const getLayers = ( ? series.axis_position : model.axis_position) as YAxisMode, ...(isReferenceLine && { - fill: (chartType === 'area' ? 'below' : 'none') as FillType, + fill: chartType === 'area' ? FillTypes.BELOW : FillTypes.NONE, }), }; }), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts new file mode 100644 index 0000000000000..1793f936fee72 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts @@ -0,0 +1,57 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import uuid from 'uuid'; +import { DateHistogramParams, DataType } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { DateHistogramColumn } from './types'; +import type { Panel, Series } from '../../../../common/types'; + +export const convertToDateHistogramParams = (model: Panel, series: Series): DateHistogramParams => { + return { + interval: model.interval && !model.interval?.includes('=') ? model.interval : 'auto', + dropPartials: series.override_index_pattern + ? series.series_drop_last_bucket > 0 + : model.drop_last_bucket > 0, + includeEmptyRows: true, + }; +}; + +export const convertToDateHistogramColumn = ( + model: Panel, + series: Series, + dataView: DataView, + fieldName: string, + isSplit: boolean +): DateHistogramColumn | null => { + const params = convertToDateHistogramParams(model, series); + + const dateField = dataView.getFieldByName(fieldName); + + if (!dateField) { + return null; + } + + return { + columnId: uuid(), + operationType: 'date_histogram', + dataType: dateField.type as DataType, + isBucketed: true, + isSplit, + sourceField: dateField.name, + params, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index d03d8b4a8f749..b066661328b41 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -19,4 +19,5 @@ export { convertFilterRatioToFormulaColumn } from './filter_ratio'; export { convertToLastValueColumn } from './last_value'; export { convertToStaticValueColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; +export { convertToDateHistogramColumn } from './date_histogram'; export * from './types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts index d8f6d34557619..350c87f7cdffd 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts @@ -15,7 +15,7 @@ import { FiltersColumn, TermsColumn, RangeColumn as BaseRangeColumn, - DateHistogramColumn as BaseDateHistogramColumn, + DateHistogramColumn, MinColumn as BaseMinColumn, MaxColumn as BaseMaxColumn, AvgColumn as BaseAvgColumn, @@ -31,6 +31,7 @@ import { MovingAverageColumn as BaseMovingAverageColumn, FormulaColumn as BaseFormulaColumn, StaticValueColumn as BaseStaticValueColumn, + AnyColumnWithReferences as BaseAnyColumnWithReferences, } from '@kbn/visualizations-plugin/common/convert_to_lens'; export interface Meta { @@ -66,7 +67,6 @@ export type CommonPercentileColumnWithExtendedMeta = | PercentileRanksColumnWithExtendedMeta; export type RangeColumn = GenericColumnWithMeta; -export type DateHistogramColumn = GenericColumnWithMeta; export type MinColumn = GenericColumnWithMeta; export type MaxColumn = GenericColumnWithMeta; export type AvgColumn = GenericColumnWithMeta; @@ -83,7 +83,8 @@ export type MovingAverageColumn = GenericColumnWithMeta; export type StaticValueColumn = GenericColumnWithMeta; -type ColumnsWithoutMeta = FiltersColumn | TermsColumn; +type ColumnsWithoutMeta = FiltersColumn | TermsColumn | DateHistogramColumn; +export type AnyColumnWithReferences = GenericColumnWithMeta; type CommonColumns = Exclude; export type ColumnWithMeta = @@ -92,8 +93,8 @@ export type ColumnWithMeta = export type Column = ColumnWithMeta | ColumnsWithoutMeta; -export { FiltersColumn, TermsColumn }; - export type Layer = Omit & { columns: Column[]; }; + +export { FiltersColumn, TermsColumn, DateHistogramColumn }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts index 4ad60a144cc5d..ef0d720774a80 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts @@ -6,10 +6,35 @@ * Side Public License, v 1. */ -import { Series } from '../../../../common/types'; -import { convertToFiltersColumn } from '../convert'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { Series, Panel } from '../../../../common/types'; +import { getFieldsForTerms } from '../../../../common/fields_utils'; +import { convertToFiltersColumn, convertToDateHistogramColumn } from '../convert'; -export const getFiltersOrTermColumns = (series: Series) => { +export const isSplitWithDateHistogram = ( + series: Series, + splitFields: string[], + dataView: DataView +) => { + let splitWithDateHistogram = false; + if (series.terms_field && series.split_mode === 'terms' && splitFields) { + for (const f of splitFields) { + const fieldType = dataView.getFieldByName(f)?.type; + + if (fieldType === 'date') { + if (splitFields.length === 1) { + splitWithDateHistogram = true; + } else { + // not supported terms with several field if one of them has date type + return null; + } + } + } + } + return splitWithDateHistogram; +}; + +export const getSplitColumns = (model: Panel, series: Series, dataView: DataView) => { if (series.split_mode === 'filters' || series.split_mode === 'filter') { const filterColumn = convertToFiltersColumn(series, true); if (!filterColumn) { @@ -17,5 +42,25 @@ export const getFiltersOrTermColumns = (series: Series) => { } return [filterColumn]; } + if (series.split_mode === 'terms') { + const splitFields = getFieldsForTerms(series.terms_field); + const isDateHistogram = isSplitWithDateHistogram(series, splitFields, dataView); + if (isDateHistogram === null) { + return null; + } + if (isDateHistogram) { + const dateHistogramColumn = convertToDateHistogramColumn( + model, + series, + dataView, + splitFields[0], + true + ); + if (!dateHistogramColumn) { + return null; + } + return [dateHistogramColumn]; + } + } return []; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 7f6cf4f1b137f..6e74756ff2678 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -16,9 +16,14 @@ import uuid from 'uuid'; import { Panel } from '../../../common/types'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; -import { getMetricsColumns, getFiltersOrTermColumns } from '../lib/series'; +import { getMetricsColumns, getSplitColumns } from '../lib/series'; import { getLayers, getYExtents } from '../lib/configurations/xy'; -import { Layer as ExtendedLayer, ColumnWithMeta, Column } from '../lib/convert'; +import { + Layer as ExtendedLayer, + ColumnWithMeta, + Column, + convertToDateHistogramColumn, +} from '../lib/convert'; const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { if ((column as ColumnWithMeta).meta) { @@ -57,7 +62,7 @@ export const convertToLens = async ( continue; } - const { indexPatternId, indexPattern } = await getDataSourceInfo( + const { indexPatternId, indexPattern, timeField } = await getDataSourceInfo( model.index_pattern, model.time_field, Boolean(series.override_index_pattern), @@ -65,13 +70,27 @@ export const convertToLens = async ( dataViews ); + if (!timeField) { + return null; + } + + const dateHistogramColumn = convertToDateHistogramColumn( + model, + series, + indexPattern!, + timeField, + false + ); + if (dateHistogramColumn === null) { + return null; + } // handle multiple metrics const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum); if (!metricsColumns) { return null; } - const filtersOrTermColumns = getFiltersOrTermColumns(series); + const filtersOrTermColumns = getSplitColumns(model, series, indexPattern!); if (filtersOrTermColumns === null) { return null; } @@ -80,7 +99,7 @@ export const convertToLens = async ( extendedLayers[layerIdx] = { indexPatternId, layerId, - columns: [...metricsColumns, ...filtersOrTermColumns], + columns: [...metricsColumns, dateHistogramColumn, ...filtersOrTermColumns], columnOrder: [], }; // TODO: update later. } diff --git a/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts b/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts index a7176f3d1fe44..b908ee2c5346b 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts @@ -17,8 +17,6 @@ export const XYCurveTypes = { CURVE_STEP_AFTER: 'CURVE_STEP_AFTER', } as const; -export type XYCurveType = $Values; - export const YAxisModes = { AUTO: 'auto', LEFT: 'left', @@ -26,8 +24,6 @@ export const YAxisModes = { BOTTOM: 'bottom', } as const; -export type YAxisMode = $Values; - export const SeriesTypes = { BAR: 'bar', LINE: 'line', @@ -41,8 +37,16 @@ export const SeriesTypes = { BAR_HORIZONTAL_PERCENTAGE_STACKED: 'bar_horizontal_percentage_stacked', } as const; -export type FillType = 'none' | 'above' | 'below'; +export const FillTypes = { + NONE: 'none', + ABOVE: 'above', + BELOW: 'below', +} as const; + +export type FillType = $Values; export type SeriesType = $Values; +export type YAxisMode = $Values; +export type XYCurveType = $Values; export interface AxisExtentConfig { mode: 'full' | 'custom' | 'dataBounds'; From bfd1dff43c15ee52ec98445abaf9ae0c8b8b86af Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 22 Aug 2022 17:01:52 +0300 Subject: [PATCH 029/129] Added terms support. --- .../convert_to_lens/lib/convert/column.ts | 21 +++- .../convert_to_lens/lib/convert/index.ts | 4 +- .../convert_to_lens/lib/convert/terms.ts | 116 ++++++++++++++++++ .../convert_to_lens/lib/series/columns.ts | 27 ++++ .../lib/series/metrics_columns.ts | 19 +-- .../lib/series/split_columns.ts | 18 ++- .../convert_to_lens/timeseries/new.index.ts | 21 +--- 7 files changed, 184 insertions(+), 42 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 1803ae3e0ff96..5e28795f0c512 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -11,16 +11,16 @@ import { Operation, DataType, Column, - ColumnWithMeta, + ColumnWithMeta as GenericColumnWithMeta, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; import { ConvertToColumnsFn } from '../../types'; import { getTimeScale } from '../metrics'; -import { Meta } from './types'; +import { ColumnWithMeta, Meta } from './types'; type GeneralColumn = Omit, 'operationType' | 'params'>; -type GeneralColumnWithMeta = ColumnWithMeta; +type GeneralColumnWithMeta = GenericColumnWithMeta; export const createColumn = ( series: Series, @@ -46,3 +46,18 @@ export const convertMetricsToColumns = ( dataView: DataView, convertToFn: ConvertToColumnsFn ) => metrics.flatMap((metric) => convertToFn(series, metric, dataView)); + +export const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { + if ((column as ColumnWithMeta).meta) { + return true; + } + return false; +}; + +export const excludeMetaFromColumn = (column: Column) => { + if (isColumnWithMeta(column)) { + const { meta, ...rest } = column; + return rest; + } + return column; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index b066661328b41..ca197a80950d7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -export { convertMetricsToColumns } from './column'; +export { convertMetricsToColumns, isColumnWithMeta, excludeMetaFromColumn } from './column'; export { convertToPercentileColumns, isPercentileColumnWithMeta } from './percentile'; export { convertToPercentileRankColumns, isPercentileRanksColumnWithMeta } from './percentile_rank'; export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './formula'; @@ -20,4 +20,6 @@ export { convertToLastValueColumn } from './last_value'; export { convertToStaticValueColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; export { convertToDateHistogramColumn } from './date_histogram'; +export { converToTermsColumns } from './terms'; + export * from './types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts new file mode 100644 index 0000000000000..6e0c480d49654 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts @@ -0,0 +1,116 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import { DataType, TermsParams } from '@kbn/visualizations-plugin/common'; +import uuid from 'uuid'; +import { Series } from '../../../../common/types'; +import { excludeMetaFromColumn, isColumnWithMeta } from './column'; +import { Column, TermsColumn } from './types'; + +interface OrderByWithAgg { + orderAgg?: TermsParams['orderAgg']; + orderBy: TermsParams['orderBy']; +} + +const getOrderByWithAgg = (series: Series, columns: Column[]): OrderByWithAgg | null => { + if (series.terms_order_by === '_key') { + return { orderBy: { type: 'alphabetical' } }; + } + + if (series.terms_order_by === '_count') { + const columnId = uuid(); + return { + orderBy: { type: 'column', columnId }, + orderAgg: { + operationType: 'count', + sourceField: 'document', + columnId, + isBucketed: true, + isSplit: true, + dataType: 'number', + params: {}, + }, + }; + } + + const orderAgg = columns.find((column) => { + if (isColumnWithMeta(column)) { + return column.meta.metricId === series.terms_order_by; + } + return false; + }); + + if (!orderAgg) { + return null; + } + + return { + orderBy: { type: 'column', columnId: orderAgg.columnId }, + orderAgg: excludeMetaFromColumn(orderAgg), + }; +}; + +export const convertToTermsParams = (series: Series, columns: Column[]): TermsParams | null => { + const orderDirection: TermsParams['orderDirection'] = + series.terms_direction === 'asc' ? 'asc' : 'desc'; + + const orderByWithAgg = getOrderByWithAgg(series, columns); + if (orderByWithAgg === null) { + return null; + } + + return { + size: series.terms_size ? Number(series.terms_size) : 10, + ...(series.terms_include && { include: [series.terms_include] }), + includeIsRegex: Boolean(series.terms_include), + ...(series.terms_exclude && { exclude: [series.terms_exclude] }), + excludeIsRegex: Boolean(series.terms_exclude), + otherBucket: false, + orderDirection, + parentFormat: { id: 'terms' }, + ...orderByWithAgg, + }; +}; + +export const converToTermsColumn = ( + termField: string, + series: Series, + columns: Column[], + dataView: DataView +): TermsColumn | null => { + const field = dataView.getFieldByName(termField); + + if (!field) { + return null; + } + + const params = convertToTermsParams(series, columns); + if (!params) { + return params; + } + + return { + columnId: uuid(), + operationType: 'terms', + dataType: (field.type as DataType) ?? undefined, + sourceField: field.name, + isBucketed: true, + isSplit: true, + params, + }; +}; + +export const converToTermsColumns = ( + termFields: string[], + series: Series, + columns: Column[], + dataView: DataView +): Array => { + return termFields.map((field) => converToTermsColumn(field, series, columns, dataView)); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.ts new file mode 100644 index 0000000000000..d9f455103f1e8 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.ts @@ -0,0 +1,27 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Column } from '../convert'; + +type UnwrapArray = T extends Array ? P : T; + +export const getValidColumns = (columns: Array | Column | null | undefined) => { + if (columns && Array.isArray(columns)) { + const nonNullColumns = columns.filter( + (c): c is Exclude, null> => c !== null + ); + + if (nonNullColumns.length !== columns.length) { + return null; + } + + return nonNullColumns; + } + + return columns ? [columns] : null; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 977da92b374c5..2f3461b2dcd62 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -24,24 +24,7 @@ import { convertToStaticValueColumn, convertMetricAggregationColumnWithoutParams, } from '../convert'; - -type UnwrapArray = T extends Array ? P : T; - -const getValidColumns = (columns: Array | Column | null | undefined) => { - if (columns && Array.isArray(columns)) { - const nonNullColumns = columns.filter( - (c): c is Exclude, null> => c !== null - ); - - if (nonNullColumns.length !== columns.length) { - return null; - } - - return nonNullColumns; - } - - return columns ? [columns] : null; -}; +import { getValidColumns } from './columns'; export const getMetricsColumns = ( series: Series, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts index ef0d720774a80..e82eb0a40cc46 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts @@ -9,7 +9,13 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { Series, Panel } from '../../../../common/types'; import { getFieldsForTerms } from '../../../../common/fields_utils'; -import { convertToFiltersColumn, convertToDateHistogramColumn } from '../convert'; +import { + Column, + convertToFiltersColumn, + convertToDateHistogramColumn, + converToTermsColumns, +} from '../convert'; +import { getValidColumns } from './columns'; export const isSplitWithDateHistogram = ( series: Series, @@ -34,7 +40,12 @@ export const isSplitWithDateHistogram = ( return splitWithDateHistogram; }; -export const getSplitColumns = (model: Panel, series: Series, dataView: DataView) => { +export const getSplitColumns = ( + model: Panel, + series: Series, + columns: Column[], + dataView: DataView +) => { if (series.split_mode === 'filters' || series.split_mode === 'filter') { const filterColumn = convertToFiltersColumn(series, true); if (!filterColumn) { @@ -61,6 +72,9 @@ export const getSplitColumns = (model: Panel, series: Series, dataView: DataView } return [dateHistogramColumn]; } + + const termsColumns = converToTermsColumns(splitFields, series, columns, dataView); + return getValidColumns(termsColumns); } return []; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 6e74756ff2678..5c61169f61687 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -20,29 +20,14 @@ import { getMetricsColumns, getSplitColumns } from '../lib/series'; import { getLayers, getYExtents } from '../lib/configurations/xy'; import { Layer as ExtendedLayer, - ColumnWithMeta, - Column, convertToDateHistogramColumn, + excludeMetaFromColumn, } from '../lib/convert'; -const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { - if ((column as ColumnWithMeta).meta) { - return true; - } - return false; -}; - const excludeMetaFromLayers = (layers: Record): Record => { const newLayers: Record = {}; Object.entries(layers).forEach(([layerId, layer]) => { - const columns = layer.columns.map((column) => { - if (isColumnWithMeta(column)) { - const { meta, ...rest } = column; - return rest; - } - return column; - }); - + const columns = layer.columns.map(excludeMetaFromColumn); newLayers[layerId] = { ...layer, columns }; }); @@ -90,7 +75,7 @@ export const convertToLens = async ( return null; } - const filtersOrTermColumns = getSplitColumns(model, series, indexPattern!); + const filtersOrTermColumns = getSplitColumns(model, series, metricsColumns, indexPattern!); if (filtersOrTermColumns === null) { return null; } From 8f4c8d57e42eb6ac1f3134ab1f0a3a53b156ae8b Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 22 Aug 2022 17:12:41 +0300 Subject: [PATCH 030/129] Refactored. --- .../public/convert_to_lens/lib/convert/terms.ts | 12 +++++++----- .../series/{split_columns.ts => buckets_columns.ts} | 7 ++++--- .../public/convert_to_lens/lib/series/index.ts | 2 +- .../public/convert_to_lens/timeseries/new.index.ts | 10 +++++----- 4 files changed, 17 insertions(+), 14 deletions(-) rename src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/{split_columns.ts => buckets_columns.ts} (95%) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts index 6e0c480d49654..4db8211bba35d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts @@ -32,7 +32,7 @@ const getOrderByWithAgg = (series: Series, columns: Column[]): OrderByWithAgg | sourceField: 'document', columnId, isBucketed: true, - isSplit: true, + isSplit: false, dataType: 'number', params: {}, }, @@ -82,7 +82,8 @@ export const converToTermsColumn = ( termField: string, series: Series, columns: Column[], - dataView: DataView + dataView: DataView, + isSplit: boolean = false ): TermsColumn | null => { const field = dataView.getFieldByName(termField); @@ -101,7 +102,7 @@ export const converToTermsColumn = ( dataType: (field.type as DataType) ?? undefined, sourceField: field.name, isBucketed: true, - isSplit: true, + isSplit, params, }; }; @@ -110,7 +111,8 @@ export const converToTermsColumns = ( termFields: string[], series: Series, columns: Column[], - dataView: DataView + dataView: DataView, + isSplit: boolean = false ): Array => { - return termFields.map((field) => converToTermsColumn(field, series, columns, dataView)); + return termFields.map((field) => converToTermsColumn(field, series, columns, dataView, isSplit)); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts similarity index 95% rename from src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts rename to src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index e82eb0a40cc46..181fab2b1ae8e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/split_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -40,11 +40,12 @@ export const isSplitWithDateHistogram = ( return splitWithDateHistogram; }; -export const getSplitColumns = ( +export const getBucketColumns = ( model: Panel, series: Series, columns: Column[], - dataView: DataView + dataView: DataView, + isSplit: boolean = false ) => { if (series.split_mode === 'filters' || series.split_mode === 'filter') { const filterColumn = convertToFiltersColumn(series, true); @@ -73,7 +74,7 @@ export const getSplitColumns = ( return [dateHistogramColumn]; } - const termsColumns = converToTermsColumns(splitFields, series, columns, dataView); + const termsColumns = converToTermsColumns(splitFields, series, columns, dataView, isSplit); return getValidColumns(termsColumns); } return []; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts index b02865d24257d..c10fa1846eadb 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts @@ -9,4 +9,4 @@ export * from './get_series'; export * from './get_series_agg'; export * from './metrics_columns'; -export * from './split_columns'; +export * from './buckets_columns'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 5c61169f61687..87a1696e280a3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -16,7 +16,7 @@ import uuid from 'uuid'; import { Panel } from '../../../common/types'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; -import { getMetricsColumns, getSplitColumns } from '../lib/series'; +import { getMetricsColumns, getBucketColumns } from '../lib/series'; import { getLayers, getYExtents } from '../lib/configurations/xy'; import { Layer as ExtendedLayer, @@ -75,8 +75,8 @@ export const convertToLens = async ( return null; } - const filtersOrTermColumns = getSplitColumns(model, series, metricsColumns, indexPattern!); - if (filtersOrTermColumns === null) { + const bucketsColumns = getBucketColumns(model, series, metricsColumns, indexPattern!, true); + if (bucketsColumns === null) { return null; } @@ -84,9 +84,9 @@ export const convertToLens = async ( extendedLayers[layerIdx] = { indexPatternId, layerId, - columns: [...metricsColumns, dateHistogramColumn, ...filtersOrTermColumns], + columns: [...metricsColumns, dateHistogramColumn, ...bucketsColumns], columnOrder: [], - }; // TODO: update later. + }; } const extents = getYExtents(model); From a21b64e423fca6c1130ef9fddf9a89601a6e5665 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 22 Aug 2022 17:13:17 +0300 Subject: [PATCH 031/129] Refactored for consistancy. --- .../public/convert_to_lens/lib/series/buckets_columns.ts | 2 +- .../timeseries/public/convert_to_lens/timeseries/new.index.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index 181fab2b1ae8e..aa7a58f1fd9e1 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -40,7 +40,7 @@ export const isSplitWithDateHistogram = ( return splitWithDateHistogram; }; -export const getBucketColumns = ( +export const getBucketsColumns = ( model: Panel, series: Series, columns: Column[], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 87a1696e280a3..748e57a887e6b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -16,7 +16,7 @@ import uuid from 'uuid'; import { Panel } from '../../../common/types'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; -import { getMetricsColumns, getBucketColumns } from '../lib/series'; +import { getMetricsColumns, getBucketsColumns } from '../lib/series'; import { getLayers, getYExtents } from '../lib/configurations/xy'; import { Layer as ExtendedLayer, @@ -75,7 +75,7 @@ export const convertToLens = async ( return null; } - const bucketsColumns = getBucketColumns(model, series, metricsColumns, indexPattern!, true); + const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, true); if (bucketsColumns === null) { return null; } From 6b0f939959a0e9eb57788d924e67e7cef2cbaef9 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 22 Aug 2022 18:36:25 +0300 Subject: [PATCH 032/129] Removed `getVisualizationSuggestionFromContext` fn. --- .../editor_frame/suggestion_helpers.ts | 13 ++- x-pack/plugins/lens/public/types.ts | 12 --- .../visualizations/xy/visualization.tsx | 93 +------------------ 3 files changed, 10 insertions(+), 108 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts index 5daa15fd90eb4..19bc353b65dc5 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts @@ -199,10 +199,15 @@ export function getVisualizeFieldSuggestions({ const allSuggestions = suggestions.filter( (s) => s.visualizationId === visualizeTriggerFieldContext.type ); - return activeVisualization?.getVisualizationSuggestionFromContext?.({ - suggestions: allSuggestions, - context: visualizeTriggerFieldContext, - }); + return { + ...allSuggestions[0], + visualizationState: { + ...(typeof allSuggestions[0].visualizationState === 'object' + ? allSuggestions[0].visualizationState + : {}), + ...visualizeTriggerFieldContext.configuration, + }, + }; } if (suggestions.length) { diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 0a76ceec5d315..9816a9b8cce42 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -979,19 +979,7 @@ export interface Visualization { dropType: DropType; group?: VisualizationDimensionGroupConfig; }) => T; - /** - * Update the configuration for the visualization. This is used to update the state - */ - updateLayersConfigurationFromContext?: ( - props: VisualizationConfigurationFromContextChangeProps - ) => T; - /** - * Update the visualization state from the context. - */ - getVisualizationSuggestionFromContext?: ( - props: VisualizationStateFromContextChangeProps - ) => Suggestion; /** * Additional editor that gets rendered inside the dimension popover. * This can be used to configure dimension-specific options diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index e0d0a19cebec8..c9f35b3d1e752 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -16,7 +16,6 @@ import { CoreStart, ThemeServiceStart } from '@kbn/core/public'; import { EventAnnotationServiceType } from '@kbn/event-annotation-plugin/public'; import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; -import { FillStyle } from '@kbn/expression-xy-plugin/common'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { getSuggestions } from './xy_suggestions'; @@ -24,16 +23,7 @@ import { XyToolbar } from './xy_config_panel'; import { DimensionEditor } from './xy_config_panel/dimension_editor'; import { LayerHeader } from './xy_config_panel/layer_header'; import type { Visualization, AccessorConfig, FramePublicAPI } from '../../types'; -import { - State, - visualizationTypes, - XYSuggestion, - XYLayerConfig, - XYDataLayerConfig, - YConfig, - YAxisMode, - SeriesType, -} from './types'; +import { State, visualizationTypes, XYLayerConfig, XYDataLayerConfig, SeriesType } from './types'; import { layerTypes } from '../../../common'; import { isHorizontalChart } from './state_helpers'; import { toExpression, toPreviewExpression, getSortedAccessors } from './to_expression'; @@ -378,87 +368,6 @@ export const getXyVisualization = ({ }; }, - updateLayersConfigurationFromContext({ prevState, layerId, context }) { - const { chartType, axisPosition, palette, metrics, collapseFn } = context; - const foundLayer = prevState?.layers.find((l) => l.layerId === layerId); - if (!foundLayer || !isDataLayer(foundLayer)) { - return prevState; - } - const isReferenceLine = metrics.some((metric) => metric.agg === 'static_value'); - const axisMode = axisPosition as YAxisMode; - const yConfig = metrics.map((metric, idx) => { - return { - color: metric.color, - forAccessor: metric.accessor ?? foundLayer.accessors[idx], - ...(axisMode && { axisMode }), - ...(isReferenceLine && { fill: chartType === 'area' ? 'below' : ('none' as FillStyle) }), - }; - }); - const newLayer = { - ...foundLayer, - ...(chartType && { seriesType: chartType as SeriesType }), - ...(palette && { palette }), - collapseFn, - yConfig, - layerType: isReferenceLine ? layerTypes.REFERENCELINE : layerTypes.DATA, - } as XYLayerConfig; - - const newLayers = prevState.layers.map((l) => (l.layerId === layerId ? newLayer : l)); - - return { - ...prevState, - layers: newLayers, - }; - }, - - getVisualizationSuggestionFromContext({ suggestions, context }) { - const visualizationStateLayers = []; - let datasourceStateLayers = {}; - const fillOpacity = context.configuration.fill ? Number(context.configuration.fill) : undefined; - for (let suggestionIdx = 0; suggestionIdx < suggestions.length; suggestionIdx++) { - const currentSuggestion = suggestions[suggestionIdx] as XYSuggestion; - const currentSuggestionsLayers = currentSuggestion.visualizationState.layers; - const contextLayer = context.layers.find( - (layer) => layer.layerId === Object.keys(currentSuggestion.datasourceState.layers)[0] - ); - if (this.updateLayersConfigurationFromContext && contextLayer) { - const updatedSuggestionState = this.updateLayersConfigurationFromContext({ - prevState: currentSuggestion.visualizationState as unknown as State, - layerId: currentSuggestionsLayers[0].layerId as string, - context: contextLayer, - }); - - visualizationStateLayers.push(...updatedSuggestionState.layers); - datasourceStateLayers = { - ...datasourceStateLayers, - ...currentSuggestion.datasourceState.layers, - }; - } - } - let suggestion = suggestions[0] as XYSuggestion; - suggestion = { - ...suggestion, - datasourceState: { - ...suggestion.datasourceState, - layers: { - ...suggestion.datasourceState.layers, - ...datasourceStateLayers, - }, - }, - visualizationState: { - ...suggestion.visualizationState, - fillOpacity, - yRightExtent: context.configuration.extents?.yRightExtent, - yLeftExtent: context.configuration.extents?.yLeftExtent, - legend: context.configuration.legend, - gridlinesVisibilitySettings: context.configuration.gridLinesVisibility, - valuesInLegend: true, - layers: visualizationStateLayers, - }, - }; - return suggestion; - }, - removeDimension({ prevState, layerId, columnId, frame }) { const foundLayer = prevState.layers.find((l) => l.layerId === layerId); if (!foundLayer) { From a36fabcbb7cdbbad550868813e42659174807458 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 13:01:20 +0300 Subject: [PATCH 033/129] Added references. --- .../operations/layer_helpers.ts | 255 +++++++++++++----- 1 file changed, 186 insertions(+), 69 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 3d079584e32f9..f78b672311e6d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -66,6 +66,7 @@ interface ColumnChange { incompleteFieldOperation?: OperationType; columnParams?: Record; initialParams?: { params: Record }; // TODO: bind this to the op parameter + references?: ColumnChange[]; } interface ColumnCopy { @@ -174,6 +175,166 @@ function ensureCompatibleParamsAreMoved( return newColumn; } +const insertReferences = ({ + layer, + references, + requiredReferences, + indexPattern, + visualizationGroups, + targetGroup, +}: { + layer: IndexPatternLayer; + references: ColumnChange[]; + requiredReferences: RequiredReference[]; + indexPattern: IndexPattern; + visualizationGroups: VisualizationDimensionGroupConfig[]; + targetGroup?: string; +}) => { + references.forEach((reference) => { + const validOperations = requiredReferences.filter((validation) => + isOperationAllowedAsReference({ validation, operationType: reference.op, indexPattern }) + ); + + if (!validOperations.length) { + throw new Error( + `Can't create reference, ${reference.op} has a validation function which doesn't allow any operations` + ); + } + }); + + const referenceIds: string[] = []; + references.forEach((reference) => { + const operation = operationDefinitionMap[reference.op]; + + if (operation.input === 'none') { + layer = insertNewColumn({ + layer, + columnId: reference.columnId, + op: operation.type, + indexPattern, + columnParams: { ...reference.columnParams }, + ...(reference.references ? { references: reference.references } : {}), + visualizationGroups, + targetGroup, + }); + + referenceIds.push(reference.columnId); + return; + } + const field = + operation.input === 'field' + ? indexPattern.fields.find((f) => operation.getPossibleOperationForField(f)) + : undefined; + + if (field) { + // Recursively update the layer for each new reference + layer = insertNewColumn({ + layer, + columnId: reference.columnId, + op: operation.type, + indexPattern, + field, + visualizationGroups, + targetGroup, + }); + referenceIds.push(reference.columnId); + return; + } + }); + return referenceIds; +}; + +const generateNewReferences = ({ + op, + incompleteFieldOperation, + incompleteFieldName, + columnParams, + layer, + requiredReferences, + indexPattern, + visualizationGroups, + targetGroup, +}: { + op: string; + incompleteFieldName?: string; + incompleteFieldOperation?: OperationType; + columnParams?: Record; + layer: IndexPatternLayer; + requiredReferences: RequiredReference[]; + indexPattern: IndexPattern; + visualizationGroups: VisualizationDimensionGroupConfig[]; + targetGroup?: string; +}) => { + return requiredReferences.map((validation) => { + const validOperations = Object.values(operationDefinitionMap).filter(({ type }) => + isOperationAllowedAsReference({ validation, operationType: type, indexPattern }) + ); + + if (!validOperations.length) { + throw new Error( + `Can't create reference, ${op} has a validation function which doesn't allow any operations` + ); + } + + const newId = generateId(); + if (incompleteFieldOperation && incompleteFieldName) { + const validFields = indexPattern.fields.filter( + (validField) => validField.name === incompleteFieldName + ); + layer = insertNewColumn({ + layer, + columnId: newId, + op: incompleteFieldOperation, + indexPattern, + field: validFields[0] ?? documentField, + visualizationGroups, + columnParams, + targetGroup, + }); + } + if (validOperations.length === 1) { + const def = validOperations[0]; + + let validFields = + def.input === 'field' ? indexPattern.fields.filter(def.getPossibleOperationForField) : []; + + if (incompleteFieldName) { + validFields = validFields.filter((validField) => validField.name === incompleteFieldName); + } + if (def.input === 'none') { + layer = insertNewColumn({ + layer, + columnId: newId, + op: def.type, + indexPattern, + visualizationGroups, + targetGroup, + }); + } else if (validFields.length === 1) { + // Recursively update the layer for each new reference + layer = insertNewColumn({ + layer, + columnId: newId, + op: def.type, + indexPattern, + field: validFields[0], + visualizationGroups, + targetGroup, + }); + } else { + layer = { + ...layer, + incompleteColumns: { + ...layer.incompleteColumns, + [newId]: { operationType: def.type }, + }, + }; + } + } + return newId; + }); +}; + // Insert a column into an empty ID. The field parameter is required when constructing // a field-based operation, but will cause the function to fail for any other type of operation. export function insertNewColumn({ @@ -184,12 +345,12 @@ export function insertNewColumn({ indexPattern, visualizationGroups, targetGroup, - shouldResetLabel, incompleteParams, incompleteFieldName, incompleteFieldOperation, columnParams, initialParams, + references, }: ColumnChange): IndexPatternLayer { const operationDefinition = operationDefinitionMap[op]; @@ -231,75 +392,31 @@ export function insertNewColumn({ if (field) { throw new Error(`Reference-based operations can't take a field as input when creating`); } - let tempLayer = { ...layer }; - const referenceIds = operationDefinition.requiredReferences.map((validation) => { - const validOperations = Object.values(operationDefinitionMap).filter(({ type }) => - isOperationAllowedAsReference({ validation, operationType: type, indexPattern }) - ); - - if (!validOperations.length) { - throw new Error( - `Can't create reference, ${op} has a validation function which doesn't allow any operations` - ); - } - - const newId = generateId(); - if (incompleteFieldOperation && incompleteFieldName) { - const validFields = indexPattern.fields.filter( - (validField) => validField.name === incompleteFieldName - ); - tempLayer = insertNewColumn({ - layer: tempLayer, - columnId: newId, - op: incompleteFieldOperation, - indexPattern, - field: validFields[0] ?? documentField, - visualizationGroups, - columnParams, - targetGroup, - }); - } - if (validOperations.length === 1) { - const def = validOperations[0]; + const tempLayer = { ...layer }; - let validFields = - def.input === 'field' ? indexPattern.fields.filter(def.getPossibleOperationForField) : []; - - if (incompleteFieldName) { - validFields = validFields.filter((validField) => validField.name === incompleteFieldName); - } - if (def.input === 'none') { - tempLayer = insertNewColumn({ - layer: tempLayer, - columnId: newId, - op: def.type, - indexPattern, - visualizationGroups, - targetGroup, - }); - } else if (validFields.length === 1) { - // Recursively update the layer for each new reference - tempLayer = insertNewColumn({ - layer: tempLayer, - columnId: newId, - op: def.type, - indexPattern, - field: validFields[0], - visualizationGroups, - targetGroup, - }); - } else { - tempLayer = { - ...tempLayer, - incompleteColumns: { - ...tempLayer.incompleteColumns, - [newId]: { operationType: def.type }, - }, - }; - } - } - return newId; - }); + let referenceIds: string[] = []; + if (references) { + referenceIds = insertReferences({ + layer: tempLayer, + references, + requiredReferences: operationDefinition.requiredReferences, + indexPattern, + visualizationGroups, + targetGroup, + }); + } else { + referenceIds = generateNewReferences({ + op, + incompleteFieldName, + incompleteFieldOperation, + columnParams, + layer, + requiredReferences: operationDefinition.requiredReferences, + indexPattern, + visualizationGroups, + targetGroup, + }); + } const possibleOperation = operationDefinition.getPossibleOperation(indexPattern); if (!possibleOperation) { From a9d19b7120268437c17acdbbb7623c3214f4eea1 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 13:14:16 +0300 Subject: [PATCH 034/129] Fixed percentile and percentile ranks. --- .../convert_to_lens/lib/convert/percentile.ts | 10 +++++----- .../lib/convert/percentile_rank.ts | 10 +++++----- .../lib/series/metrics_columns.ts | 18 +++++++++++++++--- .../timeseries/public/convert_to_lens/types.ts | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 918ea14ee9b75..58559462f0d6c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -61,14 +61,14 @@ export const convertToPercentileColumns = ( series: Series, metric: Metric, dataView: DataView -): PercentileColumn[] => { +): Array | null => { const { percentiles } = metric; if (!percentiles) { - return []; + return null; } - return percentiles - .map((p, index) => convertToPercentileColumn(p.value, series, metric, dataView, index)) - .filter((p): p is PercentileColumn => Boolean(p)); + return percentiles.map((p, index) => + convertToPercentileColumn(p.value, series, metric, dataView, index) + ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index 5c87d9d4051fc..7b50f417f0131 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -65,14 +65,14 @@ export const convertToPercentileRankColumns = ( series: Series, metric: Metric, dataView: DataView -): PercentileRanksColumn[] => { +): Array | null => { const { values } = metric; if (!values) { - return []; + return null; } - return values - .map((p, index) => convertToPercentileRankColumn(p, series, metric, dataView, index)) - .filter((p): p is PercentileRanksColumn => Boolean(p)); + return values.map((p, index) => + convertToPercentileRankColumn(p, series, metric, dataView, index) + ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 2f3461b2dcd62..4bbc9a03634ac 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -41,14 +41,26 @@ export const getMetricsColumns = ( switch (aggregation) { case 'percentile': { - return convertMetricsToColumns(series, metrics, dataView, convertToPercentileColumns); + const percentileColumns = convertMetricsToColumns( + series, + metrics, + dataView, + convertToPercentileColumns + ); + return getValidColumns(percentileColumns); } case 'percentile_rank': { - return convertMetricsToColumns(series, metrics, dataView, convertToPercentileRankColumns); + const percentileRankColumns = convertMetricsToColumns( + series, + metrics, + dataView, + convertToPercentileRankColumns + ); + return getValidColumns(percentileRankColumns); } case 'math': { const formulaColumn = convertMathToFormulaColumn(series, metrics); - return formulaColumn ? [formulaColumn] : null; + return getValidColumns(formulaColumn); } case 'moving_average': { const movingAverageColumns = convertParentPipelineAggToColumns(series, metrics, dataView); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index 3b3a03b965745..ff170286ba3a2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -24,4 +24,4 @@ export type ConvertToColumnsFn = ( series: Series, metric: Metric, dataView: DataView -) => C[]; +) => Array | null; From f1b830378b5261506ea2e32dcdac9eab275cf6d5 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 14:10:21 +0300 Subject: [PATCH 035/129] removed unused return statement. --- .../public/convert_to_lens/lib/series/metrics_columns.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 4bbc9a03634ac..20ff06fa86aba 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -100,6 +100,4 @@ export const getMetricsColumns = ( return getValidColumns(column); } } - - return []; }; From 00dc472e7c4d717805235fd2a35e00bb6211bf67 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 23 Aug 2022 14:15:28 +0300 Subject: [PATCH 036/129] Refactoring 'getEmptyLayersSuggestionsForVisualizeCharts' method --- .../common/convert_to_lens/types/columns.ts | 1 - .../common/convert_to_lens/types/common.ts | 2 +- .../indexpattern_suggestions.ts | 196 ++++++++----- .../definitions/calculations/counter_rate.tsx | 2 +- .../calculations/cumulative_sum.tsx | 2 +- .../calculations/moving_average.tsx | 2 +- .../operations/definitions/cardinality.tsx | 2 +- .../operations/definitions/count.tsx | 2 +- .../definitions/filters/filters.tsx | 12 +- .../definitions/formula/formula.tsx | 15 +- .../operations/definitions/index.ts | 22 +- .../operations/definitions/last_value.tsx | 5 +- .../operations/definitions/percentile.tsx | 2 +- .../definitions/percentile_ranks.tsx | 2 +- .../operations/definitions/ranges/ranges.tsx | 20 +- .../operations/definitions/terms/index.tsx | 31 ++- .../operations/layer_helpers.ts | 262 +----------------- 17 files changed, 201 insertions(+), 379 deletions(-) diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index d1e407170b70f..392c686a45554 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -84,7 +84,6 @@ export type FormulaColumn = ColumnWithReferences<'formula', FormulaParams>; export type StaticValueColumn = ColumnWithReferences<'static_value', StaticValueParams>; export type AnyColumnWithSourceField = - | FiltersColumn | RangeColumn | TermsColumn | DateHistogramColumn diff --git a/src/plugins/visualizations/common/convert_to_lens/types/common.ts b/src/plugins/visualizations/common/convert_to_lens/types/common.ts index 7cf68761751f7..974326834ce2a 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/common.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/common.ts @@ -18,7 +18,7 @@ export type DataType = | 'geo_shape' | 'murmur3'; -export type TimeScaleUnit = 'ms' | 's' | 'm' | 'h' | 'd'; +export type TimeScaleUnit = 's' | 'm' | 'h' | 'd'; export type SortingHint = 'version'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 319c309cac036..e2d30e6cf10cb 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -7,7 +7,12 @@ import { flatten, minBy, pick, mapValues, partition } from 'lodash'; import { i18n } from '@kbn/i18n'; -import type { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import type { + Layer, + Column, + AnyColumnWithReferences, + AnyColumnWithSourceField, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; import { generateId } from '../id_generator'; import type { DatasourceSuggestion, @@ -15,6 +20,7 @@ import type { IndexPatternField, IndexPatternMap, TableChangeType, + VisualizationDimensionGroupConfig, } from '../types'; import { columnToOperation } from './indexpattern'; import { @@ -28,16 +34,26 @@ import { getExistingColumnGroups, isReferenced, getReferencedColumnIds, - getSplitByTermsLayer, - getSplitByFiltersLayer, - computeLayerFromContext, hasTermsWithManyBuckets, + FormulaIndexPatternColumn, } from './operations'; import { hasField } from './pure_utils'; import type { IndexPatternPrivateState, IndexPatternLayer } from './types'; import { documentField } from './document_field'; +import { OperationDefinition } from './operations/definitions'; +import { insertOrReplaceFormulaColumn } from './operations/definitions/formula'; export type IndexPatternSuggestion = DatasourceSuggestion; +interface ColumnChange { + op: OperationType; + columnId: string; + indexPattern: IndexPattern; + field?: IndexPatternField; + visualizationGroups: VisualizationDimensionGroupConfig[]; + columnParams?: Record; + references?: ColumnChange[]; +} + function buildSuggestion({ state, updatedLayer, @@ -155,95 +171,123 @@ export function getDatasourceSuggestionsForField( // Called when the user navigates from Visualize editor to Lens export function getDatasourceSuggestionsForVisualizeCharts( state: IndexPatternPrivateState, - context: VisualizeEditorLayersContext[], + contextLayers: Layer[], indexPatterns: IndexPatternMap ): IndexPatternSuggestion[] { - const layers = Object.keys(state.layers); - const layerIds = layers.filter( - (id) => state.layers[id].indexPatternId === context[0].indexPatternId - ); - if (layerIds.length !== 0) return []; - return getEmptyLayersSuggestionsForVisualizeCharts(state, context, indexPatterns); + return getEmptyLayersSuggestionsForVisualizeCharts(state, contextLayers, indexPatterns); } function getEmptyLayersSuggestionsForVisualizeCharts( state: IndexPatternPrivateState, - context: VisualizeEditorLayersContext[], + contextLayers: Layer[], indexPatterns: IndexPatternMap ): IndexPatternSuggestion[] { const suggestions: IndexPatternSuggestion[] = []; - for (let layerIdx = 0; layerIdx < context.length; layerIdx++) { - const layer = context[layerIdx]; + contextLayers.forEach((layer) => { const indexPattern = indexPatterns[layer.indexPatternId]; if (!indexPattern) return []; + const newLayer = createNewLayerWithMetricAggregationFromVizEditor(indexPattern, layer); + const suggestion = buildSuggestion({ + state, + updatedLayer: newLayer, + layerId: layer.layerId, + changeType: 'initial', + }); + suggestions.push(suggestion); + }); + return suggestions; +} - const newId = generateId(); - let newLayer: IndexPatternLayer | undefined; - if (indexPattern.timeFieldName) { - newLayer = createNewTimeseriesLayerWithMetricAggregationFromVizEditor(indexPattern, layer); - } - if (newLayer) { - const suggestion = buildSuggestion({ - state, - updatedLayer: newLayer, - layerId: newId, - changeType: 'initial', - }); - const layerId = Object.keys(suggestion.state.layers)[0]; - context[layerIdx].layerId = layerId; - suggestions.push(suggestion); +function isReferenceColumn(column: Column): column is AnyColumnWithReferences { + return 'references' in column && (column as AnyColumnWithReferences).references.length > 0; +} + +function isFieldBasedColumn(column: Column): column is AnyColumnWithSourceField { + return 'sourceField' in column; +} + +function getSourceField(column: Column, indexPattern: IndexPattern) { + return isFieldBasedColumn(column) + ? column.sourceField === 'document' + ? documentField + : indexPattern.getFieldByName(column.sourceField) + : undefined; +} + +function getParams(column: Column) { + return { + ...column.params, + filter: column.filter, + shift: column.timeShift, + window: column.window, + }; +} + +function convertToColumnChange(columns: Layer['columns'], indexPattern: IndexPattern) { + return columns.reduce((acc, column) => { + if (!columns.some((c) => isReferenceColumn(c) && column.columnId === c.references[0])) { + const newColumn: ColumnChange = { + op: column.operationType, + columnId: column.columnId, + field: getSourceField(column, indexPattern), + indexPattern, + visualizationGroups: [], + columnParams: getParams(column), + }; + if (isReferenceColumn(column)) { + const referenceColumn = columns.find((c) => c.columnId === column.references[0])!; + newColumn.references = [ + { + op: referenceColumn.operationType, + columnId: referenceColumn.columnId, + field: getSourceField(referenceColumn, indexPattern), + indexPattern, + visualizationGroups: [], + columnParams: getParams(referenceColumn), + }, + ]; + } + acc.push(newColumn); } - } - return suggestions; + + return acc; + }, []); } -function createNewTimeseriesLayerWithMetricAggregationFromVizEditor( +function createNewLayerWithMetricAggregationFromVizEditor( indexPattern: IndexPattern, - layer: VisualizeEditorLayersContext -): IndexPatternLayer | undefined { - const { timeFieldName, splitMode, splitFilters, metrics, timeInterval, dropPartialBuckets } = - layer; - const dateField = indexPattern.getFieldByName(timeFieldName!); - - const splitFields = layer.splitFields - ? (layer.splitFields - .map((item) => indexPattern.getFieldByName(item)) - .filter(Boolean) as IndexPatternField[]) - : null; - - // generate the layer for split by terms - if (splitMode === 'terms' && splitFields?.length) { - return getSplitByTermsLayer(indexPattern, splitFields, dateField, layer); - // generate the layer for split by filters - } else if (splitMode?.includes('filter') && splitFilters && splitFilters.length) { - return getSplitByFiltersLayer(indexPattern, dateField, layer); - } else { - const copyMetricsArray = [...metrics]; - const computedLayer = computeLayerFromContext( - metrics.length === 1, - copyMetricsArray, - indexPattern, - layer.format, - layer.label - ); - // static values layers do not need a date histogram column - if (Object.values(computedLayer.columns)[0].isStaticValue) { - return computedLayer; + layer: Layer +) { + const columns = convertToColumnChange(layer.columns, indexPattern); + let newLayer: IndexPatternLayer = { + indexPatternId: indexPattern.id, + columns: {}, + columnOrder: [], + }; + columns.forEach((column) => { + if (column.op === 'formula') { + const operationDefinition = operationDefinitionMap.formula as OperationDefinition< + FormulaIndexPatternColumn, + 'managedReference' + >; + const newColumn = operationDefinition.buildColumn( + { + indexPattern, + layer: newLayer, + }, + column.columnParams + ) as FormulaIndexPatternColumn; + newLayer = insertOrReplaceFormulaColumn(column.columnId, newColumn, newLayer, { + indexPattern, + }).layer; + } else { + newLayer = insertNewColumn({ + ...column, + layer: newLayer, + }); } - - return insertNewColumn({ - op: 'date_histogram', - layer: computedLayer, - columnId: generateId(), - field: dateField, - indexPattern, - visualizationGroups: [], - columnParams: { - interval: timeInterval, - dropPartials: dropPartialBuckets, - }, - }); - } + }); + return newLayer; } // Called when the user navigates from Discover to Lens (Visualize button) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx index 674eac8194e41..6619fc6889894 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx @@ -99,7 +99,7 @@ export const counterRateOperation: OperationDefinition< references: referenceIds, timeScale, timeShift: columnParams?.shift || previousColumn?.timeShift, - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter || getFilter(previousColumn, columnParams), params: getFormatFromPreviousColumn(previousColumn), }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx index 11e1da98b0ca0..0fa80c7440fcb 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx @@ -98,7 +98,7 @@ export const cumulativeSumOperation: OperationDefinition< isBucketed: false, scale: 'ratio', timeShift: columnParams?.shift || previousColumn?.timeShift, - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter || getFilter(previousColumn, columnParams), references: referenceIds, params: getFormatFromPreviousColumn(previousColumn), }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx index c46b6954f7480..7330267fbbe76 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx @@ -103,7 +103,7 @@ export const movingAverageOperation: OperationDefinition< scale: 'ratio', references: referenceIds, timeShift: columnParams?.shift || previousColumn?.timeShift, - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter || getFilter(previousColumn, columnParams), timeScale: previousColumn?.timeScale, params: { window, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx index dbbbb2da80e08..7d11fe1b00a1f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx @@ -118,7 +118,7 @@ export const cardinalityOperation: OperationDefinition< scale: SCALE, sourceField: field.name, isBucketed: IS_BUCKETED, - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter || getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index a80e1f7e1c718..33cf50c36d1f7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -129,7 +129,7 @@ export const countOperation: OperationDefinition = { +export const filtersOperation: OperationDefinition< + FiltersIndexPatternColumn, + 'none', + FiltersIndexPatternColumn['params'] +> = { type: OPERATION_NAME, displayName: filtersLabel, priority: 3, // Higher than any metric @@ -92,11 +96,11 @@ export const filtersOperation: OperationDefinition true, getDefaultLabel: () => filtersLabel, - buildColumn({ previousColumn }) { - let params = { filters: [defaultFilter] }; + buildColumn({ previousColumn }, columnParams) { + let params = { filters: columnParams?.filters ?? [defaultFilter] }; if (previousColumn?.operationType === 'terms' && 'sourceField' in previousColumn) { params = { - filters: [ + filters: columnParams?.filters ?? [ { label: '', input: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx index c3562fb649665..388f3abac9e5a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx @@ -138,7 +138,7 @@ export const formulaOperation: OperationDefinition { input: 'none'; @@ -496,12 +508,10 @@ interface FieldBasedOperationDefinition C; /** * This method will be called if the user changes the field of an operation. @@ -611,10 +621,8 @@ interface FullReferenceOperationDefinition { previousColumn?: GenericIndexPatternColumn; }, columnParams?: (ReferenceBasedIndexPatternColumn & C)['params'] & { - kql?: string; - lucene?: string; shift?: string; - } + } & FilterParams ) => ReferenceBasedIndexPatternColumn & C; /** * Returns the meta data of the operation if applied. Undefined @@ -640,7 +648,7 @@ interface ManagedReferenceOperationDefinition arg: BaseBuildColumnArgs & { previousColumn?: GenericIndexPatternColumn; }, - columnParams?: (ReferenceBasedIndexPatternColumn & C)['params'], + columnParams?: (ReferenceBasedIndexPatternColumn & C)['params'] & FilterParams, operationDefinitionMap?: Record ) => ReferenceBasedIndexPatternColumn & C; /** diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx index f9fbb80e649c6..afc74b043fca7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx @@ -215,7 +215,10 @@ export const lastValueOperation: OperationDefinition< isBucketed: false, scale: field.type === 'string' ? 'ordinal' : 'ratio', sourceField: field.name, - filter: getFilter(previousColumn, columnParams) || getExistsFilter(field.name), + filter: + columnParams?.filter || + getFilter(previousColumn, columnParams) || + getExistsFilter(field.name), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx index a0eb542449813..e725f5b394767 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx @@ -133,7 +133,7 @@ export const percentileOperation: OperationDefinition< sourceField: field.name, isBucketed: false, scale: 'ratio', - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter || getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx index 9541665195689..66bb21498706d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx @@ -126,7 +126,7 @@ export const percentileRanksOperation: OperationDefinition< sourceField: field.name, isBucketed: false, scale: 'ratio', - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter || getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx index d3c3bd5ceec86..73b0ac0d96ca6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx @@ -71,7 +71,11 @@ function getFieldDefaultFormat(indexPattern: IndexPattern, field: IndexPatternFi return undefined; } -export const rangeOperation: OperationDefinition = { +export const rangeOperation: OperationDefinition< + RangeIndexPatternColumn, + 'field', + RangeColumnParams +> = { type: 'range', displayName: i18n.translate('xpack.lens.indexPattern.intervals', { defaultMessage: 'Intervals', @@ -98,7 +102,7 @@ export const rangeOperation: OperationDefinition) const idPrefix = htmlIdGenerator()(); -export const termsOperation: OperationDefinition = { +export const termsOperation: OperationDefinition< + TermsIndexPatternColumn, + 'field', + TermsIndexPatternColumn['params'] +> = { type: 'terms', displayName: i18n.translate('xpack.lens.indexPattern.terms', { defaultMessage: 'Top values', @@ -205,7 +209,7 @@ export const termsOperation: OperationDefinition isSortableByColumn(layer, columnId)) .map(([id]) => id)[0]; @@ -222,17 +226,18 @@ export const termsOperation: OperationDefinition; initialParams?: { params: Record }; // TODO: bind this to the op parameter - references?: ColumnChange[]; + references?: Array>; } interface ColumnCopy { @@ -184,13 +182,13 @@ const insertReferences = ({ targetGroup, }: { layer: IndexPatternLayer; - references: ColumnChange[]; + references: ColumnChange['references']; requiredReferences: RequiredReference[]; indexPattern: IndexPattern; visualizationGroups: VisualizationDimensionGroupConfig[]; targetGroup?: string; }) => { - references.forEach((reference) => { + references?.forEach((reference) => { const validOperations = requiredReferences.filter((validation) => isOperationAllowedAsReference({ validation, operationType: reference.op, indexPattern }) ); @@ -203,7 +201,7 @@ const insertReferences = ({ }); const referenceIds: string[] = []; - references.forEach((reference) => { + references?.forEach((reference) => { const operation = operationDefinitionMap[reference.op]; if (operation.input === 'none') { @@ -1742,253 +1740,3 @@ export function getManagedColumnsFrom( } return store.filter(([, column]) => column); } - -export function computeLayerFromContext( - isLast: boolean, - metricsArray: VisualizeEditorLayersContext['metrics'], - indexPattern: IndexPattern, - format?: string, - customLabel?: string -): IndexPatternLayer { - let layer: IndexPatternLayer = { - indexPatternId: indexPattern.id, - columns: {}, - columnOrder: [], - }; - if (isArray(metricsArray)) { - const metricContext = metricsArray.shift(); - const field = metricContext - ? indexPattern.getFieldByName(metricContext.fieldName) ?? documentField - : documentField; - - const operation = metricContext?.agg; - // Formula should be treated differently from other operations - if (operation === 'formula') { - const operationDefinition = operationDefinitionMap.formula as OperationDefinition< - FormulaIndexPatternColumn, - 'managedReference' - >; - const tempLayer = { indexPatternId: indexPattern.id, columns: {}, columnOrder: [] }; - let newColumn = operationDefinition.buildColumn({ - indexPattern, - layer: tempLayer, - }) as FormulaIndexPatternColumn; - let filterBy = metricContext?.params?.kql - ? { query: metricContext?.params?.kql, language: 'kuery' } - : undefined; - if (metricContext?.params?.lucene) { - filterBy = metricContext?.params?.lucene - ? { query: metricContext?.params?.lucene, language: 'lucene' } - : undefined; - } - newColumn = { - ...newColumn, - ...(filterBy && { filter: filterBy }), - params: { - ...newColumn.params, - ...metricContext?.params, - }, - } as FormulaIndexPatternColumn; - layer = metricContext?.params?.formula - ? insertOrReplaceFormulaColumn(generateId(), newColumn, tempLayer, { - indexPattern, - }).layer - : tempLayer; - } else { - const columnId = generateId(); - // recursive function to build the layer - layer = insertNewColumn({ - op: operation as OperationType, - layer: isLast - ? { indexPatternId: indexPattern.id, columns: {}, columnOrder: [] } - : computeLayerFromContext(metricsArray.length === 1, metricsArray, indexPattern), - columnId, - field: !metricContext?.isFullReference ? field ?? documentField : undefined, - columnParams: metricContext?.params ?? undefined, - incompleteFieldName: metricContext?.isFullReference ? field?.name : undefined, - incompleteFieldOperation: metricContext?.isFullReference - ? metricContext?.pipelineAggType - : undefined, - indexPattern, - visualizationGroups: [], - }); - if (metricContext) { - metricContext.accessor = columnId; - } - } - } - - // update the layer with the custom label and the format - let columnIdx = 0; - for (const [columnId, column] of Object.entries(layer.columns)) { - if (format) { - layer = updateColumnParam({ - layer, - columnId, - paramName: 'format', - value: { - id: format, - params: { - decimals: 0, - }, - }, - }); - } - - // for percentiles I want to update all columns with the custom label - if (customLabel && column.operationType === 'percentile') { - layer = updateColumnLabel({ - layer, - columnId, - customLabel, - }); - } else if (customLabel && columnIdx === Object.keys(layer.columns).length - 1) { - layer = updateColumnLabel({ - layer, - columnId, - customLabel, - }); - } - columnIdx++; - } - return layer; -} - -export function getSplitByTermsLayer( - indexPattern: IndexPattern, - splitFields: IndexPatternField[], - dateField: IndexPatternField | undefined, - layer: VisualizeEditorLayersContext -): IndexPatternLayer { - const { termsParams, metrics, timeInterval, splitWithDateHistogram, dropPartialBuckets } = layer; - const copyMetricsArray = [...metrics]; - - const computedLayer = computeLayerFromContext( - metrics.length === 1, - copyMetricsArray, - indexPattern, - layer.format, - layer.label - ); - - const [baseField, ...secondaryFields] = splitFields; - const columnId = generateId(); - - let termsLayer = insertNewColumn({ - op: splitWithDateHistogram ? 'date_histogram' : 'terms', - layer: insertNewColumn({ - op: 'date_histogram', - layer: computedLayer, - columnId: generateId(), - field: dateField, - indexPattern, - visualizationGroups: [], - columnParams: { - interval: timeInterval, - dropPartials: dropPartialBuckets, - }, - }), - columnId, - field: baseField, - indexPattern, - visualizationGroups: [], - }); - - if (secondaryFields.length) { - termsLayer = updateColumnParam({ - layer: termsLayer, - columnId, - paramName: 'secondaryFields', - value: secondaryFields.map((i) => i.name), - }); - - termsLayer = updateDefaultLabels(termsLayer, indexPattern); - } - - const termsColumnParams = termsParams as TermsIndexPatternColumn['params']; - if (termsColumnParams) { - for (const [param, value] of Object.entries(termsColumnParams)) { - let paramValue = value; - if (param === 'orderBy') { - const [existingMetricColumn] = Object.keys(termsLayer.columns).filter((colId) => - isSortableByColumn(termsLayer, colId) - ); - - paramValue = ( - termsColumnParams.orderBy.type === 'column' && existingMetricColumn - ? { - type: 'column', - columnId: existingMetricColumn, - } - : { type: 'alphabetical', fallback: true } - ) as TermsIndexPatternColumn['params']['orderBy']; - } - termsLayer = updateColumnParam({ - layer: termsLayer, - columnId, - paramName: param, - value: paramValue, - }); - // label must be updated after the param is updated (Top {size} values of {field}) - termsLayer = updateDefaultLabels(termsLayer, indexPattern); - } - } - return termsLayer; -} - -export function getSplitByFiltersLayer( - indexPattern: IndexPattern, - dateField: IndexPatternField | undefined, - layer: VisualizeEditorLayersContext -): IndexPatternLayer { - const { splitFilters, metrics, timeInterval, dropPartialBuckets } = layer; - const filterParams = splitFilters?.map((param) => { - const query = param.filter ? param.filter.query : ''; - const language = param.filter ? param.filter.language : 'kuery'; - return { - input: { - query, - language, - }, - label: param.label ?? '', - }; - }); - const copyMetricsArray = [...metrics]; - const computedLayer = computeLayerFromContext( - metrics.length === 1, - copyMetricsArray, - indexPattern, - layer.format, - layer.label - ); - const columnId = generateId(); - let filtersLayer = insertNewColumn({ - op: 'filters', - layer: insertNewColumn({ - op: 'date_histogram', - layer: computedLayer, - columnId: generateId(), - field: dateField, - indexPattern, - visualizationGroups: [], - columnParams: { - interval: timeInterval, - dropPartials: dropPartialBuckets, - }, - }), - columnId, - field: undefined, - indexPattern, - visualizationGroups: [], - }); - - if (filterParams) { - filtersLayer = updateColumnParam({ - layer: filtersLayer, - columnId, - paramName: 'filters', - value: filterParams, - }); - } - return filtersLayer; -} From b146838776dd5c6879a249bc9b9e7fa53a963738 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 14:41:43 +0300 Subject: [PATCH 037/129] TimeScaleUnit fix. --- .../public/convert_to_lens/lib/metrics/metrics_helpers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 4978592f0e032..fc089abfdcbe3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -44,7 +44,7 @@ export const getPercentileRankSeries = ( type TimeScaleValue = `1${TimeScaleUnit}`; const isTimeScaleValue = (unit: string): unit is TimeScaleValue => { - const supportedTimeScales: TimeScaleValue[] = ['1ms', '1s', '1m', '1h', '1d']; + const supportedTimeScales: TimeScaleValue[] = ['1s', '1m', '1h', '1d']; return supportedTimeScales.includes(unit as TimeScaleValue); }; From 97187d6c24ebff1469acc253e08eb432c376c061 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 14:58:24 +0300 Subject: [PATCH 038/129] Fixed references. --- .../operations/layer_helpers.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 93c6d97968968..5ce4a07afd167 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -182,13 +182,13 @@ const insertReferences = ({ targetGroup, }: { layer: IndexPatternLayer; - references: ColumnChange['references']; + references: Exclude; requiredReferences: RequiredReference[]; indexPattern: IndexPattern; visualizationGroups: VisualizationDimensionGroupConfig[]; targetGroup?: string; }) => { - references?.forEach((reference) => { + references.forEach((reference) => { const validOperations = requiredReferences.filter((validation) => isOperationAllowedAsReference({ validation, operationType: reference.op, indexPattern }) ); @@ -201,7 +201,7 @@ const insertReferences = ({ }); const referenceIds: string[] = []; - references?.forEach((reference) => { + references.forEach((reference) => { const operation = operationDefinitionMap[reference.op]; if (operation.input === 'none') { @@ -219,9 +219,12 @@ const insertReferences = ({ referenceIds.push(reference.columnId); return; } + const field = - operation.input === 'field' - ? indexPattern.fields.find((f) => operation.getPossibleOperationForField(f)) + operation.input === 'field' && + reference.field && + operation.getPossibleOperationForField(reference.field) + ? reference.field : undefined; if (field) { @@ -239,7 +242,7 @@ const insertReferences = ({ return; } }); - return referenceIds; + return { layer, referenceIds }; }; const generateNewReferences = ({ @@ -263,7 +266,7 @@ const generateNewReferences = ({ visualizationGroups: VisualizationDimensionGroupConfig[]; targetGroup?: string; }) => { - return requiredReferences.map((validation) => { + const referenceIds = requiredReferences.map((validation) => { const validOperations = Object.values(operationDefinitionMap).filter(({ type }) => isOperationAllowedAsReference({ validation, operationType: type, indexPattern }) ); @@ -331,6 +334,8 @@ const generateNewReferences = ({ } return newId; }); + + return { layer, referenceIds }; }; // Insert a column into an empty ID. The field parameter is required when constructing @@ -390,11 +395,11 @@ export function insertNewColumn({ if (field) { throw new Error(`Reference-based operations can't take a field as input when creating`); } - const tempLayer = { ...layer }; + let tempLayer = { ...layer }; let referenceIds: string[] = []; if (references) { - referenceIds = insertReferences({ + const result = insertReferences({ layer: tempLayer, references, requiredReferences: operationDefinition.requiredReferences, @@ -402,18 +407,20 @@ export function insertNewColumn({ visualizationGroups, targetGroup, }); + [tempLayer, referenceIds] = [result.layer, result.referenceIds]; } else { - referenceIds = generateNewReferences({ + const result = generateNewReferences({ op, incompleteFieldName, incompleteFieldOperation, columnParams, - layer, + layer: tempLayer, requiredReferences: operationDefinition.requiredReferences, indexPattern, visualizationGroups, targetGroup, }); + [tempLayer, referenceIds] = [result.layer, result.referenceIds]; } const possibleOperation = operationDefinition.getPossibleOperation(indexPattern); From b2817cce59ab8dcb97febd175a6ad487a6a78816 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 15:08:08 +0300 Subject: [PATCH 039/129] Fixed types. --- .../timeseries/public/convert_to_lens/lib/convert/column.ts | 3 +-- .../vis_types/timeseries/public/convert_to_lens/types.ts | 2 +- .../visualizations/common/convert_to_lens/types/columns.ts | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 5e28795f0c512..7429239addac3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -10,14 +10,13 @@ import { BaseColumn, Operation, DataType, - Column, ColumnWithMeta as GenericColumnWithMeta, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; import { ConvertToColumnsFn } from '../../types'; import { getTimeScale } from '../metrics'; -import { ColumnWithMeta, Meta } from './types'; +import { ColumnWithMeta, Meta, Column } from './types'; type GeneralColumn = Omit, 'operationType' | 'params'>; type GeneralColumnWithMeta = GenericColumnWithMeta; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index ff170286ba3a2..46e8c33fd26e8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import { Column } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { DataView } from '@kbn/data-views-plugin/common'; import { NavigateToLensContext } from '@kbn/visualizations-plugin/public'; import type { Metric, Panel, Series } from '../../common/types'; +import { Column } from './lib/convert'; export type ConvertTsvbToLensVisualization = ( model: Panel diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index 392c686a45554..4dcfaed3291d4 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -107,7 +107,7 @@ export type AnyColumnWithReferences = | FormulaColumn | StaticValueColumn; -export type Column = AnyColumnWithReferences | AnyColumnWithSourceField; +export type Column = AnyColumnWithReferences | AnyColumnWithSourceField | FiltersColumn; export type ColumnWithMeta = Col & (Meta extends undefined ? undefined : { meta: Meta }); From 798998b2046e537c5a981461326c47d07afe04fd Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 23 Aug 2022 15:43:46 +0300 Subject: [PATCH 040/129] Fixed terms column --- .../convert_to_lens/lib/convert/index.ts | 2 +- .../convert_to_lens/lib/convert/terms.ts | 26 ++++++++----------- .../lib/series/buckets_columns.ts | 16 ++++-------- .../indexpattern_suggestions.ts | 20 ++++++++++++++ .../operations/definitions/terms/index.tsx | 10 ++++--- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index ca197a80950d7..a1bdce8a7ccb2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -20,6 +20,6 @@ export { convertToLastValueColumn } from './last_value'; export { convertToStaticValueColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; export { convertToDateHistogramColumn } from './date_histogram'; -export { converToTermsColumns } from './terms'; +export { converToTermsColumn } from './terms'; export * from './types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts index 4db8211bba35d..91a115c167ba4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts @@ -23,7 +23,7 @@ const getOrderByWithAgg = (series: Series, columns: Column[]): OrderByWithAgg | return { orderBy: { type: 'alphabetical' } }; } - if (series.terms_order_by === '_count') { + if (series.terms_order_by === '_count' || !series.terms_order_by) { const columnId = uuid(); return { orderBy: { type: 'column', columnId }, @@ -56,7 +56,11 @@ const getOrderByWithAgg = (series: Series, columns: Column[]): OrderByWithAgg | }; }; -export const convertToTermsParams = (series: Series, columns: Column[]): TermsParams | null => { +export const convertToTermsParams = ( + series: Series, + columns: Column[], + secondaryFields: string[] +): TermsParams | null => { const orderDirection: TermsParams['orderDirection'] = series.terms_direction === 'asc' ? 'asc' : 'desc'; @@ -75,23 +79,25 @@ export const convertToTermsParams = (series: Series, columns: Column[]): TermsPa orderDirection, parentFormat: { id: 'terms' }, ...orderByWithAgg, + secondaryFields, }; }; export const converToTermsColumn = ( - termField: string, + termFields: string[], series: Series, columns: Column[], dataView: DataView, isSplit: boolean = false ): TermsColumn | null => { - const field = dataView.getFieldByName(termField); + const [baseField, ...secondaryFields] = termFields; + const field = dataView.getFieldByName(baseField); if (!field) { return null; } - const params = convertToTermsParams(series, columns); + const params = convertToTermsParams(series, columns, secondaryFields); if (!params) { return params; } @@ -106,13 +112,3 @@ export const converToTermsColumn = ( params, }; }; - -export const converToTermsColumns = ( - termFields: string[], - series: Series, - columns: Column[], - dataView: DataView, - isSplit: boolean = false -): Array => { - return termFields.map((field) => converToTermsColumn(field, series, columns, dataView, isSplit)); -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index aa7a58f1fd9e1..ce33e78a26094 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -13,7 +13,7 @@ import { Column, convertToFiltersColumn, convertToDateHistogramColumn, - converToTermsColumns, + converToTermsColumn, } from '../convert'; import { getValidColumns } from './columns'; @@ -49,10 +49,7 @@ export const getBucketsColumns = ( ) => { if (series.split_mode === 'filters' || series.split_mode === 'filter') { const filterColumn = convertToFiltersColumn(series, true); - if (!filterColumn) { - return null; - } - return [filterColumn]; + return getValidColumns([filterColumn]); } if (series.split_mode === 'terms') { const splitFields = getFieldsForTerms(series.terms_field); @@ -68,14 +65,11 @@ export const getBucketsColumns = ( splitFields[0], true ); - if (!dateHistogramColumn) { - return null; - } - return [dateHistogramColumn]; + return getValidColumns([dateHistogramColumn]); } - const termsColumns = converToTermsColumns(splitFields, series, columns, dataView, isSplit); - return getValidColumns(termsColumns); + const termsColumn = converToTermsColumn(splitFields, series, columns, dataView, isSplit); + return getValidColumns([termsColumn]); } return []; }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index e2d30e6cf10cb..c1e5b1fa80992 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -12,6 +12,7 @@ import type { Column, AnyColumnWithReferences, AnyColumnWithSourceField, + TermsColumn, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { generateId } from '../id_generator'; import type { @@ -206,6 +207,10 @@ function isFieldBasedColumn(column: Column): column is AnyColumnWithSourceField return 'sourceField' in column; } +function isTermsColumn(column: Column): column is TermsColumn { + return column.operationType === 'terms'; +} + function getSourceField(column: Column, indexPattern: IndexPattern) { return isFieldBasedColumn(column) ? column.sourceField === 'document' @@ -247,6 +252,21 @@ function convertToColumnChange(columns: Layer['columns'], indexPattern: IndexPat }, ]; } + if ( + isTermsColumn(column) && + column.params.orderAgg && + !columns.some((c) => c.columnId === column.params.orderAgg?.columnId) + ) { + const orderAggColumn: ColumnChange = { + op: column.params.orderAgg.operationType, + columnId: column.params.orderAgg.columnId, + field: getSourceField(column.params.orderAgg, indexPattern), + indexPattern, + visualizationGroups: [], + columnParams: getParams(column.params.orderAgg), + }; + acc.push(orderAggColumn); + } acc.push(newColumn); } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx index 3959aa9778e0b..eec39bd530944 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx @@ -226,18 +226,20 @@ export const termsOperation: OperationDefinition< sourceField: field.name, isBucketed: true, params: { - size: columnParams?.size ?? previousBucketsLength === 0 ? 5 : DEFAULT_SIZE, + size: columnParams?.size ?? (previousBucketsLength === 0 ? 5 : DEFAULT_SIZE), orderBy: - columnParams?.orderBy ?? existingMetricColumn + columnParams?.orderBy ?? + (existingMetricColumn ? { type: 'column', columnId: existingMetricColumn, } - : { type: 'alphabetical', fallback: true }, - orderDirection: columnParams?.orderDirection ?? existingMetricColumn ? 'desc' : 'asc', + : { type: 'alphabetical', fallback: true }), + orderDirection: columnParams?.orderDirection ?? (existingMetricColumn ? 'desc' : 'asc'), otherBucket: (columnParams?.otherBucket ?? true) && !indexPattern.hasRestrictions, missingBucket: columnParams?.missingBucket ?? false, parentFormat: columnParams?.parentFormat ?? { id: 'terms' }, + secondaryFields: columnParams?.secondaryFields, }, }; }, From b26ca08733a3ae809c008f430c440bac8e63e25c Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 16:40:56 +0300 Subject: [PATCH 041/129] Fixed count custom label. --- .../indexpattern_suggestions.ts | 13 +++++++++++-- .../operations/definitions/count.tsx | 5 +++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index e2d30e6cf10cb..efc63fa6a63de 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -223,13 +223,22 @@ function getParams(column: Column) { }; } +function getFieldWithLabel(column: Column, indexPattern: IndexPattern) { + const field = getSourceField(column, indexPattern); + + if (field && column.label) { + return { ...field, customLabel: column.label }; + } + return field; +} + function convertToColumnChange(columns: Layer['columns'], indexPattern: IndexPattern) { return columns.reduce((acc, column) => { if (!columns.some((c) => isReferenceColumn(c) && column.columnId === c.references[0])) { const newColumn: ColumnChange = { op: column.operationType, columnId: column.columnId, - field: getSourceField(column, indexPattern), + field: getFieldWithLabel(column, indexPattern), indexPattern, visualizationGroups: [], columnParams: getParams(column), @@ -240,7 +249,7 @@ function convertToColumnChange(columns: Layer['columns'], indexPattern: IndexPat { op: referenceColumn.operationType, columnId: referenceColumn.columnId, - field: getSourceField(referenceColumn, indexPattern), + field: getFieldWithLabel(referenceColumn, indexPattern), indexPattern, visualizationGroups: [], columnParams: getParams(referenceColumn), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index 33cf50c36d1f7..8a1107a821c52 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -52,6 +52,10 @@ function ofName( timeScale: string | undefined, window: string | undefined ) { + if (field?.customLabel) { + return field.customLabel; + } + return adjustTimeScaleLabelSuffix( field?.type !== 'document' ? i18n.translate('xpack.lens.indexPattern.valueCountOf', { @@ -123,6 +127,7 @@ export const countOperation: OperationDefinition Date: Tue, 23 Aug 2022 17:33:36 +0300 Subject: [PATCH 042/129] Fix multi series --- .../editor_frame/suggestion_helpers.ts | 21 +++++++++++++++++++ x-pack/plugins/lens/public/types.ts | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts index 19bc353b65dc5..0b91cf7ec740d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts @@ -170,6 +170,12 @@ export function getSuggestions({ .sort((a, b) => b.score - a.score); } +function isDataSourceWithLayers(datasourceState: object): datasourceState is { + layers: Record; +} { + return 'layers' in datasourceState; +} + export function getVisualizeFieldSuggestions({ datasourceMap, datasourceStates, @@ -201,6 +207,21 @@ export function getVisualizeFieldSuggestions({ ); return { ...allSuggestions[0], + datasourceState: { + ...(typeof allSuggestions[0].datasourceState === 'object' + ? allSuggestions[0].datasourceState + : {}), + layers: allSuggestions.reduce((acc, s) => { + return { + ...acc, + ...(typeof s.datasourceState === 'object' && + s.datasourceState !== null && + isDataSourceWithLayers(s.datasourceState) + ? s.datasourceState.layers + : {}), + }; + }, {}), + }, visualizationState: { ...(typeof allSuggestions[0].visualizationState === 'object' ? allSuggestions[0].visualizationState diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 9816a9b8cce42..f71f9f0bfdf1d 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -18,6 +18,7 @@ import type { Datatable, } from '@kbn/expressions-plugin/public'; import type { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Query } from '@kbn/es-query'; import type { UiActionsStart, @@ -353,7 +354,7 @@ export interface Datasource { ) => Array>; getDatasourceSuggestionsForVisualizeCharts: ( state: T, - context: VisualizeEditorLayersContext[], + context: Layer[], indexPatterns: IndexPatternMap ) => Array>; getDatasourceSuggestionsForVisualizeField: ( From 9bd61fbd272d38b89c89d3b1e011211b22f3fb91 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 23 Aug 2022 17:44:44 +0300 Subject: [PATCH 043/129] Fixed custom labels. --- .../operations/definitions/cardinality.tsx | 19 +++++++-- .../operations/definitions/count.tsx | 15 +++---- .../operations/definitions/date_histogram.tsx | 10 +++-- .../operations/definitions/helpers.tsx | 25 ++++++++--- .../operations/definitions/last_value.tsx | 16 +++++-- .../operations/definitions/metrics.tsx | 20 ++++++--- .../operations/definitions/percentile.tsx | 42 ++++++++++--------- .../definitions/percentile_ranks.tsx | 36 ++++++++-------- 8 files changed, 113 insertions(+), 70 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx index 7d11fe1b00a1f..68430c3f43161 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx @@ -108,11 +108,21 @@ export const cardinalityOperation: OperationDefinition< filterable: true, shiftable: true, windowable: true, - getDefaultLabel: (column, indexPattern) => - ofName(getSafeName(column.sourceField, indexPattern), column.timeShift, column.window), + getDefaultLabel: (column, indexPattern) => { + const { customLabel, label } = getSafeName(column.sourceField, indexPattern); + if (customLabel) { + return label; + } + return ofName(label, column.timeShift, column.window); + }, buildColumn({ field, previousColumn }, columnParams) { + const label = + field.customLabel || + ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window); + return { - label: ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window), + label, + customLabel: Boolean(field.customLabel), dataType: 'number', operationType: OPERATION_TYPE, scale: SCALE, @@ -185,7 +195,8 @@ export const cardinalityOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: ofName(field.displayName, oldColumn.timeShift, oldColumn.window), + label: field.customLabel || ofName(field.displayName, oldColumn.timeShift, oldColumn.window), + customLabel: Boolean(field.customLabel), sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index 8a1107a821c52..265cc786505ee 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -52,10 +52,6 @@ function ofName( timeScale: string | undefined, window: string | undefined ) { - if (field?.customLabel) { - return field.customLabel; - } - return adjustTimeScaleLabelSuffix( field?.type !== 'document' ? i18n.translate('xpack.lens.indexPattern.valueCountOf', { @@ -120,13 +116,12 @@ export const countOperation: OperationDefinition getSafeName(column.sourceField, indexPattern), + getDefaultLabel: (column, indexPattern) => { + const { label } = getSafeName(column.sourceField, indexPattern); + return label; + }, buildColumn({ field }, columnParams) { return { - label: field.displayName, + label: field.customLabel || field.displayName, + customLabel: Boolean(field.customLabel), dataType: 'date', operationType: 'date_histogram', sourceField: field.name, @@ -134,7 +138,7 @@ export const dateHistogramOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: field.displayName, + label: field.customLabel || field.displayName, sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx index 868d5e2557e49..793279d3dd48b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx @@ -95,13 +95,28 @@ export function combineErrorMessages( return messages.length ? messages : undefined; } -export function getSafeName(name: string, indexPattern: IndexPattern): string { +export function getSafeName(name: string, indexPattern: IndexPattern) { const field = indexPattern.getFieldByName(name); - return field - ? field.displayName - : i18n.translate('xpack.lens.indexPattern.missingFieldLabel', { + if (!field) { + return { + label: i18n.translate('xpack.lens.indexPattern.missingFieldLabel', { defaultMessage: 'Missing field', - }); + }), + customLabel: false, + }; + } + + if (field.customLabel) { + return { + label: field.customLabel, + customLabel: true, + }; + } + + return { + label: field.displayName, + customLabel: false, + }; } export function isValidNumber( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx index afc74b043fca7..ac351fbf82df3 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx @@ -133,8 +133,13 @@ export const lastValueOperation: OperationDefinition< displayName: i18n.translate('xpack.lens.indexPattern.lastValue', { defaultMessage: 'Last value', }), - getDefaultLabel: (column, indexPattern) => - ofName(getSafeName(column.sourceField, indexPattern), column.timeShift, column.window), + getDefaultLabel: (column, indexPattern) => { + const { customLabel, label } = getSafeName(column.sourceField, indexPattern); + if (customLabel) { + return label; + } + return ofName(label, column.timeShift, column.window); + }, input: 'field', onFieldChange: (oldColumn, field) => { const newParams = { ...oldColumn.params }; @@ -147,7 +152,7 @@ export const lastValueOperation: OperationDefinition< return { ...oldColumn, dataType: field.type as DataType, - label: ofName(field.displayName, oldColumn.timeShift, oldColumn.window), + label: field.customLabel || ofName(field.displayName, oldColumn.timeShift, oldColumn.window), sourceField: field.name, params: newParams, scale: field.type === 'string' ? 'ordinal' : 'ratio', @@ -209,7 +214,10 @@ export const lastValueOperation: OperationDefinition< const showArrayValues = isScriptedField(field) || lastValueParams?.showArrayValues; return { - label: ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window), + label: + field.customLabel || + ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window), + customLabel: Boolean(field.customLabel), dataType: field.type as DataType, operationType: 'last_value', isBucketed: false, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx index 1942095ffa7ce..d46ab16d708fe 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx @@ -75,9 +75,8 @@ function buildMetricOperation>({ documentationDescription?: string; }) { const labelLookup = (name: string, column?: BaseIndexPatternColumn) => { - const label = ofName(name); return adjustTimeScaleLabelSuffix( - label, + name, undefined, optionalTimeScaling ? column?.timeScale : undefined, undefined, @@ -121,11 +120,19 @@ function buildMetricOperation>({ optionalTimeScaling ? (adjustTimeScaleOnOtherColumnChange(layer, thisColumnId) as T) : (layer.columns[thisColumnId] as T), - getDefaultLabel: (column, indexPattern, columns) => - labelLookup(getSafeName(column.sourceField, indexPattern), column), + getDefaultLabel: (column, indexPattern, columns) => { + const { label, customLabel } = getSafeName(column.sourceField, indexPattern); + if (customLabel) { + return label; + } + return labelLookup(label, column); + }, buildColumn: ({ field, previousColumn }, columnParams) => { return { - label: labelLookup(field.displayName, previousColumn), + label: field.customLabel + ? field.customLabel + : labelLookup(field.displayName, previousColumn), + customLabel: Boolean(field.customLabel), dataType: supportsDate && field.type === 'date' ? 'date' : 'number', operationType: type, sourceField: field.name, @@ -147,7 +154,8 @@ function buildMetricOperation>({ onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: labelLookup(field.displayName, oldColumn), + label: field.customLabel || labelLookup(field.displayName, oldColumn), + customLabel: Boolean(field.customLabel), dataType: field.type, sourceField: field.name, }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx index e725f5b394767..4406edbd5e2ce 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx @@ -107,13 +107,14 @@ export const percentileOperation: OperationDefinition< !newField.aggregationRestrictions ); }, - getDefaultLabel: (column, indexPattern, columns) => - ofName( - getSafeName(column.sourceField, indexPattern), - column.params.percentile, - column.timeShift, - column.window - ), + getDefaultLabel: (column, indexPattern, columns) => { + const { customLabel, label } = getSafeName(column.sourceField, indexPattern); + if (customLabel) { + return label; + } + + return ofName(label, column.params.percentile, column.timeShift, column.window); + }, buildColumn: ({ field, previousColumn, indexPattern }, columnParams) => { const existingPercentileParam = previousColumn && @@ -121,13 +122,13 @@ export const percentileOperation: OperationDefinition< previousColumn.params.percentile; const newPercentileParam = columnParams?.percentile ?? (existingPercentileParam || DEFAULT_PERCENTILE_VALUE); + + const { customLabel, label } = getSafeName(field.name, indexPattern); return { - label: ofName( - getSafeName(field.name, indexPattern), - newPercentileParam, - previousColumn?.timeShift, - previousColumn?.window - ), + label: customLabel + ? label + : ofName(label, newPercentileParam, previousColumn?.timeShift, previousColumn?.window), + customLabel, dataType: 'number', operationType: 'percentile', sourceField: field.name, @@ -145,12 +146,15 @@ export const percentileOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: ofName( - field.displayName, - oldColumn.params.percentile, - oldColumn.timeShift, - oldColumn.window - ), + label: + field.customLabel || + ofName( + field.displayName, + oldColumn.params.percentile, + oldColumn.timeShift, + oldColumn.window + ), + customLabel: Boolean(field.customLabel), sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx index 66bb21498706d..95071799b6ab4 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx @@ -100,13 +100,13 @@ export const percentileRanksOperation: OperationDefinition< !newField.aggregationRestrictions ); }, - getDefaultLabel: (column, indexPattern, columns) => - ofName( - getSafeName(column.sourceField, indexPattern), - column.params.value, - column.timeShift, - column.window - ), + getDefaultLabel: (column, indexPattern, columns) => { + const { label, customLabel } = getSafeName(column.sourceField, indexPattern); + if (customLabel) { + return label; + } + return ofName(label, column.params.value, column.timeShift, column.window); + }, buildColumn: ({ field, previousColumn, indexPattern }, columnParams) => { const existingPercentileRanksParam = previousColumn && @@ -114,13 +114,13 @@ export const percentileRanksOperation: OperationDefinition< previousColumn.params.value; const newPercentileRanksParam = columnParams?.value ?? (existingPercentileRanksParam || DEFAULT_PERCENTILE_RANKS_VALUE); + + const { label, customLabel } = getSafeName(field.name, indexPattern); + return { - label: ofName( - getSafeName(field.name, indexPattern), - newPercentileRanksParam, - previousColumn?.timeShift, - previousColumn?.window - ), + label: customLabel + ? label + : ofName(label, newPercentileRanksParam, previousColumn?.timeShift, previousColumn?.window), dataType: 'number', operationType: 'percentile_rank', sourceField: field.name, @@ -138,12 +138,10 @@ export const percentileRanksOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: ofName( - field.displayName, - oldColumn.params.value, - oldColumn.timeShift, - oldColumn.window - ), + label: + field.customLabel || + ofName(field.displayName, oldColumn.params.value, oldColumn.timeShift, oldColumn.window), + customLabel: Boolean(field.customLabel), sourceField: field.name, }; }, From 9d45e795dfa93da6a17cdc2060b8183466fe53d5 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 23 Aug 2022 17:50:29 +0300 Subject: [PATCH 044/129] Fixed 'insertReferences' method --- .../public/indexpattern_datasource/operations/layer_helpers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 5ce4a07afd167..9a4f3ab82f516 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -235,6 +235,7 @@ const insertReferences = ({ op: operation.type, indexPattern, field, + columnParams: { ...reference.columnParams }, visualizationGroups, targetGroup, }); From 0556994a879c7ca3cdcadffe9eed5e40bb2e53e3 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Wed, 24 Aug 2022 09:56:03 +0300 Subject: [PATCH 045/129] Revert "Fixed custom labels." This reverts commit 9bd61fbd272d38b89c89d3b1e011211b22f3fb91. --- .../operations/definitions/cardinality.tsx | 19 ++------- .../operations/definitions/count.tsx | 15 ++++--- .../operations/definitions/date_histogram.tsx | 10 ++--- .../operations/definitions/helpers.tsx | 25 +++-------- .../operations/definitions/last_value.tsx | 16 ++----- .../operations/definitions/metrics.tsx | 20 +++------ .../operations/definitions/percentile.tsx | 42 +++++++++---------- .../definitions/percentile_ranks.tsx | 36 ++++++++-------- 8 files changed, 70 insertions(+), 113 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx index 68430c3f43161..7d11fe1b00a1f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx @@ -108,21 +108,11 @@ export const cardinalityOperation: OperationDefinition< filterable: true, shiftable: true, windowable: true, - getDefaultLabel: (column, indexPattern) => { - const { customLabel, label } = getSafeName(column.sourceField, indexPattern); - if (customLabel) { - return label; - } - return ofName(label, column.timeShift, column.window); - }, + getDefaultLabel: (column, indexPattern) => + ofName(getSafeName(column.sourceField, indexPattern), column.timeShift, column.window), buildColumn({ field, previousColumn }, columnParams) { - const label = - field.customLabel || - ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window); - return { - label, - customLabel: Boolean(field.customLabel), + label: ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window), dataType: 'number', operationType: OPERATION_TYPE, scale: SCALE, @@ -195,8 +185,7 @@ export const cardinalityOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: field.customLabel || ofName(field.displayName, oldColumn.timeShift, oldColumn.window), - customLabel: Boolean(field.customLabel), + label: ofName(field.displayName, oldColumn.timeShift, oldColumn.window), sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index 265cc786505ee..8a1107a821c52 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -52,6 +52,10 @@ function ofName( timeScale: string | undefined, window: string | undefined ) { + if (field?.customLabel) { + return field.customLabel; + } + return adjustTimeScaleLabelSuffix( field?.type !== 'document' ? i18n.translate('xpack.lens.indexPattern.valueCountOf', { @@ -116,12 +120,13 @@ export const countOperation: OperationDefinition { - const { label } = getSafeName(column.sourceField, indexPattern); - return label; - }, + getDefaultLabel: (column, indexPattern) => getSafeName(column.sourceField, indexPattern), buildColumn({ field }, columnParams) { return { - label: field.customLabel || field.displayName, - customLabel: Boolean(field.customLabel), + label: field.displayName, dataType: 'date', operationType: 'date_histogram', sourceField: field.name, @@ -138,7 +134,7 @@ export const dateHistogramOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: field.customLabel || field.displayName, + label: field.displayName, sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx index 793279d3dd48b..868d5e2557e49 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx @@ -95,28 +95,13 @@ export function combineErrorMessages( return messages.length ? messages : undefined; } -export function getSafeName(name: string, indexPattern: IndexPattern) { +export function getSafeName(name: string, indexPattern: IndexPattern): string { const field = indexPattern.getFieldByName(name); - if (!field) { - return { - label: i18n.translate('xpack.lens.indexPattern.missingFieldLabel', { + return field + ? field.displayName + : i18n.translate('xpack.lens.indexPattern.missingFieldLabel', { defaultMessage: 'Missing field', - }), - customLabel: false, - }; - } - - if (field.customLabel) { - return { - label: field.customLabel, - customLabel: true, - }; - } - - return { - label: field.displayName, - customLabel: false, - }; + }); } export function isValidNumber( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx index ac351fbf82df3..afc74b043fca7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx @@ -133,13 +133,8 @@ export const lastValueOperation: OperationDefinition< displayName: i18n.translate('xpack.lens.indexPattern.lastValue', { defaultMessage: 'Last value', }), - getDefaultLabel: (column, indexPattern) => { - const { customLabel, label } = getSafeName(column.sourceField, indexPattern); - if (customLabel) { - return label; - } - return ofName(label, column.timeShift, column.window); - }, + getDefaultLabel: (column, indexPattern) => + ofName(getSafeName(column.sourceField, indexPattern), column.timeShift, column.window), input: 'field', onFieldChange: (oldColumn, field) => { const newParams = { ...oldColumn.params }; @@ -152,7 +147,7 @@ export const lastValueOperation: OperationDefinition< return { ...oldColumn, dataType: field.type as DataType, - label: field.customLabel || ofName(field.displayName, oldColumn.timeShift, oldColumn.window), + label: ofName(field.displayName, oldColumn.timeShift, oldColumn.window), sourceField: field.name, params: newParams, scale: field.type === 'string' ? 'ordinal' : 'ratio', @@ -214,10 +209,7 @@ export const lastValueOperation: OperationDefinition< const showArrayValues = isScriptedField(field) || lastValueParams?.showArrayValues; return { - label: - field.customLabel || - ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window), - customLabel: Boolean(field.customLabel), + label: ofName(field.displayName, previousColumn?.timeShift, previousColumn?.window), dataType: field.type as DataType, operationType: 'last_value', isBucketed: false, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx index d46ab16d708fe..1942095ffa7ce 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx @@ -75,8 +75,9 @@ function buildMetricOperation>({ documentationDescription?: string; }) { const labelLookup = (name: string, column?: BaseIndexPatternColumn) => { + const label = ofName(name); return adjustTimeScaleLabelSuffix( - name, + label, undefined, optionalTimeScaling ? column?.timeScale : undefined, undefined, @@ -120,19 +121,11 @@ function buildMetricOperation>({ optionalTimeScaling ? (adjustTimeScaleOnOtherColumnChange(layer, thisColumnId) as T) : (layer.columns[thisColumnId] as T), - getDefaultLabel: (column, indexPattern, columns) => { - const { label, customLabel } = getSafeName(column.sourceField, indexPattern); - if (customLabel) { - return label; - } - return labelLookup(label, column); - }, + getDefaultLabel: (column, indexPattern, columns) => + labelLookup(getSafeName(column.sourceField, indexPattern), column), buildColumn: ({ field, previousColumn }, columnParams) => { return { - label: field.customLabel - ? field.customLabel - : labelLookup(field.displayName, previousColumn), - customLabel: Boolean(field.customLabel), + label: labelLookup(field.displayName, previousColumn), dataType: supportsDate && field.type === 'date' ? 'date' : 'number', operationType: type, sourceField: field.name, @@ -154,8 +147,7 @@ function buildMetricOperation>({ onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: field.customLabel || labelLookup(field.displayName, oldColumn), - customLabel: Boolean(field.customLabel), + label: labelLookup(field.displayName, oldColumn), dataType: field.type, sourceField: field.name, }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx index 4406edbd5e2ce..e725f5b394767 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx @@ -107,14 +107,13 @@ export const percentileOperation: OperationDefinition< !newField.aggregationRestrictions ); }, - getDefaultLabel: (column, indexPattern, columns) => { - const { customLabel, label } = getSafeName(column.sourceField, indexPattern); - if (customLabel) { - return label; - } - - return ofName(label, column.params.percentile, column.timeShift, column.window); - }, + getDefaultLabel: (column, indexPattern, columns) => + ofName( + getSafeName(column.sourceField, indexPattern), + column.params.percentile, + column.timeShift, + column.window + ), buildColumn: ({ field, previousColumn, indexPattern }, columnParams) => { const existingPercentileParam = previousColumn && @@ -122,13 +121,13 @@ export const percentileOperation: OperationDefinition< previousColumn.params.percentile; const newPercentileParam = columnParams?.percentile ?? (existingPercentileParam || DEFAULT_PERCENTILE_VALUE); - - const { customLabel, label } = getSafeName(field.name, indexPattern); return { - label: customLabel - ? label - : ofName(label, newPercentileParam, previousColumn?.timeShift, previousColumn?.window), - customLabel, + label: ofName( + getSafeName(field.name, indexPattern), + newPercentileParam, + previousColumn?.timeShift, + previousColumn?.window + ), dataType: 'number', operationType: 'percentile', sourceField: field.name, @@ -146,15 +145,12 @@ export const percentileOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: - field.customLabel || - ofName( - field.displayName, - oldColumn.params.percentile, - oldColumn.timeShift, - oldColumn.window - ), - customLabel: Boolean(field.customLabel), + label: ofName( + field.displayName, + oldColumn.params.percentile, + oldColumn.timeShift, + oldColumn.window + ), sourceField: field.name, }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx index 95071799b6ab4..66bb21498706d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx @@ -100,13 +100,13 @@ export const percentileRanksOperation: OperationDefinition< !newField.aggregationRestrictions ); }, - getDefaultLabel: (column, indexPattern, columns) => { - const { label, customLabel } = getSafeName(column.sourceField, indexPattern); - if (customLabel) { - return label; - } - return ofName(label, column.params.value, column.timeShift, column.window); - }, + getDefaultLabel: (column, indexPattern, columns) => + ofName( + getSafeName(column.sourceField, indexPattern), + column.params.value, + column.timeShift, + column.window + ), buildColumn: ({ field, previousColumn, indexPattern }, columnParams) => { const existingPercentileRanksParam = previousColumn && @@ -114,13 +114,13 @@ export const percentileRanksOperation: OperationDefinition< previousColumn.params.value; const newPercentileRanksParam = columnParams?.value ?? (existingPercentileRanksParam || DEFAULT_PERCENTILE_RANKS_VALUE); - - const { label, customLabel } = getSafeName(field.name, indexPattern); - return { - label: customLabel - ? label - : ofName(label, newPercentileRanksParam, previousColumn?.timeShift, previousColumn?.window), + label: ofName( + getSafeName(field.name, indexPattern), + newPercentileRanksParam, + previousColumn?.timeShift, + previousColumn?.window + ), dataType: 'number', operationType: 'percentile_rank', sourceField: field.name, @@ -138,10 +138,12 @@ export const percentileRanksOperation: OperationDefinition< onFieldChange: (oldColumn, field) => { return { ...oldColumn, - label: - field.customLabel || - ofName(field.displayName, oldColumn.params.value, oldColumn.timeShift, oldColumn.window), - customLabel: Boolean(field.customLabel), + label: ofName( + field.displayName, + oldColumn.params.value, + oldColumn.timeShift, + oldColumn.window + ), sourceField: field.name, }; }, From 83060ad730a361d08b26caf1835389e9367eda10 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Wed, 24 Aug 2022 11:07:35 +0300 Subject: [PATCH 046/129] Fixed custom labels. --- .../indexpattern_datasource/indexpattern_suggestions.ts | 7 ++++++- .../indexpattern_datasource/operations/layer_helpers.ts | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 123dcce6f3664..d61d31258c267 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -37,6 +37,7 @@ import { getReferencedColumnIds, hasTermsWithManyBuckets, FormulaIndexPatternColumn, + updateColumnLabel, } from './operations'; import { hasField } from './pure_utils'; import type { IndexPatternPrivateState, IndexPatternLayer } from './types'; @@ -316,7 +317,11 @@ function createNewLayerWithMetricAggregationFromVizEditor( }); } }); - return newLayer; + let updatedLayer = newLayer; + layer.columns.forEach(({ columnId, label: customLabel }) => { + updatedLayer = updateColumnLabel({ layer: updatedLayer, columnId, customLabel }); + }); + return updatedLayer; } // Called when the user navigates from Discover to Lens (Visualize button) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 9a4f3ab82f516..a61559f5c2793 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -1263,14 +1263,14 @@ export function getMetricOperationTypes(field: IndexPatternField) { }); } -export function updateColumnLabel({ +export function updateColumnLabel({ layer, columnId, customLabel, }: { layer: IndexPatternLayer; columnId: string; - customLabel: string; + customLabel?: string; }): IndexPatternLayer { const oldColumn = layer.columns[columnId]; return { From fac12ffbc3e998c79150cdd1e0784cf0e1286d02 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Wed, 24 Aug 2022 11:25:39 +0300 Subject: [PATCH 047/129] Fixed filter ratio and derivative metrics --- .../public/convert_to_lens/lib/convert/filter_ratio.ts | 9 ++------- .../public/convert_to_lens/lib/series/metrics_columns.ts | 9 +++++++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts index ff6e3868ef871..af7ac1d1d64d2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -6,9 +6,8 @@ * Side Public License, v 1. */ -import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric, Series } from '../../../../common/types'; -import { getSiblingPipelineSeriesFormula } from '../metrics'; +import { getFilterRatioFormula } from '../metrics'; import { createFormulaColumn } from './formula'; import { FormulaColumn } from './types'; @@ -18,11 +17,7 @@ export const convertFilterRatioToFormulaColumn = ( ): FormulaColumn | null => { const currentMetric = metrics[metrics.length - 1]; - const formula = getSiblingPipelineSeriesFormula( - TSVB_METRIC_TYPES.FILTER_RATIO, - currentMetric, - metrics - ); + const formula = getFilterRatioFormula(currentMetric); if (!formula) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 20ff06fa86aba..9c2746efae2d8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -62,9 +62,14 @@ export const getMetricsColumns = ( const formulaColumn = convertMathToFormulaColumn(series, metrics); return getValidColumns(formulaColumn); } + case 'derivative': case 'moving_average': { - const movingAverageColumns = convertParentPipelineAggToColumns(series, metrics, dataView); - return getValidColumns(movingAverageColumns); + const movingAverageOrDerivativeColumns = convertParentPipelineAggToColumns( + series, + metrics, + dataView + ); + return getValidColumns(movingAverageOrDerivativeColumns); } case 'cumulative_sum': { const cumulativeSumColumns = convertToCumulativeSumColumns(series, metrics, dataView); From 6070decbf6fe2769cf2140e0a15cf0b363e44c0c Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Wed, 24 Aug 2022 13:19:59 +0300 Subject: [PATCH 048/129] fix last_value and series agg --- .../public/convert_to_lens/lib/convert/last_value.ts | 11 ++++------- .../convert_to_lens/lib/convert/static_value.ts | 1 + .../convert_to_lens/lib/series/metrics_columns.ts | 6 +++++- .../common/convert_to_lens/types/params.ts | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index 297b6bf972661..35a7866a16849 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -12,13 +12,10 @@ import { LastValueColumn } from './types'; import type { Metric, Series } from '../../../../common/types'; import { createColumn } from './column'; -const convertToLastValueParams = (metric: Metric): LastValueParams | null => - metric.order_by - ? { - sortField: metric.order_by, - showArrayValues: false, - } - : null; +const convertToLastValueParams = (metric: Metric): LastValueParams | null => ({ + sortField: metric.order_by, + showArrayValues: false, +}); export const convertToLastValueColumn = ( series: Series, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index c6e657d01acc4..7d14a27cb67ee 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -20,6 +20,7 @@ export const convertToStaticValueColumn = ( metrics: Metric[], visibleSeriesCount: number ): StaticValueColumn | null => { + // Lens support reference lines only when at least one layer data exists if (visibleSeriesCount === 1) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 9c2746efae2d8..4a9111e86e989 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -31,7 +31,11 @@ export const getMetricsColumns = ( dataView: DataView, visibleSeriesCount: number ): Column[] | null => { - const { metrics } = getSeriesAgg(series.metrics); + const { metrics, seriesAgg } = getSeriesAgg(series.metrics); + // series agg supported as collapseFn if we have split + if (seriesAgg && series.split_mode === 'everything') { + return null; + } const metricIdx = metrics.length - 1; const aggregation = metrics[metricIdx].type; const aggregationMap = SUPPORTED_METRICS[aggregation]; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/params.ts b/src/plugins/visualizations/common/convert_to_lens/types/params.ts index a3bd11f32542e..272ec8200ccfd 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/params.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/params.ts @@ -98,7 +98,7 @@ export interface CountParams { } export interface LastValueParams { - sortField: string; + sortField?: string; showArrayValues: boolean; format?: NumberValueFormat; } From 8e045ea4abe0008b2f6c76c87da9270ce8706615 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Wed, 24 Aug 2022 15:24:20 +0300 Subject: [PATCH 049/129] Added CounterRate formula support. --- .../convert_to_lens/lib/convert/column.ts | 1 + .../lib/convert/counter_rate.ts | 29 ++++++++++++++++ .../convert_to_lens/lib/convert/formula.ts | 5 +-- .../convert_to_lens/lib/convert/index.ts | 1 + .../lib/convert/parent_pipeline.ts | 1 - .../lib/metrics/counter_rate_formula.ts | 33 +++++++++++++++++++ .../convert_to_lens/lib/metrics/index.ts | 1 + .../lib/metrics/metrics_helpers.ts | 4 +-- .../lib/series/metrics_columns.ts | 5 +++ .../definitions/formula/formula.tsx | 13 +++++--- 10 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 7429239addac3..62fe6a318aa87 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import { BaseColumn, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts new file mode 100644 index 0000000000000..e39f9f1378580 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts @@ -0,0 +1,29 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { Metric, Series } from '../../../../common/types'; +import { buildCounterRateFormula } from '../metrics'; +import { createFormulaColumn } from './formula'; +import { FormulaColumn } from './types'; + +export const convertToCounterRateFormulaColumn = ( + series: Series, + metrics: Metric[], + dataView: DataView +): FormulaColumn | null => { + const currentMetric = metrics[metrics.length - 1]; + + const field = currentMetric.field ? dataView.getFieldByName(currentMetric.field) : undefined; + if (!field) { + return null; + } + + const formula = buildCounterRateFormula(currentMetric, field); + return createFormulaColumn(formula, series, currentMetric); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 8f9e7f0e041d2..7318ad85ae839 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -28,7 +28,8 @@ const convertToFormulaParams = (formula: string): FormulaParams | null => ({ export const createFormulaColumn = ( mathScript: string, series: Series, - metric: Metric + metric: Metric, + formatParams: Omit = {} ): FormulaColumn | null => { const params = convertToFormulaParams(mathScript); if (!params) { @@ -39,7 +40,7 @@ export const createFormulaColumn = ( operationType: 'formula', references: [], ...createColumn(series, metric), - params, + params: { ...params, ...formatParams }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index a1bdce8a7ccb2..67a1b216aa98b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -21,5 +21,6 @@ export { convertToStaticValueColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; export { convertToDateHistogramColumn } from './date_histogram'; export { converToTermsColumn } from './terms'; +export { convertToCounterRateFormulaColumn } from './counter_rate'; export * from './types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index d0ce3559e014e..78fb451eecb00 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -113,7 +113,6 @@ export const convertMetricAggregationColumnWithoutParams = ( if (!isSupportedAggregationWithoutParams(aggregation.name)) { return null; } - const sourceField = aggregation.name !== 'count' && metric.field ? metric.field : 'document'; const field = dataView.getFieldByName(sourceField); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts new file mode 100644 index 0000000000000..77b7ab1fdc778 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts @@ -0,0 +1,33 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { DataViewField } from '@kbn/data-views-plugin/common'; +import type { Metric } from '../../../../common/types'; +import { TimeScaleValue, isTimeScaleValue } from './metrics_helpers'; + +const buildMaxFormula = (selector: string) => { + return `max(${selector})`; +}; + +const buildPickMaxPositiveFormula = (selector: string) => { + return `pick_max(${selector}, 0)`; +}; + +const buildDifferencesFormula = (selector: string, shift?: TimeScaleValue) => { + return `differences(${selector}${shift ? `, shift=${shift}` : ''})`; +}; + +export const buildCounterRateFormula = (metric: Metric, field: DataViewField) => { + const maxFormula = buildMaxFormula(field.name); + + const unit = metric.unit && isTimeScaleValue(metric.unit) ? metric.unit : undefined; + const diffOfMaxFormula = buildDifferencesFormula(maxFormula, unit); + + const counterRateFormula = buildPickMaxPositiveFormula(diffOfMaxFormula); + return counterRateFormula; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts index 9a79fb804e3ba..b11032d58f237 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts @@ -13,3 +13,4 @@ export * from './parent_pipeline_formula'; export * from './sibling_pipeline_formula'; export * from './filter_ratio_formula'; export * from './parent_pipeline_series'; +export * from './counter_rate_formula'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index fc089abfdcbe3..e24d8c2a9127a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -41,9 +41,9 @@ export const getPercentileRankSeries = ( }); }; -type TimeScaleValue = `1${TimeScaleUnit}`; +export type TimeScaleValue = `1${TimeScaleUnit}`; -const isTimeScaleValue = (unit: string): unit is TimeScaleValue => { +export const isTimeScaleValue = (unit: string): unit is TimeScaleValue => { const supportedTimeScales: TimeScaleValue[] = ['1s', '1m', '1h', '1d']; return supportedTimeScales.includes(unit as TimeScaleValue); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 20ff06fa86aba..9133148aec9ea 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -23,6 +23,7 @@ import { convertToLastValueColumn, convertToStaticValueColumn, convertMetricAggregationColumnWithoutParams, + convertToCounterRateFormulaColumn, } from '../convert'; import { getValidColumns } from './columns'; @@ -74,6 +75,10 @@ export const getMetricsColumns = ( const formulaColumn = convertFilterRatioToFormulaColumn(series, metrics); return getValidColumns(formulaColumn); } + case 'positive_rate': { + const formulaColumn = convertToCounterRateFormulaColumn(series, metrics, dataView); + return getValidColumns(formulaColumn); + } case 'positive_only': case 'avg_bucket': case 'max_bucket': diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx index 388f3abac9e5a..e123737c6d5fd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx @@ -150,10 +150,15 @@ export const formulaOperation: OperationDefinition Date: Wed, 24 Aug 2022 17:12:06 +0300 Subject: [PATCH 050/129] Fix types --- .../vis_types/timeseries/common/agg_utils.ts | 2 +- .../timeseries/common/enums/metric_types.ts | 1 - .../get_supported_fields_by_metric_type.js | 3 +- .../lib/metrics/parent_pipeline_formula.ts | 1 - .../lib/metrics/parent_pipeline_series.ts | 3 +- .../lib/metrics/supported_metrics.ts | 159 +++++++----------- .../lib/metrics/validate_metrics.ts | 35 ++-- 7 files changed, 87 insertions(+), 117 deletions(-) diff --git a/src/plugins/vis_types/timeseries/common/agg_utils.ts b/src/plugins/vis_types/timeseries/common/agg_utils.ts index 93b89d23b9793..505a326ac1aa2 100644 --- a/src/plugins/vis_types/timeseries/common/agg_utils.ts +++ b/src/plugins/vis_types/timeseries/common/agg_utils.ts @@ -179,7 +179,7 @@ export const aggs: Agg[] = [ }, }, { - id: TSVB_METRIC_TYPES.VALUE_COUNT, + id: METRIC_TYPES.VALUE_COUNT, meta: { ...aggDefaultMeta, isFilterRatioSupported: true, diff --git a/src/plugins/vis_types/timeseries/common/enums/metric_types.ts b/src/plugins/vis_types/timeseries/common/enums/metric_types.ts index 651af07905a1e..96ca940a7246e 100644 --- a/src/plugins/vis_types/timeseries/common/enums/metric_types.ts +++ b/src/plugins/vis_types/timeseries/common/enums/metric_types.ts @@ -16,7 +16,6 @@ export enum TSVB_METRIC_TYPES { STD_DEVIATION = 'std_deviation', SUM_OF_SQUARES = 'sum_of_squares', TOP_HIT = 'top_hit', - VALUE_COUNT = 'value_count', VARIANCE = 'variance', CALCULATION = 'calculation', MOVING_AVERAGE = 'moving_average', diff --git a/src/plugins/vis_types/timeseries/public/application/components/lib/get_supported_fields_by_metric_type.js b/src/plugins/vis_types/timeseries/public/application/components/lib/get_supported_fields_by_metric_type.js index c44c34b570c9a..e404245c22abb 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/lib/get_supported_fields_by_metric_type.js +++ b/src/plugins/vis_types/timeseries/public/application/components/lib/get_supported_fields_by_metric_type.js @@ -8,13 +8,12 @@ import { KBN_FIELD_TYPES } from '@kbn/data-plugin/public'; import { METRIC_TYPES } from '@kbn/data-plugin/common'; -import { TSVB_METRIC_TYPES } from '../../../../common/enums'; export function getSupportedFieldsByMetricType(type) { switch (type) { case METRIC_TYPES.CARDINALITY: return Object.values(KBN_FIELD_TYPES).filter((t) => t !== KBN_FIELD_TYPES.HISTOGRAM); - case TSVB_METRIC_TYPES.VALUE_COUNT: + case METRIC_TYPES.VALUE_COUNT: return Object.values(KBN_FIELD_TYPES); case METRIC_TYPES.AVG: case METRIC_TYPES.SUM: diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index 6ad1473bf448d..eac3eb6712ee9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -8,7 +8,6 @@ import type { Metric, MetricType } from '../../../../common/types'; import { SUPPORTED_METRICS, getFormulaFromMetric, SupportedMetric } from './supported_metrics'; -import { getFilterRatioFormula } from './filter_ratio_formula'; import { getFormulaEquivalent } from './metrics_helpers'; export const getParentPipelineSeriesFormula = ( diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index dc1c65d79e2da..091450d76bc23 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -17,7 +17,8 @@ export const computeParentSeries = ( currentMetric: Metric, subFunctionMetric: Metric, pipelineAgg: SupportedMetric, - meta?: number + meta?: number, + window?: string ) => { const aggregationMap = SUPPORTED_METRICS[aggregation]; if (!aggregationMap) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts index 48ca754729b9e..736037a3eb67c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts @@ -22,8 +22,8 @@ interface AggWithFormula { export type AggOptions = { isFullReference: boolean; isFieldRequired: boolean; - supportedPanelTypes: string[]; - supportedTimeRangeModes: string[]; + supportedPanelTypes: PANEL_TYPES[]; + supportedTimeRangeModes: TIME_RANGE_DATA_MODES[]; } & (T extends Exclude ? Agg : AggWithFormula); // list of supported TSVB aggregation types in Lens @@ -44,15 +44,15 @@ interface LocalSupportedMetrics { [METRIC_TYPES.MAX]: Metric; [METRIC_TYPES.MIN]: Metric; [METRIC_TYPES.SUM]: Metric; + [METRIC_TYPES.VALUE_COUNT]: Metric; + [TSVB_METRIC_TYPES.STD_DEVIATION]: Metric; [TSVB_METRIC_TYPES.PERCENTILE]: Metric; [TSVB_METRIC_TYPES.PERCENTILE_RANK]: Metric; - [TSVB_METRIC_TYPES.PERCENTILE_RANK]: Metric; [TSVB_METRIC_TYPES.FILTER_RATIO]: Metric; [TSVB_METRIC_TYPES.TOP_HIT]: Metric; [TSVB_METRIC_TYPES.MATH]: Metric; [TSVB_METRIC_TYPES.POSITIVE_ONLY]: Metric; [TSVB_METRIC_TYPES.STATIC]: Metric; - [TSVB_METRIC_TYPES.POSITIVE_RATE]: Metric; [TSVB_METRIC_TYPES.MOVING_AVERAGE]: Metric; } @@ -62,220 +62,187 @@ export type SupportedMetrics = LocalSupportedMetrics & { [Key in UnsupportedSupportedMetrics]?: null; }; +const supportedPanelTypes: PANEL_TYPES[] = [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N]; +const supportedTimeRangeModes: TIME_RANGE_DATA_MODES[] = [ + TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + TIME_RANGE_DATA_MODES.LAST_VALUE, +]; + export const SUPPORTED_METRICS: SupportedMetrics = { avg: { name: 'average', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, cardinality: { name: 'unique_count', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, count: { name: 'count', isFullReference: false, isFieldRequired: false, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, positive_rate: { name: 'counter_rate', isFullReference: true, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes, }, moving_average: { name: 'moving_average', isFullReference: true, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, derivative: { name: 'differences', isFullReference: true, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, cumulative_sum: { name: 'cumulative_sum', isFullReference: true, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, avg_bucket: { name: 'formula', isFullReference: true, + isFieldRequired: true, isFormula: true, formula: 'overall_average', - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, max_bucket: { name: 'formula', isFullReference: true, + isFieldRequired: true, isFormula: true, formula: 'overall_max', - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, min_bucket: { name: 'formula', isFullReference: true, + isFieldRequired: true, isFormula: true, formula: 'overall_min', - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, sum_bucket: { name: 'formula', isFullReference: true, + isFieldRequired: true, isFormula: true, formula: 'overall_sum', - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, max: { name: 'max', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, min: { name: 'min', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, percentile: { name: 'percentile', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, percentile_rank: { name: 'percentile_rank', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, sum: { name: 'sum', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, filter_ratio: { name: 'formula', isFullReference: false, isFormula: true, formula: 'filter_ratio', - - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + isFieldRequired: false, + supportedPanelTypes, + supportedTimeRangeModes, }, top_hit: { name: 'last_value', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, math: { name: 'formula', isFormula: true, formula: 'math', + isFullReference: false, isFieldRequired: false, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, positive_only: { name: 'formula', isFullReference: true, + isFieldRequired: true, isFormula: true, formula: 'pick_max', - supportedPanelTypes: [PANEL_TYPES.TIMESERIES], - supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE], + supportedPanelTypes: [PANEL_TYPES.TIMESERIES] as PANEL_TYPES[], + supportedTimeRangeModes: [TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE] as TIME_RANGE_DATA_MODES[], }, static: { name: 'static_value', isFullReference: true, isFieldRequired: false, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, value_count: { name: 'count', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, std_deviation: { name: 'standard_deviation', isFullReference: false, isFieldRequired: true, - supportedPanelTypes: [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N], - supportedTimeRangeModes: [ - TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, - TIME_RANGE_DATA_MODES.LAST_VALUE, - ], + supportedPanelTypes, + supportedTimeRangeModes, }, } as const; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts index adcc2e9a94664..bd23e63fc99ac 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.ts @@ -6,35 +6,40 @@ * Side Public License, v 1. */ -import { Metric } from '../../../../common/types'; +import { Metric, MetricType } from '../../../../common/types'; +import { PANEL_TYPES } from '../../../../common/enums'; import { SUPPORTED_METRICS } from '.'; const isMetricValid = ( - metricType: string, - panelType: string, + metricType: MetricType, + panelType: PANEL_TYPES, field?: string, timeRangeMode?: string ) => { - const isMetricSupported = SUPPORTED_METRICS[metricType]; - if (!isMetricSupported) { + const metric = SUPPORTED_METRICS[metricType]; + if (!metric) { return false; } - const isPanelTypeSupported = - SUPPORTED_METRICS[metricType].supportedPanelTypes.includes(panelType); + const isPanelTypeSupported = metric.supportedPanelTypes.includes(panelType); const isTimeRangeModeSupported = - !timeRangeMode || SUPPORTED_METRICS[metricType].supportedTimeRangeModes.includes(timeRangeMode); - return ( - isPanelTypeSupported && - isTimeRangeModeSupported && - (!SUPPORTED_METRICS[metricType].isFieldRequired || field) - ); + !timeRangeMode || (metric.supportedTimeRangeModes as string[]).includes(timeRangeMode); + return isPanelTypeSupported && isTimeRangeModeSupported && (!metric.isFieldRequired || field); }; -export const isValidMetrics = (metrics: Metric[], panelType: string, timeRangeMode?: string) => { +export const isValidMetrics = ( + metrics: Metric[], + panelType: PANEL_TYPES, + timeRangeMode?: string +) => { return metrics.every((metric) => { const isMetricAggValid = metric.type !== 'filter_ratio' || - isMetricValid(metric.metric_agg || 'count', panelType, metric.field, timeRangeMode); + isMetricValid( + (metric.metric_agg as MetricType) || 'count', + panelType, + metric.field, + timeRangeMode + ); return ( metric.type === 'series_agg' || (isMetricValid(metric.type, panelType, metric.field, timeRangeMode) && isMetricAggValid) From 3e2d94394deb028de92c99870ef93ab2d7e40ff0 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Wed, 24 Aug 2022 17:16:19 +0300 Subject: [PATCH 051/129] Replaced usage of timeseries. --- .../vis_types/timeseries/public/convert_to_lens/index.ts | 6 ++---- .../vis_types/timeseries/public/convert_to_lens/types.ts | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts index 071001381f0f1..9bd26cd54655d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts @@ -10,12 +10,10 @@ import type { Panel } from '../../common/types'; import { PANEL_TYPES } from '../../common/enums'; import { ConvertTsvbToLensVisualization } from './types'; -const getConvertFnByType = ( - type: PANEL_TYPES -): Promise | undefined => { +const getConvertFnByType = (type: PANEL_TYPES) => { const convertionFns: { [key in PANEL_TYPES]?: () => Promise } = { [PANEL_TYPES.TIMESERIES]: async () => { - const { convertToLens } = await import('./timeseries'); + const { convertToLens } = await import('./timeseries/new.index'); return convertToLens; }, }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index 46e8c33fd26e8..c5e4ed1109db6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -7,13 +7,13 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; -import { NavigateToLensContext } from '@kbn/visualizations-plugin/public'; +import { NavigateToLensContext, XYConfiguration } from '@kbn/visualizations-plugin/common'; import type { Metric, Panel, Series } from '../../common/types'; import { Column } from './lib/convert'; export type ConvertTsvbToLensVisualization = ( model: Panel -) => Promise; +) => Promise | null>; export interface Filter { kql?: string | { [key: string]: any } | undefined; From 12669a3caee4241a468f7e325ffbdd7a4add1cd4 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Wed, 24 Aug 2022 19:22:33 +0300 Subject: [PATCH 052/129] Added window everywhere. --- .../public/convert_to_lens/index.ts | 2 +- .../convert_to_lens/lib/convert/column.ts | 10 +- .../lib/convert/cumulative_sum.ts | 10 +- .../lib/convert/filter_ratio.ts | 5 +- .../convert_to_lens/lib/convert/formula.ts | 28 +++-- .../convert_to_lens/lib/convert/last_value.ts | 5 +- .../lib/convert/parent_pipeline.ts | 44 ++++--- .../convert_to_lens/lib/convert/percentile.ts | 10 +- .../lib/convert/percentile_rank.ts | 10 +- .../lib/convert/static_value.ts | 5 +- .../lib/series/buckets_columns.ts | 9 +- .../lib/series/metrics_columns.ts | 27 +++-- .../lib/split_chart/date_histogram.ts | 5 +- .../public/convert_to_lens/top_n/new.index.ts | 110 ++++++++++++++++++ .../public/convert_to_lens/types.ts | 3 +- 15 files changed, 218 insertions(+), 65 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts index 46be316f19ce3..462617ba784e8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts @@ -18,7 +18,7 @@ const getConvertFnByType = (type: PANEL_TYPES) => { return convertToLens; }, [PANEL_TYPES.TOP_N]: async () => { - const { convertToLens } = await import('./top_n'); + const { convertToLens } = await import('./top_n/new.index'); return convertToLens; }, }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 62fe6a318aa87..3d268c4f9872c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -27,14 +27,15 @@ export const createColumn = ( metric: Metric, field?: DataViewField, isBucketed: boolean = false, - isSplit: boolean = false + isSplit: boolean = false, + window?: string ): GeneralColumnWithMeta => ({ columnId: uuid(), dataType: (field?.type as DataType) ?? undefined, label: series.label, isBucketed, isSplit, - window: metric.window?.toString(), + window, filter: series.filter, timeScale: getTimeScale(metric), meta: { metricId: metric.id }, @@ -44,8 +45,9 @@ export const convertMetricsToColumns = ( series: Series, metrics: Metric[], dataView: DataView, - convertToFn: ConvertToColumnsFn -) => metrics.flatMap((metric) => convertToFn(series, metric, dataView)); + convertToFn: ConvertToColumnsFn, + window?: string +) => metrics.flatMap((metric) => convertToFn(series, metric, dataView, window)); export const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { if ((column as ColumnWithMeta).meta) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index 59b6d5b291979..8c023ac35a81c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -16,7 +16,8 @@ import { computeParentPipelineColumns } from './parent_pipeline'; export const convertToCumulativeSumColumns = ( series: Series, metrics: Metric[], - dataView: DataView + dataView: DataView, + window?: string ) => { const currentMetric = metrics[metrics.length - 1]; if (!currentMetric) { @@ -43,7 +44,8 @@ export const convertToCumulativeSumColumns = ( subFunctionMetric, pipelineAgg, currentMetric.type, - metaValue + metaValue, + window ); if (!formula) { return null; @@ -62,7 +64,9 @@ export const convertToCumulativeSumColumns = ( currentMetric, dataView, subFunctionMetric, - pipelineAgg + pipelineAgg, + undefined, + window ); } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts index af7ac1d1d64d2..66b3dadf57a48 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -13,11 +13,12 @@ import { FormulaColumn } from './types'; export const convertFilterRatioToFormulaColumn = ( series: Series, - metrics: Metric[] + metrics: Metric[], + window?: string ): FormulaColumn | null => { const currentMetric = metrics[metrics.length - 1]; - const formula = getFilterRatioFormula(currentMetric); + const formula = getFilterRatioFormula(currentMetric, window); if (!formula) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 7318ad85ae839..18b06c18a1eeb 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -48,7 +48,8 @@ const convertFormulaScriptForPercentileAggs = ( mathScript: string, variables: Exclude, metric: Metric, - allAggMetrics: Metric[] + allAggMetrics: Metric[], + window?: string ) => { variables.forEach((variable) => { const [_, meta] = variable?.field?.split('[') ?? []; @@ -56,7 +57,7 @@ const convertFormulaScriptForPercentileAggs = ( if (!metaValue) { return; } - const script = getFormulaEquivalent(metric, allAggMetrics, metaValue); + const script = getFormulaEquivalent(metric, allAggMetrics, metaValue, window); if (!script) { return; } @@ -69,9 +70,10 @@ const convertFormulaScriptForAggs = ( mathScript: string, variables: Exclude, metric: Metric, - allAggMetrics: Metric[] + allAggMetrics: Metric[], + window?: string ) => { - const script = getFormulaEquivalent(metric, allAggMetrics); + const script = getFormulaEquivalent(metric, allAggMetrics, window); if (!script) { return null; } @@ -81,7 +83,8 @@ const convertFormulaScriptForAggs = ( export const convertMathToFormulaColumn = ( series: Series, - metrics: Metric[] + metrics: Metric[], + window?: string ): FormulaColumn | null => { // find the metric idx that has math expression const mathMetric = metrics.find((metric) => metric.type === 'math'); @@ -113,9 +116,15 @@ export const convertMathToFormulaColumn = ( // should treat percentiles differently if (notMathMetric.type === 'percentile' || notMathMetric.type === 'percentile_rank') { - script = convertFormulaScriptForPercentileAggs(script!, variables, notMathMetric, metrics); + script = convertFormulaScriptForPercentileAggs( + script!, + variables, + notMathMetric, + metrics, + window + ); } else { - script = convertFormulaScriptForAggs(script!, variables, notMathMetric, metrics); + script = convertFormulaScriptForAggs(script!, variables, notMathMetric, metrics, window); } } @@ -134,11 +143,12 @@ export const convertMathToFormulaColumn = ( export const convertOtherAggsToFormulaColumn = ( aggregation: OtherFormulaAggregations, series: Series, - metrics: Metric[] + metrics: Metric[], + window?: string ): FormulaColumn | null => { const currentMetric = metrics[metrics.length - 1]; - const formula = getSiblingPipelineSeriesFormula(aggregation, currentMetric, metrics); + const formula = getSiblingPipelineSeriesFormula(aggregation, currentMetric, metrics, window); if (!formula) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index 35a7866a16849..f2b657ae49d31 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -20,7 +20,8 @@ const convertToLastValueParams = (metric: Metric): LastValueParams | null => ({ export const convertToLastValueColumn = ( series: Series, metrics: Metric[], - dataView: DataView + dataView: DataView, + window?: string ): LastValueColumn | null => { const currentMetric = metrics[metrics.length - 1]; // We can only support top_hit with size 1 @@ -44,7 +45,7 @@ export const convertToLastValueColumn = ( return { operationType: 'last_value', sourceField: field.name ?? 'document', - ...createColumn(series, currentMetric), + ...createColumn(series, currentMetric, undefined, false, false, window), params, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 78fb451eecb00..3b6b8994887c9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -108,7 +108,8 @@ export const convertMetricAggregationColumnWithoutParams = ( aggregation: SupportedMetric, series: Series, metric: Metric, - dataView: DataView + dataView: DataView, + window?: string ): MetricAggregationColumnWithoutParams | null => { if (!isSupportedAggregationWithoutParams(aggregation.name)) { return null; @@ -123,7 +124,7 @@ export const convertMetricAggregationColumnWithoutParams = ( return { operationType: aggregation.name, sourceField, - ...createColumn(series, metric, field), + ...createColumn(series, metric, field, false, false, window), params: {}, } as MetricAggregationColumnWithoutParams; }; @@ -133,7 +134,8 @@ export const convertMetricAggregationToColumn = ( series: Series, metric: Metric, dataView: DataView, - meta?: number + meta?: number, + window?: string ): MetricAggregationColumn | null => { if (!isSupportedAggregation(aggregation.name)) { return null; @@ -145,18 +147,25 @@ export const convertMetricAggregationToColumn = ( } if (aggregation.name === Operations.PERCENTILE) { - return convertToPercentileColumn(meta, series, metric, dataView); + return convertToPercentileColumn(meta, series, metric, dataView, undefined, window); } if (aggregation.name === Operations.PERCENTILE_RANK) { - return convertToPercentileRankColumn(meta?.toString() ?? '', series, metric, dataView); + return convertToPercentileRankColumn( + meta?.toString() ?? '', + series, + metric, + dataView, + undefined, + window + ); } if (aggregation.name === Operations.LAST_VALUE) { return null; } - return convertMetricAggregationColumnWithoutParams(aggregation, series, metric, dataView); + return convertMetricAggregationColumnWithoutParams(aggregation, series, metric, dataView, window); }; export const computeParentPipelineColumns = ( @@ -166,7 +175,8 @@ export const computeParentPipelineColumns = ( dataView: DataView, subFunctionMetric: Metric, pipelineAgg: SupportedMetric, - meta?: number + meta?: number, + window?: string ) => { const agg = SUPPORTED_METRICS[currentMetric.type]; if (!agg) { @@ -176,7 +186,7 @@ export const computeParentPipelineColumns = ( const aggFormula = getFormulaFromMetric(agg); if (subFunctionMetric.type === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric); + const script = getFilterRatioFormula(subFunctionMetric, window); if (!script) { return null; } @@ -189,7 +199,8 @@ export const computeParentPipelineColumns = ( series, subFunctionMetric, dataView, - meta + meta, + window ); if (!metricAggregationColumn) { @@ -209,7 +220,8 @@ const convertMovingAvgOrDerivativeToColumns = ( currentMetric: Metric, series: Series, metrics: Metric[], - dataView: DataView + dataView: DataView, + window?: string ) => { // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; @@ -233,7 +245,8 @@ const convertMovingAvgOrDerivativeToColumns = ( subFunctionMetric, pipelineAgg, currentMetric.type, - metaValue + metaValue, + window ); if (!formula) { return null; @@ -253,7 +266,8 @@ const convertMovingAvgOrDerivativeToColumns = ( dataView, subFunctionMetric, pipelineAgg, - metaValue + metaValue, + window ); } }; @@ -261,7 +275,8 @@ const convertMovingAvgOrDerivativeToColumns = ( export const convertParentPipelineAggToColumns = ( series: Series, metrics: Metric[], - dataView: DataView + dataView: DataView, + window?: string ) => { const currentMetric = metrics[metrics.length - 1]; @@ -271,7 +286,8 @@ export const convertParentPipelineAggToColumns = ( currentMetric, series, metrics, - dataView + dataView, + window ); } return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 58559462f0d6c..6eb130fdf212f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -30,7 +30,8 @@ export const convertToPercentileColumn = ( series: Series, metric: Metric, dataView: DataView, - index?: number + index?: number, + window?: string ): PercentileColumn | null => { const params = convertToPercentileParams(percentile); if (!params) { @@ -41,7 +42,7 @@ export const convertToPercentileColumn = ( if (!field) { return null; } - const commonColumnParams = createColumn(series, metric, field); + const commonColumnParams = createColumn(series, metric, field, false, false, window); return { operationType: 'percentile', sourceField: field.name, @@ -60,7 +61,8 @@ export const convertToPercentileColumn = ( export const convertToPercentileColumns = ( series: Series, metric: Metric, - dataView: DataView + dataView: DataView, + window?: string ): Array | null => { const { percentiles } = metric; @@ -69,6 +71,6 @@ export const convertToPercentileColumns = ( } return percentiles.map((p, index) => - convertToPercentileColumn(p.value, series, metric, dataView, index) + convertToPercentileColumn(p.value, series, metric, dataView, index, window) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index 7b50f417f0131..ed59a6cebc17c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -33,7 +33,8 @@ export const convertToPercentileRankColumn = ( series: Series, metric: Metric, dataView: DataView, - index?: number + index?: number, + window?: string ): PercentileRanksColumn | null => { const params = convertToPercentileRankParams(value); if (!params) { @@ -45,7 +46,7 @@ export const convertToPercentileRankColumn = ( return null; } - const commonColumnParams = createColumn(series, metric, field); + const commonColumnParams = createColumn(series, metric, field, false, false, window); return { operationType: 'percentile_rank', sourceField: field.name, @@ -64,7 +65,8 @@ export const convertToPercentileRankColumn = ( export const convertToPercentileRankColumns = ( series: Series, metric: Metric, - dataView: DataView + dataView: DataView, + window?: string ): Array | null => { const { values } = metric; @@ -73,6 +75,6 @@ export const convertToPercentileRankColumns = ( } return values.map((p, index) => - convertToPercentileRankColumn(p, series, metric, dataView, index) + convertToPercentileRankColumn(p, series, metric, dataView, index, window) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index 7d14a27cb67ee..4d0a942605b97 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -18,7 +18,8 @@ export const convertToStaticValueParams = ({ value }: Metric): StaticValueParams export const convertToStaticValueColumn = ( series: Series, metrics: Metric[], - visibleSeriesCount: number + visibleSeriesCount: number, + window?: string ): StaticValueColumn | null => { // Lens support reference lines only when at least one layer data exists if (visibleSeriesCount === 1) { @@ -28,7 +29,7 @@ export const convertToStaticValueColumn = ( return { operationType: 'static_value', references: [], - ...createColumn(series, currentMetric), + ...createColumn(series, currentMetric, undefined, false, false, window), params: convertToStaticValueParams(currentMetric), }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index ce33e78a26094..63b2e2b5a10f8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -22,14 +22,13 @@ export const isSplitWithDateHistogram = ( splitFields: string[], dataView: DataView ) => { - let splitWithDateHistogram = false; if (series.terms_field && series.split_mode === 'terms' && splitFields) { for (const f of splitFields) { const fieldType = dataView.getFieldByName(f)?.type; if (fieldType === 'date') { if (splitFields.length === 1) { - splitWithDateHistogram = true; + return true; } else { // not supported terms with several field if one of them has date type return null; @@ -37,7 +36,7 @@ export const isSplitWithDateHistogram = ( } } } - return splitWithDateHistogram; + return false; }; export const getBucketsColumns = ( @@ -65,11 +64,11 @@ export const getBucketsColumns = ( splitFields[0], true ); - return getValidColumns([dateHistogramColumn]); + return getValidColumns(dateHistogramColumn); } const termsColumn = converToTermsColumn(splitFields, series, columns, dataView, isSplit); - return getValidColumns([termsColumn]); + return getValidColumns(termsColumn); } return []; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 1657b55f20198..bf1803b93a406 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -30,7 +30,8 @@ import { getValidColumns } from './columns'; export const getMetricsColumns = ( series: Series, dataView: DataView, - visibleSeriesCount: number + visibleSeriesCount: number, + window?: string ): Column[] | null => { const { metrics, seriesAgg } = getSeriesAgg(series.metrics); // series agg supported as collapseFn if we have split @@ -50,7 +51,8 @@ export const getMetricsColumns = ( series, metrics, dataView, - convertToPercentileColumns + convertToPercentileColumns, + window ); return getValidColumns(percentileColumns); } @@ -59,12 +61,13 @@ export const getMetricsColumns = ( series, metrics, dataView, - convertToPercentileRankColumns + convertToPercentileRankColumns, + window ); return getValidColumns(percentileRankColumns); } case 'math': { - const formulaColumn = convertMathToFormulaColumn(series, metrics); + const formulaColumn = convertMathToFormulaColumn(series, metrics, window); return getValidColumns(formulaColumn); } case 'derivative': @@ -72,16 +75,17 @@ export const getMetricsColumns = ( const movingAverageOrDerivativeColumns = convertParentPipelineAggToColumns( series, metrics, - dataView + dataView, + window ); return getValidColumns(movingAverageOrDerivativeColumns); } case 'cumulative_sum': { - const cumulativeSumColumns = convertToCumulativeSumColumns(series, metrics, dataView); + const cumulativeSumColumns = convertToCumulativeSumColumns(series, metrics, dataView, window); return getValidColumns(cumulativeSumColumns); } case 'filter_ratio': { - const formulaColumn = convertFilterRatioToFormulaColumn(series, metrics); + const formulaColumn = convertFilterRatioToFormulaColumn(series, metrics, window); return getValidColumns(formulaColumn); } case 'positive_rate': { @@ -93,15 +97,15 @@ export const getMetricsColumns = ( case 'max_bucket': case 'min_bucket': case 'sum_bucket': { - const formulaColumn = convertOtherAggsToFormulaColumn(aggregation, series, metrics); + const formulaColumn = convertOtherAggsToFormulaColumn(aggregation, series, metrics, window); return getValidColumns(formulaColumn); } case 'top_hit': { - const column = convertToLastValueColumn(series, metrics, dataView); + const column = convertToLastValueColumn(series, metrics, dataView, window); return getValidColumns(column); } case 'static': { - const column = convertToStaticValueColumn(series, metrics, visibleSeriesCount); + const column = convertToStaticValueColumn(series, metrics, visibleSeriesCount, window); return getValidColumns(column); } default: { @@ -109,7 +113,8 @@ export const getMetricsColumns = ( aggregationMap, series, metrics[metricIdx], - dataView + dataView, + window ); return getValidColumns(column); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts index bad2e476ecc85..eb500457bdac4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts @@ -16,19 +16,18 @@ export const isSplitWithDateHistogram = async ( indexPatternId: string, dataViews: DataViewsPublicPluginStart ) => { - let splitWithDateHistogram = false; if (series.terms_field && series.split_mode === 'terms' && splitFields) { for (const f of splitFields) { const fieldType = await getFieldType(indexPatternId, f, dataViews); if (fieldType === 'date') { if (splitFields.length === 1) { - splitWithDateHistogram = true; + return true; } else { return null; } } } } - return splitWithDateHistogram; + return false; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts new file mode 100644 index 0000000000000..50de5e40912b5 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts @@ -0,0 +1,110 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import uuid from 'uuid'; +import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { Position } from '@elastic/charts'; +import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../common/enums'; +import { getDataViewsStart } from '../../services'; +import { getDataSourceInfo } from '../lib/datasource'; +import { getMetricsColumns, getBucketsColumns } from '../lib/series'; +import { getLayers } from '../lib/configurations/xy'; +import { getWindow, isValidMetrics } from '../lib/metrics'; +import { ConvertTsvbToLensVisualization } from '../types'; +import { Layer as ExtendedLayer, excludeMetaFromColumn } from '../lib/convert'; + +const excludeMetaFromLayers = (layers: Record): Record => { + const newLayers: Record = {}; + Object.entries(layers).forEach(([layerId, layer]) => { + const columns = layer.columns.map(excludeMetaFromColumn); + newLayers[layerId] = { ...layer, columns }; + }); + + return newLayers; +}; + +export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeRange) => { + const dataViews = getDataViewsStart(); + const extendedLayers: Record = {}; + const seriesNum = model.series.filter((series) => !series.hidden).length; + + // handle multiple layers/series + for (const [layerIdx, series] of model.series.entries()) { + if (series.hidden) { + continue; + } + + if (!isValidMetrics(series.metrics, PANEL_TYPES.TOP_N, series.time_range_mode)) { + return null; + } + + const { indexPatternId, indexPattern } = await getDataSourceInfo( + model.index_pattern, + model.time_field, + Boolean(series.override_index_pattern), + series.series_index_pattern, + dataViews + ); + + const window = + model.time_range_mode === TIME_RANGE_DATA_MODES.LAST_VALUE + ? getWindow(model.interval, timeRange) + : undefined; + + // handle multiple metrics + const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, window); + if (!metricsColumns) { + return null; + } + + const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, true); + if (bucketsColumns === null) { + return null; + } + + const layerId = uuid(); + extendedLayers[layerIdx] = { + indexPatternId, + layerId, + columns: [...metricsColumns, ...bucketsColumns], + columnOrder: [], + }; + } + + return { + type: 'lnsXY', + layers: excludeMetaFromLayers(extendedLayers), + configuration: { + layers: getLayers(extendedLayers, model), + fill: model.series[0].fill ?? 0.3, + legend: { + isVisible: Boolean(model.show_legend), + showSingleSeries: Boolean(model.show_legend), + position: (model.legend_position as Position) ?? Position.Right, + shouldTruncate: Boolean(model.truncate_legend), + maxLines: model.max_lines_legend ?? 1, + }, + gridLinesVisibility: { + x: false, + yLeft: false, + yRight: false, + }, + tickLabelsVisibility: { + x: true, + yLeft: false, + yRight: false, + }, + axisTitlesVisibility: { + x: false, + yLeft: false, + yRight: false, + }, + valueLabels: 'show', + }, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index efac1fa996ad3..5dababb63a7f6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -25,5 +25,6 @@ export interface Filter { export type ConvertToColumnsFn = ( series: Series, metric: Metric, - dataView: DataView + dataView: DataView, + window?: string ) => Array | null; From 9e9593c3aa5a8b5ed5f849cb461b35aebf8ba3f0 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 25 Aug 2022 14:41:18 +0300 Subject: [PATCH 053/129] Add std_deviation and value_count, fix some issues --- .../convert_to_lens/lib/convert/formula.ts | 2 +- .../convert_to_lens/lib/convert/index.ts | 1 + .../lib/convert/parent_pipeline.ts | 8 ++- .../lib/convert/std_deviation.ts | 63 +++++++++++++++++++ .../lib/datasource/get_datasource_info.ts | 3 +- .../lib/metrics/metrics_helpers.ts | 31 ++++++--- .../lib/series/metrics_columns.ts | 5 ++ .../convert_to_lens/timeseries/new.index.ts | 7 +++ .../public/convert_to_lens/top_n/new.index.ts | 16 +++-- .../indexpattern_suggestions.ts | 2 +- 10 files changed, 114 insertions(+), 24 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 18b06c18a1eeb..8b288a7708ea2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -73,7 +73,7 @@ const convertFormulaScriptForAggs = ( allAggMetrics: Metric[], window?: string ) => { - const script = getFormulaEquivalent(metric, allAggMetrics, window); + const script = getFormulaEquivalent(metric, allAggMetrics, undefined, window); if (!script) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 67a1b216aa98b..e51849c11b2c0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -22,5 +22,6 @@ export { convertToFiltersColumn } from './filters'; export { convertToDateHistogramColumn } from './date_histogram'; export { converToTermsColumn } from './terms'; export { convertToCounterRateFormulaColumn } from './counter_rate'; +export { convertToStandartDeviationColumn } from './std_deviation'; export * from './types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 3b6b8994887c9..684cb7e5340bb 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -47,7 +47,8 @@ type MetricAggregationWithoutParams = | typeof Operations.COUNTER_RATE | typeof Operations.MAX | typeof Operations.MIN - | typeof Operations.SUM; + | typeof Operations.SUM + | typeof Operations.STANDARD_DEVIATION; type MetricAggregation = | MetricAggregationWithoutParams @@ -85,6 +86,7 @@ const SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS: MetricAggregationWithoutParams[] = Operations.MAX, Operations.MIN, Operations.SUM, + Operations.STANDARD_DEVIATION, ]; const SUPPORTED_METRIC_AGGS: MetricAggregation[] = [ @@ -114,10 +116,10 @@ export const convertMetricAggregationColumnWithoutParams = ( if (!isSupportedAggregationWithoutParams(aggregation.name)) { return null; } - const sourceField = aggregation.name !== 'count' && metric.field ? metric.field : 'document'; + const sourceField = aggregation.isFieldRequired && metric.field ? metric.field : 'document'; const field = dataView.getFieldByName(sourceField); - if (!field && aggregation.name !== 'count') { + if (!field && aggregation.isFieldRequired) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts new file mode 100644 index 0000000000000..989ba9d6839a9 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts @@ -0,0 +1,63 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DataView } from '@kbn/data-views-plugin/common'; +import type { Metric, Series } from '../../../../common/types'; +import { getFormulaEquivalent, SUPPORTED_METRICS } from '../metrics'; +import { createFormulaColumn } from './formula'; +import { convertMetricAggregationColumnWithoutParams } from './parent_pipeline'; + +const createStandartDeviationFormulaColumn = ( + series: Series, + currentMetric: Metric, + metrics: Metric[], + window?: string +) => { + const script = getFormulaEquivalent(currentMetric, metrics, undefined, window); + if (!script) return null; + return createFormulaColumn(script, series, currentMetric); +}; + +export const convertToStandartDeviationColumn = ( + series: Series, + metrics: Metric[], + dataView: DataView, + window?: string +) => { + const currentMetric = metrics[metrics.length - 1]; + + const field = currentMetric.field ? dataView.getFieldByName(currentMetric.field) : undefined; + if (!field) { + return null; + } + + const columns = []; + + if (currentMetric.mode === 'upper' || currentMetric.mode === 'lower') { + columns.push(createStandartDeviationFormulaColumn(series, currentMetric, metrics, window)); + } else if (currentMetric.mode === 'band') { + [ + { ...currentMetric, mode: 'upper' }, + { ...currentMetric, mode: 'lower' }, + ].forEach((metric) => { + columns.push(createStandartDeviationFormulaColumn(series, metric, metrics, window)); + }); + } else { + columns.push( + convertMetricAggregationColumnWithoutParams( + SUPPORTED_METRICS.std_deviation, + series, + currentMetric, + dataView, + window + ) + ); + } + + return columns; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts index 5a9b74b7a41c3..5e8bcb0416caa 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts @@ -17,6 +17,7 @@ export const getDataSourceInfo = async ( modelTimeField: string | undefined, isOverwritten: boolean, overwrittenIndexPattern: IndexPatternValue | undefined, + seriesTimeField: string | undefined, dataViews: DataViewsPublicPluginStart ) => { let indexPatternId = @@ -31,7 +32,7 @@ export const getDataSourceInfo = async ( if (indexPattern) { indexPatternId = indexPattern.id ?? ''; - timeField = indexPattern.timeFieldName; + timeField = seriesTimeField ?? indexPattern.timeFieldName; } } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 8cbf0d0deea3e..db8bb7f45f22b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -12,7 +12,8 @@ import dateMath from '@kbn/datemath'; import { TimeRange, UI_SETTINGS } from '@kbn/data-plugin/common'; import { TimeScaleUnit } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { getUISettings } from '../../../services'; -import type { Metric, MetricType } from '../../../../common/types'; +import type { Metric, MetricType, Panel, Series } from '../../../../common/types'; +import { TIME_RANGE_DATA_MODES } from '../../../../common/enums'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; @@ -53,7 +54,19 @@ export const getPercentileRankSeries = ( }); }; -export const getWindow = (interval?: string, timeRange?: TimeRange) => { +const shouldCalculateWindow = (timeRangeMode?: string) => { + return timeRangeMode === TIME_RANGE_DATA_MODES.LAST_VALUE; +}; + +export const getWindow = (model: Panel, series: Series, timeRange?: TimeRange) => { + if ( + !shouldCalculateWindow( + series.override_index_pattern ? series.time_range_mode : model.time_range_mode + ) + ) { + return undefined; + } + const interval = series.override_index_pattern ? series.series_interval : model.interval; let window = interval || '1h'; if (timeRange && !interval) { @@ -137,12 +150,12 @@ export const getFormulaEquivalent = ( return `${aggFormula}()`; } case 'percentile': { - return `${aggregation}(${currentMetric.field}${ + return `${aggFormula}(${currentMetric.field}${ metaValue ? `, percentile=${metaValue}` : '' }${addTimeRangeToFormula(window)})`; } case 'percentile_rank': { - return `${aggregation}(${currentMetric.field}${ + return `${aggFormula}(${currentMetric.field}${ metaValue ? `, value=${metaValue}` : '' }${addTimeRangeToFormula(window)})`; } @@ -168,7 +181,7 @@ export const getFormulaEquivalent = ( ); } case 'positive_rate': { - return `${aggregation}(max(${currentMetric.field}${addTimeRangeToFormula(window)}))`; + return `${aggFormula}(max(${currentMetric.field}${addTimeRangeToFormula(window)}))`; } case 'filter_ratio': { return getFilterRatioFormula(currentMetric, window); @@ -180,17 +193,17 @@ export const getFormulaEquivalent = ( if (currentMetric.mode === 'lower') { return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) - ${ currentMetric.sigma || 1.5 - } * ${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(window)})`; } if (currentMetric.mode === 'upper') { return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) + ${ currentMetric.sigma || 1.5 - } * ${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(window)})`; } - return `${aggregation}(${currentMetric.field})`; + return `${aggFormula}(${currentMetric.field})`; } default: { - return `${aggregation}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + return `${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(window)})`; } } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index bf1803b93a406..001a704811a12 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -24,6 +24,7 @@ import { convertToStaticValueColumn, convertMetricAggregationColumnWithoutParams, convertToCounterRateFormulaColumn, + convertToStandartDeviationColumn, } from '../convert'; import { getValidColumns } from './columns'; @@ -108,6 +109,10 @@ export const getMetricsColumns = ( const column = convertToStaticValueColumn(series, metrics, visibleSeriesCount, window); return getValidColumns(column); } + case 'std_deviation': { + const column = convertToStandartDeviationColumn(series, metrics, dataView, window); + return getValidColumns(column); + } default: { const column = convertMetricAggregationColumnWithoutParams( aggregationMap, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 748e57a887e6b..5c568ebbddbae 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -14,6 +14,7 @@ import { } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import { Panel } from '../../../common/types'; +import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getMetricsColumns, getBucketsColumns } from '../lib/series'; @@ -23,6 +24,7 @@ import { convertToDateHistogramColumn, excludeMetaFromColumn, } from '../lib/convert'; +import { isValidMetrics } from '../lib/metrics'; const excludeMetaFromLayers = (layers: Record): Record => { const newLayers: Record = {}; @@ -47,11 +49,16 @@ export const convertToLens = async ( continue; } + if (!isValidMetrics(series.metrics, PANEL_TYPES.TIMESERIES)) { + return null; + } + const { indexPatternId, indexPattern, timeField } = await getDataSourceInfo( model.index_pattern, model.time_field, Boolean(series.override_index_pattern), series.series_index_pattern, + series.series_time_field, dataViews ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts index 50de5e40912b5..3a06da582f186 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts @@ -9,7 +9,7 @@ import uuid from 'uuid'; import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { Position } from '@elastic/charts'; -import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../common/enums'; +import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getMetricsColumns, getBucketsColumns } from '../lib/series'; @@ -48,13 +48,11 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR model.time_field, Boolean(series.override_index_pattern), series.series_index_pattern, + series.series_time_field, dataViews ); - const window = - model.time_range_mode === TIME_RANGE_DATA_MODES.LAST_VALUE - ? getWindow(model.interval, timeRange) - : undefined; + const window = getWindow(model, series, timeRange); // handle multiple metrics const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, window); @@ -62,7 +60,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR return null; } - const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, true); + const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, false); if (bucketsColumns === null) { return null; } @@ -89,17 +87,17 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR shouldTruncate: Boolean(model.truncate_legend), maxLines: model.max_lines_legend ?? 1, }, - gridLinesVisibility: { + gridlinesVisibilitySettings: { x: false, yLeft: false, yRight: false, }, - tickLabelsVisibility: { + tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false, }, - axisTitlesVisibility: { + axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: false, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index d61d31258c267..4beb84e1683a5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -225,7 +225,7 @@ function getParams(column: Column) { ...column.params, filter: column.filter, shift: column.timeShift, - window: column.window, + ...(column.window && { window: column.window }), }; } From 7fae45ec7c6360bde428de1fb95636f15667670c Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 25 Aug 2022 18:42:17 +0300 Subject: [PATCH 054/129] Fix interval for date_histogram and fix getting filter for metrics and difference --- .../public/convert_to_lens/lib/convert/date_histogram.ts | 6 +++++- .../operations/definitions/calculations/differences.tsx | 2 +- .../operations/definitions/metrics.tsx | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts index 1793f936fee72..aeea7e96b843f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts @@ -20,9 +20,13 @@ import { DateHistogramParams, DataType } from '@kbn/visualizations-plugin/common import { DateHistogramColumn } from './types'; import type { Panel, Series } from '../../../../common/types'; +const getInterval = (interval?: string) => { + return interval && !interval?.includes('=') ? interval : 'auto'; +}; + export const convertToDateHistogramParams = (model: Panel, series: Series): DateHistogramParams => { return { - interval: model.interval && !model.interval?.includes('=') ? model.interval : 'auto', + interval: getInterval(series.override_index_pattern ? series.series_interval : model.interval), dropPartials: series.override_index_pattern ? series.series_drop_last_bucket > 0 : model.drop_last_bucket > 0, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx index 2c4ab56d7e223..0aa45786d0501 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx @@ -85,7 +85,7 @@ export const derivativeOperation: OperationDefinition< scale: 'ratio', references: referenceIds, timeScale, - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter ?? getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, params: getFormatFromPreviousColumn(previousColumn), }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx index 1942095ffa7ce..15f3fc265a626 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx @@ -132,7 +132,7 @@ function buildMetricOperation>({ isBucketed: false, scale: 'ratio', timeScale: optionalTimeScaling ? previousColumn?.timeScale : undefined, - filter: getFilter(previousColumn, columnParams), + filter: columnParams?.filter ?? getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { From afe393dbcbc5ec693f89dd6e258f760d9cacd7ef Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 25 Aug 2022 20:16:57 +0300 Subject: [PATCH 055/129] Fix tests for 'getDatasourceSuggestionsForVisualizeCharts' except test for 'format' --- .../indexpattern_suggestions.test.tsx | 286 +++++++++++------- 1 file changed, 169 insertions(+), 117 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index e90ed2c781d5a..178a744592607 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -4,7 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import type { + Layer, + TermsColumn, + FiltersColumn, + FormulaColumn, + StaticValueColumn, + CountColumn, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; import { DatasourceSuggestion } from '../types'; import { generateId } from '../id_generator'; import type { IndexPatternPrivateState } from './types'; @@ -1503,27 +1510,32 @@ describe('IndexPattern Data Source suggestions', () => { describe('#getDatasourceSuggestionsForVisualizeCharts', () => { const context = [ { - indexPatternId: '1', - xFieldName: 'timestamp', - xMode: 'date_histogram', - chartType: 'area', - axisPosition: 'left', - palette: { - name: 'default', - type: 'palette', - }, - metrics: [ + layerId: 'test', + columnOrder: [], + columns: [ { - agg: 'count', - isFullReference: false, - fieldName: 'document', + operationType: 'count', + isBucketed: false, + columnId: 'column-id-1', + sourceField: 'document', + isSplit: false, params: {}, - color: '#68BC00', + }, + { + operationType: 'date_histogram', + isBucketed: true, + columnId: 'column-id-2', + dataType: 'date', + sourceField: 'timestamp', + isSplit: false, + params: { + interval: 'auto', + }, }, ], - timeInterval: 'auto', + indexPatternId: '1', }, - ] as VisualizeEditorLayersContext[]; + ] as Layer[]; function stateWithoutLayer() { return { ...testInitialState(), @@ -1558,14 +1570,14 @@ describe('IndexPattern Data Source suggestions', () => { expect.objectContaining({ state: expect.objectContaining({ layers: { - id1: expect.objectContaining({ - columnOrder: ['id3', 'id2'], + test: expect.objectContaining({ + columnOrder: ['column-id-2', 'column-id-1'], columns: { - id2: expect.objectContaining({ + 'column-id-1': expect.objectContaining({ operationType: 'count', sourceField: '___records___', }), - id3: expect.objectContaining({ + 'column-id-2': expect.objectContaining({ operationType: 'date_histogram', sourceField: 'timestamp', }), @@ -1579,13 +1591,13 @@ describe('IndexPattern Data Source suggestions', () => { isMultiRow: true, columns: [ expect.objectContaining({ - columnId: 'id3', + columnId: 'column-id-2', }), expect.objectContaining({ - columnId: 'id2', + columnId: 'column-id-1', }), ], - layerId: 'id1', + layerId: 'test', }, }) ); @@ -1595,7 +1607,13 @@ describe('IndexPattern Data Source suggestions', () => { const updatedContext = [ { ...context[0], - label: 'testLabel', + columns: [ + { + ...context[0].columns[0], + label: 'testLabel', + }, + context[0].columns[1], + ], }, ]; const suggestions = getDatasourceSuggestionsForVisualizeCharts( @@ -1608,15 +1626,15 @@ describe('IndexPattern Data Source suggestions', () => { expect.objectContaining({ state: expect.objectContaining({ layers: { - id1: expect.objectContaining({ - columnOrder: ['id3', 'id2'], + test: expect.objectContaining({ + columnOrder: ['column-id-2', 'column-id-1'], columns: { - id2: expect.objectContaining({ + 'column-id-1': expect.objectContaining({ operationType: 'count', sourceField: '___records___', label: 'testLabel', }), - id3: expect.objectContaining({ + 'column-id-2': expect.objectContaining({ operationType: 'date_histogram', sourceField: 'timestamp', }), @@ -1630,13 +1648,13 @@ describe('IndexPattern Data Source suggestions', () => { isMultiRow: true, columns: [ expect.objectContaining({ - columnId: 'id3', + columnId: 'column-id-2', }), expect.objectContaining({ - columnId: 'id2', + columnId: 'column-id-1', }), ], - layerId: 'id1', + layerId: 'test', }, }) ); @@ -1646,7 +1664,18 @@ describe('IndexPattern Data Source suggestions', () => { const updatedContext = [ { ...context[0], - format: 'bytes', + columns: [ + { + ...context[0].columns[0], + params: { + ...context[0].columns[0].params, + format: { + id: 'bytes', + }, + }, + } as CountColumn, + context[0].columns[1], + ], }, ]; const suggestions = getDatasourceSuggestionsForVisualizeCharts( @@ -1659,10 +1688,10 @@ describe('IndexPattern Data Source suggestions', () => { expect.objectContaining({ state: expect.objectContaining({ layers: { - id1: expect.objectContaining({ - columnOrder: ['id3', 'id2'], + test: expect.objectContaining({ + columnOrder: ['column-id-2', 'column-id-1'], columns: { - id2: expect.objectContaining({ + 'column-id-1': expect.objectContaining({ operationType: 'count', sourceField: '___records___', label: 'Count of records', @@ -1675,7 +1704,7 @@ describe('IndexPattern Data Source suggestions', () => { }, }), }), - id3: expect.objectContaining({ + 'column-id-2': expect.objectContaining({ operationType: 'date_histogram', sourceField: 'timestamp', }), @@ -1689,13 +1718,13 @@ describe('IndexPattern Data Source suggestions', () => { isMultiRow: true, columns: [ expect.objectContaining({ - columnId: 'id3', + columnId: 'column-id-2', }), expect.objectContaining({ - columnId: 'id2', + columnId: 'column-id-1', }), ], - layerId: 'id1', + layerId: 'test', }, }) ); @@ -1705,15 +1734,27 @@ describe('IndexPattern Data Source suggestions', () => { const updatedContext = [ { ...context[0], - splitFields: ['source'], - splitMode: 'terms', - termsParams: { - size: 10, - otherBucket: false, - orderBy: { - type: 'column', - }, - }, + columns: [ + ...context[0].columns, + { + operationType: 'terms', + label: 'Top 10 values of source', + isBucketed: true, + columnId: 'column-id-3', + dataType: 'string', + sourceField: 'source', + isSplit: true, + params: { + size: 10, + orderDirection: 'desc', + otherBucket: false, + orderBy: { + type: 'column', + columnId: 'column-id-1', + }, + }, + } as TermsColumn, + ], }, ]; const suggestions = getDatasourceSuggestionsForVisualizeCharts( @@ -1726,14 +1767,18 @@ describe('IndexPattern Data Source suggestions', () => { expect.objectContaining({ state: expect.objectContaining({ layers: { - id1: expect.objectContaining({ - columnOrder: ['id3', 'id4', 'id2'], + test: expect.objectContaining({ + columnOrder: ['column-id-3', 'column-id-2', 'column-id-1'], columns: { - id2: expect.objectContaining({ + 'column-id-1': expect.objectContaining({ operationType: 'count', sourceField: '___records___', }), - id3: expect.objectContaining({ + 'column-id-2': expect.objectContaining({ + operationType: 'date_histogram', + sourceField: 'timestamp', + }), + 'column-id-3': expect.objectContaining({ operationType: 'terms', sourceField: 'source', label: 'Top 10 values of source', @@ -1743,10 +1788,6 @@ describe('IndexPattern Data Source suggestions', () => { orderDirection: 'desc', }), }), - id4: expect.objectContaining({ - operationType: 'date_histogram', - sourceField: 'timestamp', - }), }, }), }, @@ -1757,16 +1798,16 @@ describe('IndexPattern Data Source suggestions', () => { isMultiRow: true, columns: [ expect.objectContaining({ - columnId: 'id3', + columnId: 'column-id-3', }), expect.objectContaining({ - columnId: 'id4', + columnId: 'column-id-2', }), expect.objectContaining({ - columnId: 'id2', + columnId: 'column-id-1', }), ], - layerId: 'id1', + layerId: 'test', }, }) ); @@ -1776,26 +1817,32 @@ describe('IndexPattern Data Source suggestions', () => { const updatedContext = [ { ...context[0], - splitMode: 'filters', - splitFilters: [ - { - filter: { - query: 'category.keyword : "Men\'s Clothing" ', - language: 'kuery', - }, - label: '', - color: '#68BC00', - id: 'a8d92740-7de1-11ec-b443-27e8df79881f', - }, + columns: [ + ...context[0].columns, { - filter: { - query: 'category.keyword : "Women\'s Accessories" ', - language: 'kuery', + operationType: 'filters', + isBucketed: true, + columnId: 'column-id-3', + isSplit: true, + params: { + filters: [ + { + input: { + query: 'category.keyword : "Men\'s Clothing" ', + language: 'kuery', + }, + label: '', + }, + { + input: { + query: 'category.keyword : "Women\'s Accessories" ', + language: 'kuery', + }, + label: '', + }, + ], }, - label: '', - color: '#68BC00', - id: 'ad5dc500-7de1-11ec-b443-27e8df79881f', - }, + } as FiltersColumn, ], }, ]; @@ -1809,14 +1856,18 @@ describe('IndexPattern Data Source suggestions', () => { expect.objectContaining({ state: expect.objectContaining({ layers: { - id1: expect.objectContaining({ - columnOrder: ['id4', 'id3', 'id2'], + test: expect.objectContaining({ + columnOrder: ['column-id-2', 'column-id-3', 'column-id-1'], columns: { - id2: expect.objectContaining({ + 'column-id-1': expect.objectContaining({ operationType: 'count', sourceField: '___records___', }), - id3: expect.objectContaining({ + 'column-id-2': expect.objectContaining({ + operationType: 'date_histogram', + sourceField: 'timestamp', + }), + 'column-id-3': expect.objectContaining({ operationType: 'filters', label: 'Filters', params: expect.objectContaining({ @@ -1838,10 +1889,6 @@ describe('IndexPattern Data Source suggestions', () => { ], }), }), - id4: expect.objectContaining({ - operationType: 'date_histogram', - sourceField: 'timestamp', - }), }, }), }, @@ -1852,16 +1899,16 @@ describe('IndexPattern Data Source suggestions', () => { isMultiRow: true, columns: [ expect.objectContaining({ - columnId: 'id4', + columnId: 'column-id-2', }), expect.objectContaining({ - columnId: 'id3', + columnId: 'column-id-3', }), expect.objectContaining({ - columnId: 'id2', + columnId: 'column-id-1', }), ], - layerId: 'id1', + layerId: 'test', }, }) ); @@ -1871,16 +1918,19 @@ describe('IndexPattern Data Source suggestions', () => { const updatedContext = [ { ...context[0], - metrics: [ + columns: [ { - agg: 'formula', - isFullReference: true, - fieldName: 'document', + columnId: 'column-id-1', + operationType: 'formula', + references: [], + dataType: 'number', + isBucketed: false, + isSplit: false, params: { formula: 'overall_sum(count())', }, - color: '#68BC00', - }, + } as FormulaColumn, + context[0].columns[1], ], }, ]; @@ -1894,24 +1944,24 @@ describe('IndexPattern Data Source suggestions', () => { expect.objectContaining({ state: expect.objectContaining({ layers: { - id1: expect.objectContaining({ - columnOrder: ['id3', 'id2X0', 'id2X1', 'id2'], + test: expect.objectContaining({ + columnOrder: ['column-id-2', 'column-id-1X0', 'column-id-1X1', 'column-id-1'], columns: { - id2: expect.objectContaining({ + 'column-id-1': expect.objectContaining({ operationType: 'formula', params: expect.objectContaining({ formula: 'overall_sum(count())', }), }), - id2X0: expect.objectContaining({ + 'column-id-1X0': expect.objectContaining({ operationType: 'count', label: 'Part of overall_sum(count())', }), - id2X1: expect.objectContaining({ + 'column-id-1X1': expect.objectContaining({ operationType: 'overall_sum', label: 'Part of overall_sum(count())', }), - id3: expect.objectContaining({ + 'column-id-2': expect.objectContaining({ operationType: 'date_histogram', sourceField: 'timestamp', }), @@ -1925,13 +1975,13 @@ describe('IndexPattern Data Source suggestions', () => { isMultiRow: true, columns: [ expect.objectContaining({ - columnId: 'id3', + columnId: 'column-id-2', }), expect.objectContaining({ - columnId: 'id2', + columnId: 'column-id-1', }), ], - layerId: 'id1', + layerId: 'test', }, }) ); @@ -1941,16 +1991,18 @@ describe('IndexPattern Data Source suggestions', () => { const updatedContext = [ { ...context[0], - metrics: [ + columns: [ { - agg: 'static_value', - isFullReference: true, - fieldName: 'document', + columnId: 'column-id-1', + operationType: 'static_value', + references: [], + dataType: 'number', + isBucketed: false, + isSplit: false, params: { value: '10', }, - color: '#68BC00', - }, + } as StaticValueColumn, ], }, ]; @@ -1964,10 +2016,10 @@ describe('IndexPattern Data Source suggestions', () => { expect.objectContaining({ state: expect.objectContaining({ layers: { - id1: expect.objectContaining({ - columnOrder: ['id2'], + test: expect.objectContaining({ + columnOrder: ['column-id-1'], columns: { - id2: expect.objectContaining({ + 'column-id-1': expect.objectContaining({ operationType: 'static_value', isStaticValue: true, params: expect.objectContaining({ @@ -1984,10 +2036,10 @@ describe('IndexPattern Data Source suggestions', () => { isMultiRow: false, columns: [ expect.objectContaining({ - columnId: 'id2', + columnId: 'column-id-1', }), ], - layerId: 'id1', + layerId: 'test', }, }) ); From 421c39b8d8e29b2fe3d6e7620ad3eee268f2c818 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 12:04:04 +0300 Subject: [PATCH 056/129] Refactored code. --- .../convert_to_lens/lib/convert/column.ts | 9 ++++-- .../lib/convert/cumulative_sum.ts | 6 ++-- .../lib/convert/date_histogram.ts | 3 +- .../convert_to_lens/lib/convert/formula.ts | 4 +-- .../convert_to_lens/lib/convert/last_value.ts | 2 +- .../lib/convert/parent_pipeline.ts | 30 +++++++------------ .../convert_to_lens/lib/convert/percentile.ts | 7 ++--- .../lib/convert/percentile_rank.ts | 7 ++--- .../lib/convert/static_value.ts | 5 ++-- .../lib/convert/std_deviation.ts | 2 +- .../convert_to_lens/lib/layers/get_layer.ts | 18 +++++++---- .../lib/metrics/metrics_helpers.ts | 6 ++-- .../lib/metrics/parent_pipeline_formula.ts | 8 +++-- .../lib/metrics/parent_pipeline_series.ts | 20 +++++-------- .../lib/metrics/sibling_pipeline_formula.ts | 5 +++- .../lib/series/buckets_columns.ts | 11 +++---- .../convert_to_lens/lib/series/get_series.ts | 20 +++++-------- .../lib/series/metrics_columns.ts | 2 +- .../convert_to_lens/timeseries/index.ts | 5 +--- .../convert_to_lens/timeseries/new.index.ts | 11 +++---- .../public/convert_to_lens/top_n/index.ts | 10 +++---- 21 files changed, 85 insertions(+), 106 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 3d268c4f9872c..c7a491b9371a0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -21,14 +21,17 @@ import { ColumnWithMeta, Meta, Column } from './types'; type GeneralColumn = Omit, 'operationType' | 'params'>; type GeneralColumnWithMeta = GenericColumnWithMeta; +interface ExtraColumnFields { + isBucketed?: boolean; + isSplit?: boolean; + window?: string; +} export const createColumn = ( series: Series, metric: Metric, field?: DataViewField, - isBucketed: boolean = false, - isSplit: boolean = false, - window?: string + { isBucketed = false, isSplit = false, window }: ExtraColumnFields = {} ): GeneralColumnWithMeta => ({ columnId: uuid(), dataType: (field?.type as DataType) ?? undefined, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index 8c023ac35a81c..bd55b51e67758 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -44,8 +44,7 @@ export const convertToCumulativeSumColumns = ( subFunctionMetric, pipelineAgg, currentMetric.type, - metaValue, - window + { metaValue, window } ); if (!formula) { return null; @@ -65,8 +64,7 @@ export const convertToCumulativeSumColumns = ( dataView, subFunctionMetric, pipelineAgg, - undefined, - window + { window } ); } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts index aeea7e96b843f..1a0ff798c737f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts @@ -38,8 +38,7 @@ export const convertToDateHistogramColumn = ( model: Panel, series: Series, dataView: DataView, - fieldName: string, - isSplit: boolean + { fieldName, isSplit }: { fieldName: string; isSplit: boolean } ): DateHistogramColumn | null => { const params = convertToDateHistogramParams(model, series); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 8b288a7708ea2..00570a28c80cf 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -57,7 +57,7 @@ const convertFormulaScriptForPercentileAggs = ( if (!metaValue) { return; } - const script = getFormulaEquivalent(metric, allAggMetrics, metaValue, window); + const script = getFormulaEquivalent(metric, allAggMetrics, { metaValue, window }); if (!script) { return; } @@ -73,7 +73,7 @@ const convertFormulaScriptForAggs = ( allAggMetrics: Metric[], window?: string ) => { - const script = getFormulaEquivalent(metric, allAggMetrics, undefined, window); + const script = getFormulaEquivalent(metric, allAggMetrics, { window }); if (!script) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index f2b657ae49d31..923f800c8b765 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -45,7 +45,7 @@ export const convertToLastValueColumn = ( return { operationType: 'last_value', sourceField: field.name ?? 'document', - ...createColumn(series, currentMetric, undefined, false, false, window), + ...createColumn(series, currentMetric, undefined, { window }), params, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 684cb7e5340bb..520881db9cb1e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -126,7 +126,7 @@ export const convertMetricAggregationColumnWithoutParams = ( return { operationType: aggregation.name, sourceField, - ...createColumn(series, metric, field, false, false, window), + ...createColumn(series, metric, field, { window }), params: {}, } as MetricAggregationColumnWithoutParams; }; @@ -136,8 +136,7 @@ export const convertMetricAggregationToColumn = ( series: Series, metric: Metric, dataView: DataView, - meta?: number, - window?: string + { metaValue, window }: { metaValue?: number; window?: string } = {} ): MetricAggregationColumn | null => { if (!isSupportedAggregation(aggregation.name)) { return null; @@ -149,18 +148,13 @@ export const convertMetricAggregationToColumn = ( } if (aggregation.name === Operations.PERCENTILE) { - return convertToPercentileColumn(meta, series, metric, dataView, undefined, window); + return convertToPercentileColumn(metaValue, series, metric, dataView, { window }); } if (aggregation.name === Operations.PERCENTILE_RANK) { - return convertToPercentileRankColumn( - meta?.toString() ?? '', - series, - metric, - dataView, - undefined, - window - ); + return convertToPercentileRankColumn(metaValue?.toString() ?? '', series, metric, dataView, { + window, + }); } if (aggregation.name === Operations.LAST_VALUE) { @@ -177,8 +171,7 @@ export const computeParentPipelineColumns = ( dataView: DataView, subFunctionMetric: Metric, pipelineAgg: SupportedMetric, - meta?: number, - window?: string + { metaValue, window }: { metaValue?: number; window?: string } = {} ) => { const agg = SUPPORTED_METRICS[currentMetric.type]; if (!agg) { @@ -201,8 +194,7 @@ export const computeParentPipelineColumns = ( series, subFunctionMetric, dataView, - meta, - window + { metaValue, window } ); if (!metricAggregationColumn) { @@ -247,8 +239,7 @@ const convertMovingAvgOrDerivativeToColumns = ( subFunctionMetric, pipelineAgg, currentMetric.type, - metaValue, - window + { metaValue, window } ); if (!formula) { return null; @@ -268,8 +259,7 @@ const convertMovingAvgOrDerivativeToColumns = ( dataView, subFunctionMetric, pipelineAgg, - metaValue, - window + { metaValue, window } ); } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 6eb130fdf212f..d0172e41bb963 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -30,8 +30,7 @@ export const convertToPercentileColumn = ( series: Series, metric: Metric, dataView: DataView, - index?: number, - window?: string + { index, window }: { index?: number; window?: string } = {} ): PercentileColumn | null => { const params = convertToPercentileParams(percentile); if (!params) { @@ -42,7 +41,7 @@ export const convertToPercentileColumn = ( if (!field) { return null; } - const commonColumnParams = createColumn(series, metric, field, false, false, window); + const commonColumnParams = createColumn(series, metric, field, { window }); return { operationType: 'percentile', sourceField: field.name, @@ -71,6 +70,6 @@ export const convertToPercentileColumns = ( } return percentiles.map((p, index) => - convertToPercentileColumn(p.value, series, metric, dataView, index, window) + convertToPercentileColumn(p.value, series, metric, dataView, { index, window }) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index ed59a6cebc17c..c7f4116b65b14 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -33,8 +33,7 @@ export const convertToPercentileRankColumn = ( series: Series, metric: Metric, dataView: DataView, - index?: number, - window?: string + { index, window }: { index?: number; window?: string } = {} ): PercentileRanksColumn | null => { const params = convertToPercentileRankParams(value); if (!params) { @@ -46,7 +45,7 @@ export const convertToPercentileRankColumn = ( return null; } - const commonColumnParams = createColumn(series, metric, field, false, false, window); + const commonColumnParams = createColumn(series, metric, field, { window }); return { operationType: 'percentile_rank', sourceField: field.name, @@ -75,6 +74,6 @@ export const convertToPercentileRankColumns = ( } return values.map((p, index) => - convertToPercentileRankColumn(p, series, metric, dataView, index, window) + convertToPercentileRankColumn(p, series, metric, dataView, { index, window }) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index 4d0a942605b97..59b0f8844ec5b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -18,8 +18,7 @@ export const convertToStaticValueParams = ({ value }: Metric): StaticValueParams export const convertToStaticValueColumn = ( series: Series, metrics: Metric[], - visibleSeriesCount: number, - window?: string + { visibleSeriesCount = 0, window }: { visibleSeriesCount?: number; window?: string } = {} ): StaticValueColumn | null => { // Lens support reference lines only when at least one layer data exists if (visibleSeriesCount === 1) { @@ -29,7 +28,7 @@ export const convertToStaticValueColumn = ( return { operationType: 'static_value', references: [], - ...createColumn(series, currentMetric, undefined, false, false, window), + ...createColumn(series, currentMetric, undefined, { window }), params: convertToStaticValueParams(currentMetric), }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts index 989ba9d6839a9..8a989904b718f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts @@ -18,7 +18,7 @@ const createStandartDeviationFormulaColumn = ( metrics: Metric[], window?: string ) => { - const script = getFormulaEquivalent(currentMetric, metrics, undefined, window); + const script = getFormulaEquivalent(currentMetric, metrics, { window }); if (!script) return null; return createFormulaColumn(script, series, currentMetric); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts index de4c61e54837e..2f3c7d8a28421 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts @@ -40,11 +40,19 @@ export const getLayerConfiguration = ( chartType: string, model: Panel, series: VisSeries, - splitFields: string[], - xFieldName?: string, - xMode?: string, - splitWithDateHistogram?: boolean, - window?: string + { + splitFields = [], + xFieldName, + xMode, + splitWithDateHistogram, + window, + }: { + splitFields?: string[]; + xFieldName?: string; + xMode?: string; + splitWithDateHistogram?: boolean; + window?: string; + } = {} ): VisualizeEditorLayersContext => { const layer = model.series[layerIdx]; const palette = layer.palette as PaletteOutput; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index db8bb7f45f22b..60d7abb77fdb9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -128,8 +128,7 @@ export const getPipelineAgg = (agg: MetricType) => { export const getFormulaEquivalent = ( currentMetric: Metric, metrics: Metric[], - metaValue?: number, - window?: string + { metaValue, window }: { metaValue?: number; window?: string } = {} ) => { const aggregation = SUPPORTED_METRICS[currentMetric.type]; if (!aggregation) { @@ -176,8 +175,7 @@ export const getFormulaEquivalent = ( subFunctionMetric, pipelineAgg, currentMetric.type, - metaValue, - window + { metaValue, window } ); } case 'positive_rate': { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index eac3eb6712ee9..fe3706570f11d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -15,8 +15,7 @@ export const getParentPipelineSeriesFormula = ( subFunctionMetric: Metric, pipelineAgg: SupportedMetric, aggregation: MetricType, - percentileValue?: number, - window?: string + { metaValue, window }: { metaValue?: number; window?: string } = {} ) => { let formula = ''; const aggregationMap = SUPPORTED_METRICS[aggregation]; @@ -50,7 +49,10 @@ export const getParentPipelineSeriesFormula = ( additionalSubFunction.field ?? '' }${additionalFunctionArgs ?? ''})))`; } else { - const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, percentileValue, window); + const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, { + metaValue, + window, + }); if (!subFormula) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts index 091450d76bc23..f1222b9b3add5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts @@ -17,8 +17,7 @@ export const computeParentSeries = ( currentMetric: Metric, subFunctionMetric: Metric, pipelineAgg: SupportedMetric, - meta?: number, - window?: string + { metaValue, window }: { metaValue?: number; window?: string } = {} ) => { const aggregationMap = SUPPORTED_METRICS[aggregation]; if (!aggregationMap) { @@ -50,8 +49,8 @@ export const computeParentSeries = ( params: { ...(currentMetric.window && { window: currentMetric.window }), ...(timeScale && { timeScale }), - ...(pipelineAgg.name === 'percentile' && meta && { percentile: meta }), - ...(pipelineAgg.name === 'percentile_rank' && meta && { value: meta }), + ...(pipelineAgg.name === 'percentile' && metaValue && { percentile: metaValue }), + ...(pipelineAgg.name === 'percentile_rank' && metaValue && { value: metaValue }), ...(pipelineAgg.name === 'formula' ? { formula: `${pipelineAgg.formula}(${fieldName})` } : {}), @@ -90,21 +89,16 @@ export const getParentPipelineSeries = ( subFunctionMetric, pipelineAgg, aggregation, - metaValue, - window + { metaValue, window } ); if (!formula) { return null; } return getFormulaSeries(formula); } else { - return computeParentSeries( - aggregation, - currentMetric, - subFunctionMetric, - pipelineAgg, + return computeParentSeries(aggregation, currentMetric, subFunctionMetric, pipelineAgg, { metaValue, - window - ); + window, + }); } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts index 3d064e28358cc..a07cba5a99dca 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts @@ -56,7 +56,10 @@ export const getSiblingPipelineSeriesFormula = ( } else { const nestedMetaValue = Number(nestedMeta?.replace(']', '')); - const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, nestedMetaValue, window); + const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, { + metaValue: nestedMetaValue, + window, + }); if (!subFormula) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index 63b2e2b5a10f8..932235b99e14a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -57,13 +57,10 @@ export const getBucketsColumns = ( return null; } if (isDateHistogram) { - const dateHistogramColumn = convertToDateHistogramColumn( - model, - series, - dataView, - splitFields[0], - true - ); + const dateHistogramColumn = convertToDateHistogramColumn(model, series, dataView, { + fieldName: splitFields[0], + isSplit: true, + }); return getValidColumns(dateHistogramColumn); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts index 49a9eb4d2329d..16a8e750bd819 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts @@ -102,17 +102,15 @@ export const getSeries = ( const [_, meta] = variable?.field?.split('[') ?? []; const metaValue = Number(meta?.replace(']', '')); if (!metaValue) return; - const script = getFormulaEquivalent( - currentMetric, - layerMetricsArray, + const script = getFormulaEquivalent(currentMetric, layerMetricsArray, { metaValue, - window - ); + window, + }); if (!script) return; finalScript = finalScript?.replace(`params.${variable.name}`, script); }); } else { - const script = getFormulaEquivalent(currentMetric, layerMetricsArray, undefined, window); + const script = getFormulaEquivalent(currentMetric, layerMetricsArray, { window }); if (!script) return null; const variable = variables.find((v) => v.field === currentMetric.id); finalScript = finalScript?.replaceAll(`params.${variable?.name}`, script); @@ -153,8 +151,7 @@ export const getSeries = ( subFunctionMetric, pipelineAgg, aggregation, - metaValue, - window + { metaValue, window } ); if (!formula) return null; metricsArray = getFormulaSeries(formula); @@ -164,8 +161,7 @@ export const getSeries = ( metrics[metricIdx], subFunctionMetric, pipelineAgg, - undefined, - window + { window } ); if (!series) return null; metricsArray = series; @@ -241,7 +237,7 @@ export const getSeries = ( case 'std_deviation': { const currentMetric = metrics[metricIdx]; if (currentMetric.mode === 'upper' || currentMetric.mode === 'lower') { - const script = getFormulaEquivalent(currentMetric, metrics, undefined, window); + const script = getFormulaEquivalent(currentMetric, metrics, { window }); if (!script) return null; metricsArray = getFormulaSeries(script); break; @@ -250,7 +246,7 @@ export const getSeries = ( { ...currentMetric, mode: 'upper' }, { ...currentMetric, mode: 'lower' }, ].forEach((metric) => { - const script = getFormulaEquivalent(metric, metrics, undefined, window); + const script = getFormulaEquivalent(metric, metrics, { window }); if (!script) return null; metricsArray.push(...getFormulaSeries(script)); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 001a704811a12..8bc08b418d8ae 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -106,7 +106,7 @@ export const getMetricsColumns = ( return getValidColumns(column); } case 'static': { - const column = convertToStaticValueColumn(series, metrics, visibleSeriesCount, window); + const column = convertToStaticValueColumn(series, metrics, { visibleSeriesCount, window }); return getValidColumns(column); } case 'std_deviation': { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index 9c74f7314382a..bbf3c51bdd13d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -72,10 +72,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { chartType, model, series, - splitFields, - timeField, - 'date_histogram', - splitWithDateHistogram + { splitFields, xFieldName: timeField, xMode: 'date_histogram', splitWithDateHistogram } ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts index 5c568ebbddbae..f7f5514563cb1 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts @@ -66,13 +66,10 @@ export const convertToLens = async ( return null; } - const dateHistogramColumn = convertToDateHistogramColumn( - model, - series, - indexPattern!, - timeField, - false - ); + const dateHistogramColumn = convertToDateHistogramColumn(model, series, indexPattern!, { + fieldName: timeField, + isSplit: false, + }); if (dateHistogramColumn === null) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts index 292a44aaf98d9..61d5b0948021a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -74,11 +74,11 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR 'bar_horizontal', model, series, - splitFields, - undefined, - undefined, - splitWithDateHistogram, - window + { + splitFields, + splitWithDateHistogram, + window, + } ); } From ca82caf91b10feeb52c94a3a9298252d2556f70a Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Fri, 26 Aug 2022 12:31:14 +0300 Subject: [PATCH 057/129] Refactoring 'createNewLayerWithMetricAggregationFromVizEditor' --- .../indexpattern_suggestions.test.tsx | 4 +- .../indexpattern_suggestions.ts | 62 +++++++++++-------- .../definitions/calculations/counter_rate.tsx | 2 +- .../calculations/cumulative_sum.tsx | 2 +- .../definitions/calculations/differences.tsx | 2 +- .../calculations/moving_average.tsx | 2 +- .../operations/definitions/cardinality.tsx | 2 +- .../operations/definitions/count.tsx | 2 +- .../definitions/formula/formula.tsx | 2 +- .../operations/definitions/index.ts | 7 --- .../operations/definitions/last_value.tsx | 5 +- .../operations/definitions/metrics.tsx | 2 +- .../operations/definitions/percentile.tsx | 2 +- .../definitions/percentile_ranks.tsx | 2 +- .../operations/layer_helpers.ts | 4 +- 15 files changed, 51 insertions(+), 51 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index 178a744592607..fc55f200f2320 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -1515,6 +1515,7 @@ describe('IndexPattern Data Source suggestions', () => { columns: [ { operationType: 'count', + dataType: 'number', isBucketed: false, columnId: 'column-id-1', sourceField: 'document', @@ -1698,9 +1699,6 @@ describe('IndexPattern Data Source suggestions', () => { params: expect.objectContaining({ format: { id: 'bytes', - params: { - decimals: 0, - }, }, }), }), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 4beb84e1683a5..3bc598a5fdd2b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -38,12 +38,14 @@ import { hasTermsWithManyBuckets, FormulaIndexPatternColumn, updateColumnLabel, + ColumnAdvancedParams, } from './operations'; import { hasField } from './pure_utils'; import type { IndexPatternPrivateState, IndexPatternLayer } from './types'; import { documentField } from './document_field'; import { OperationDefinition } from './operations/definitions'; import { insertOrReplaceFormulaColumn } from './operations/definitions/formula'; + export type IndexPatternSuggestion = DatasourceSuggestion; interface ColumnChange { @@ -54,6 +56,8 @@ interface ColumnChange { visualizationGroups: VisualizationDimensionGroupConfig[]; columnParams?: Record; references?: ColumnChange[]; + initialParams?: { params: Record }; + incompleteParams?: ColumnAdvancedParams; } function buildSuggestion({ @@ -223,8 +227,14 @@ function getSourceField(column: Column, indexPattern: IndexPattern) { function getParams(column: Column) { return { ...column.params, + }; +} + +function getIncompleteParams(column: Column) { + return { filter: column.filter, shift: column.timeShift, + dataType: column.dataType, ...(column.window && { window: column.window }), }; } @@ -238,43 +248,38 @@ function getFieldWithLabel(column: Column, indexPattern: IndexPattern) { return field; } +function createColumnChange(column: Column, indexPattern: IndexPattern): ColumnChange { + return { + op: column.operationType, + columnId: column.columnId, + field: getFieldWithLabel(column, indexPattern), + indexPattern, + visualizationGroups: [], + incompleteParams: getIncompleteParams(column), + initialParams: { + params: getParams(column), + }, + columnParams: getParams(column), + }; +} + function convertToColumnChange(columns: Layer['columns'], indexPattern: IndexPattern) { return columns.reduce((acc, column) => { if (!columns.some((c) => isReferenceColumn(c) && column.columnId === c.references[0])) { - const newColumn: ColumnChange = { - op: column.operationType, - columnId: column.columnId, - field: getFieldWithLabel(column, indexPattern), - indexPattern, - visualizationGroups: [], - columnParams: getParams(column), - }; + const newColumn: ColumnChange = createColumnChange(column, indexPattern); if (isReferenceColumn(column)) { const referenceColumn = columns.find((c) => c.columnId === column.references[0])!; - newColumn.references = [ - { - op: referenceColumn.operationType, - columnId: referenceColumn.columnId, - field: getFieldWithLabel(referenceColumn, indexPattern), - indexPattern, - visualizationGroups: [], - columnParams: getParams(referenceColumn), - }, - ]; + newColumn.references = [createColumnChange(referenceColumn, indexPattern)]; } if ( isTermsColumn(column) && column.params.orderAgg && !columns.some((c) => c.columnId === column.params.orderAgg?.columnId) ) { - const orderAggColumn: ColumnChange = { - op: column.params.orderAgg.operationType, - columnId: column.params.orderAgg.columnId, - field: getSourceField(column.params.orderAgg, indexPattern), - indexPattern, - visualizationGroups: [], - columnParams: getParams(column.params.orderAgg), - }; + const orderAggColumn: ColumnChange = createColumnChange( + column.params.orderAgg, + indexPattern + ); acc.push(orderAggColumn); } acc.push(newColumn); @@ -300,8 +305,13 @@ function createNewLayerWithMetricAggregationFromVizEditor( FormulaIndexPatternColumn, 'managedReference' >; + const previousColumn = layer.columns.find((c) => c.columnId === column.columnId)!; const newColumn = operationDefinition.buildColumn( { + previousColumn: { + ...previousColumn, + label: previousColumn?.label || '', + }, indexPattern, layer: newLayer, }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx index 6619fc6889894..674eac8194e41 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx @@ -99,7 +99,7 @@ export const counterRateOperation: OperationDefinition< references: referenceIds, timeScale, timeShift: columnParams?.shift || previousColumn?.timeShift, - filter: columnParams?.filter || getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), params: getFormatFromPreviousColumn(previousColumn), }; }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx index 0fa80c7440fcb..11e1da98b0ca0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx @@ -98,7 +98,7 @@ export const cumulativeSumOperation: OperationDefinition< isBucketed: false, scale: 'ratio', timeShift: columnParams?.shift || previousColumn?.timeShift, - filter: columnParams?.filter || getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), references: referenceIds, params: getFormatFromPreviousColumn(previousColumn), }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx index 0aa45786d0501..2c4ab56d7e223 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx @@ -85,7 +85,7 @@ export const derivativeOperation: OperationDefinition< scale: 'ratio', references: referenceIds, timeScale, - filter: columnParams?.filter ?? getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, params: getFormatFromPreviousColumn(previousColumn), }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx index 7330267fbbe76..c46b6954f7480 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx @@ -103,7 +103,7 @@ export const movingAverageOperation: OperationDefinition< scale: 'ratio', references: referenceIds, timeShift: columnParams?.shift || previousColumn?.timeShift, - filter: columnParams?.filter || getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), timeScale: previousColumn?.timeScale, params: { window, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx index 7d11fe1b00a1f..dbbbb2da80e08 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx @@ -118,7 +118,7 @@ export const cardinalityOperation: OperationDefinition< scale: SCALE, sourceField: field.name, isBucketed: IS_BUCKETED, - filter: columnParams?.filter || getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx index 8a1107a821c52..d6d7806329e1e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx @@ -134,7 +134,7 @@ export const countOperation: OperationDefinition { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx index afc74b043fca7..f9fbb80e649c6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx @@ -215,10 +215,7 @@ export const lastValueOperation: OperationDefinition< isBucketed: false, scale: field.type === 'string' ? 'ordinal' : 'ratio', sourceField: field.name, - filter: - columnParams?.filter || - getFilter(previousColumn, columnParams) || - getExistsFilter(field.name), + filter: getFilter(previousColumn, columnParams) || getExistsFilter(field.name), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx index 15f3fc265a626..1942095ffa7ce 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx @@ -132,7 +132,7 @@ function buildMetricOperation>({ isBucketed: false, scale: 'ratio', timeScale: optionalTimeScaling ? previousColumn?.timeScale : undefined, - filter: columnParams?.filter ?? getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx index e725f5b394767..a0eb542449813 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx @@ -133,7 +133,7 @@ export const percentileOperation: OperationDefinition< sourceField: field.name, isBucketed: false, scale: 'ratio', - filter: columnParams?.filter || getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx index 66bb21498706d..9541665195689 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx @@ -126,7 +126,7 @@ export const percentileRanksOperation: OperationDefinition< sourceField: field.name, isBucketed: false, scale: 'ratio', - filter: columnParams?.filter || getFilter(previousColumn, columnParams), + filter: getFilter(previousColumn, columnParams), timeShift: columnParams?.shift || previousColumn?.timeShift, window: columnParams?.window || previousColumn?.window, params: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 1c7c6004726fb..ffef48355e8e8 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -43,11 +43,13 @@ import { FormulaIndexPatternColumn, insertOrReplaceFormulaColumn } from './defin import type { TimeScaleUnit } from '../../../common/expressions'; import { documentField } from '../document_field'; import { isColumnOfType } from './definitions/helpers'; +import { DataType } from '../..'; -interface ColumnAdvancedParams { +export interface ColumnAdvancedParams { filter?: Query | undefined; timeShift?: string | undefined; timeScale?: TimeScaleUnit | undefined; + dataType?: DataType; } interface ColumnChange { From 0e847faabf4019b2add61e50d0838372db538575 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 12:35:17 +0300 Subject: [PATCH 058/129] Removed not used code. --- .../public/convert_to_lens/index.ts | 4 +- .../lib/convert/parent_pipeline.ts | 3 +- .../datasource/get_datasource_info.test.ts | 3 + .../lib/datasource/get_field_type.ts | 18 - .../convert_to_lens/lib/formatters/index.ts | 9 - .../lib/formatters/supported_formatters.ts | 9 - .../convert_to_lens/lib/layers/get_layer.ts | 87 --- .../convert_to_lens/lib/layers/index.ts | 9 - .../convert_to_lens/lib/metrics/index.ts | 2 - .../lib/metrics/metrics_converter.ts | 48 -- .../lib/metrics/metrics_helpers.test.ts | 110 ---- .../lib/metrics/metrics_helpers.ts | 58 +- .../metrics/parent_pipeline_series.test.ts | 155 ----- .../lib/metrics/parent_pipeline_series.ts | 104 ---- .../lib/series/get_series.test.ts | 589 ------------------ .../convert_to_lens/lib/series/get_series.ts | 275 -------- .../convert_to_lens/lib/series/index.ts | 3 +- .../lib/series/metrics_columns.ts | 2 +- .../{get_series_agg.ts => series_agg.ts} | 0 .../lib/split_chart/date_histogram.ts | 33 - .../lib/split_chart/filters.ts | 23 - .../convert_to_lens/lib/split_chart/index.ts | 10 - .../convert_to_lens/timeseries/index.test.ts | 340 ---------- .../convert_to_lens/timeseries/index.ts | 104 ++-- .../convert_to_lens/timeseries/new.index.ts | 120 ---- .../convert_to_lens/top_n/index.test.ts | 329 ---------- .../public/convert_to_lens/top_n/index.ts | 97 ++- .../public/convert_to_lens/top_n/new.index.ts | 108 ---- .../common/convert_to_lens/types/context.ts | 2 +- src/plugins/visualizations/public/index.ts | 10 +- .../visualizations/public/vis_types/types.ts | 84 +-- 31 files changed, 117 insertions(+), 2631 deletions(-) delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_field_type.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/index.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/supported_formatters.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/index.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts rename src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/{get_series_agg.ts => series_agg.ts} (100%) delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/filters.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/index.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts index 462617ba784e8..c9e72040e26dd 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts @@ -14,11 +14,11 @@ import { ConvertTsvbToLensVisualization } from './types'; const getConvertFnByType = (type: PANEL_TYPES) => { const convertionFns: { [key in PANEL_TYPES]?: () => Promise } = { [PANEL_TYPES.TIMESERIES]: async () => { - const { convertToLens } = await import('./timeseries/new.index'); + const { convertToLens } = await import('./timeseries'); return convertToLens; }, [PANEL_TYPES.TOP_N]: async () => { - const { convertToLens } = await import('./top_n/new.index'); + const { convertToLens } = await import('./top_n'); return convertToLens; }, }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 520881db9cb1e..c00d45cc4fbce 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -30,7 +30,6 @@ import { getFilterRatioFormula, getFormulaFromMetric, getParentPipelineSeriesFormula, - getPipelineAgg, SupportedMetric, SUPPORTED_METRICS, } from '../metrics'; @@ -224,7 +223,7 @@ const convertMovingAvgOrDerivativeToColumns = ( return null; } - const pipelineAgg = getPipelineAgg(subFunctionMetric.type); + const pipelineAgg = SUPPORTED_METRICS[subFunctionMetric.type]; if (!pipelineAgg) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.test.ts index 33052a25190d1..5033d1470147d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.test.ts @@ -38,6 +38,7 @@ describe('getDataSourceInfo', () => { undefined, false, undefined, + undefined, dataViews ); expect(indexPatternId).toBe('12345'); @@ -50,6 +51,7 @@ describe('getDataSourceInfo', () => { 'timeField-1', false, undefined, + undefined, dataViews ); expect(indexPatternId).toBe('dataview-1-id'); @@ -62,6 +64,7 @@ describe('getDataSourceInfo', () => { 'timeField-1', true, { id: 'test2' }, + undefined, dataViews ); expect(indexPatternId).toBe('test2'); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_field_type.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_field_type.ts deleted file mode 100644 index 07ab80fd33ec1..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_field_type.ts +++ /dev/null @@ -1,18 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; - -export const getFieldType = async ( - indexPatternId: string, - fieldName: string, - dataViews: DataViewsPublicPluginStart -) => { - const dataView = await dataViews.get(indexPatternId); - const field = dataView.getFieldByName(fieldName); - return field?.type; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/index.ts deleted file mode 100644 index 04d55dd0ba52e..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/index.ts +++ /dev/null @@ -1,9 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export { SUPPORTED_FORMATTERS } from './supported_formatters'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/supported_formatters.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/supported_formatters.ts deleted file mode 100644 index 8c92686933de7..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/formatters/supported_formatters.ts +++ /dev/null @@ -1,9 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export const SUPPORTED_FORMATTERS = ['bytes', 'percent', 'number']; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts deleted file mode 100644 index 2f3c7d8a28421..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/get_layer.ts +++ /dev/null @@ -1,87 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; -import { PaletteOutput } from '@kbn/coloring'; -import { SUPPORTED_FORMATTERS } from '../formatters'; -import { convertSplitFilters } from '../split_chart'; -import { convertMetrics, convertFilter } from '../metrics'; -import type { Panel, Series } from '../../../../common/types'; -import { VisSeries } from '../series'; - -function getTermParams(layer: Series) { - return { - size: layer.terms_size ?? 10, - ...(layer.terms_include && { include: [layer.terms_include] }), - includeIsRegex: Boolean(layer.terms_include), - ...(layer.terms_exclude && { exclude: [layer.terms_exclude] }), - excludeIsRegex: Boolean(layer.terms_exclude), - otherBucket: false, - orderDirection: layer.terms_direction ?? 'desc', - orderBy: layer.terms_order_by === '_key' ? { type: 'alphabetical' } : { type: 'column' }, - parentFormat: { id: 'terms' }, - }; -} - -function getPalette(palette: PaletteOutput): PaletteOutput { - return !palette || palette.name === 'gradient' || palette.name === 'rainbow' - ? { name: 'default', type: 'palette' } - : palette; -} - -export const getLayerConfiguration = ( - indexPatternId: string, - layerIdx: number, - chartType: string, - model: Panel, - series: VisSeries, - { - splitFields = [], - xFieldName, - xMode, - splitWithDateHistogram, - window, - }: { - splitFields?: string[]; - xFieldName?: string; - xMode?: string; - splitWithDateHistogram?: boolean; - window?: string; - } = {} -): VisualizeEditorLayersContext => { - const layer = model.series[layerIdx]; - const palette = layer.palette as PaletteOutput; - const splitFilters = convertSplitFilters(layer); - const { metrics: metricsArray, seriesAgg } = series; - const filter = convertFilter(layer); - const metrics = convertMetrics(layer, metricsArray, filter, window); - return { - indexPatternId, - xFieldName, - xMode, - chartType, - axisPosition: layer.separate_axis ? layer.axis_position : model.axis_position, - ...(layer.terms_field && { splitFields }), - splitWithDateHistogram, - ...(layer.split_mode !== 'everything' && { splitMode: layer.split_mode }), - ...(splitFilters.length > 0 && { splitFilters }), - // for non supported palettes, we will use the default palette - palette: getPalette(palette), - ...(layer.split_mode === 'terms' && { - termsParams: getTermParams(layer), - }), - collapseFn: seriesAgg, - metrics, - timeInterval: model.interval && !model.interval?.includes('=') ? model.interval : 'auto', - ...(SUPPORTED_FORMATTERS.includes(layer.formatter) && { format: layer.formatter }), - ...(layer.label && { label: layer.label }), - dropPartialBuckets: layer.override_index_pattern - ? layer.series_drop_last_bucket > 0 - : model.drop_last_bucket > 0, - }; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/index.ts deleted file mode 100644 index eaef2f964f94a..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/layers/index.ts +++ /dev/null @@ -1,9 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export * from './get_layer'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts index b484010cd4483..d03df28f4814e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts @@ -8,10 +8,8 @@ export * from './supported_metrics'; export * from './metrics_helpers'; -export * from './metrics_converter'; export * from './parent_pipeline_formula'; export * from './sibling_pipeline_formula'; export * from './filter_ratio_formula'; -export * from './parent_pipeline_series'; export * from './counter_rate_formula'; export * from './validate_metrics'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts deleted file mode 100644 index 6ea305fdface3..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_converter.ts +++ /dev/null @@ -1,48 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; -import { Series } from '../../../../common/types'; -import { Filter } from '../../types'; - -export const convertFilter = (series: Series): Filter | void => { - if (!series.filter) { - return; - } - - if (series.filter.language === 'kuery') { - return { kql: series.filter.query }; - } - - if (series.filter.language === 'lucene') { - return { lucene: series.filter.query }; - } -}; - -const convertMetric = ( - series: Series, - metric: VisualizeEditorLayersContext['metrics'][number], - filter: Filter | void, - interval?: string -) => ({ - ...metric, - color: metric.color ?? series.color, - params: { - ...metric.params, - ...(series.offset_time && { shift: series.offset_time }), - ...(filter && filter), - ...(interval && { window: interval }), - }, -}); - -export const convertMetrics = ( - series: Series, - metrics: VisualizeEditorLayersContext['metrics'], - filter: Filter | void, - interval?: string -) => metrics.map((metric) => convertMetric(series, metric, filter, interval)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts deleted file mode 100644 index b07bcecb7f790..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts +++ /dev/null @@ -1,110 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { Metric } from '../../../../common/types'; -import { getPercentilesSeries, getPercentileRankSeries } from './metrics_helpers'; - -describe('getPercentilesSeries', () => { - test('should return correct config for multiple percentiles', () => { - const percentiles = [ - { - color: '#68BC00', - id: 'aef159f0-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - shade: 0.2, - value: 50, - }, - { - color: 'rgba(0,63,188,1)', - id: 'b0e0a6d0-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - percentile: '', - shade: 0.2, - value: '70', - }, - { - color: 'rgba(188,38,0,1)', - id: 'b2e04760-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - percentile: '', - shade: 0.2, - value: '80', - }, - { - color: 'rgba(188,0,3,1)', - id: 'b503eab0-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - percentile: '', - shade: 0.2, - value: '90', - }, - ] as Metric['percentiles']; - const config = getPercentilesSeries(percentiles, 'everything', '', 'bytes'); - expect(config).toStrictEqual([ - { - agg: 'percentile', - color: '#68BC00', - fieldName: 'bytes', - isFullReference: false, - params: { percentile: 50 }, - }, - { - agg: 'percentile', - color: 'rgba(0,63,188,1)', - fieldName: 'bytes', - isFullReference: false, - params: { percentile: '70' }, - }, - { - agg: 'percentile', - color: 'rgba(188,38,0,1)', - fieldName: 'bytes', - isFullReference: false, - params: { percentile: '80' }, - }, - { - agg: 'percentile', - color: 'rgba(188,0,3,1)', - fieldName: 'bytes', - isFullReference: false, - params: { percentile: '90' }, - }, - ]); - }); -}); - -describe('getPercentileRankSeries', () => { - test('should return correct config for multiple percentile ranks', () => { - const values = ['1', '5', '7'] as Metric['values']; - const colors = ['#68BC00', 'rgba(0,63,188,1)', 'rgba(188,38,0,1)'] as Metric['colors']; - const config = getPercentileRankSeries(values, colors, 'everything', '', 'day_of_week_i'); - expect(config).toStrictEqual([ - { - agg: 'percentile_rank', - color: '#68BC00', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { value: '1' }, - }, - { - agg: 'percentile_rank', - color: 'rgba(0,63,188,1)', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { value: '5' }, - }, - { - agg: 'percentile_rank', - color: 'rgba(188,38,0,1)', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { value: '7' }, - }, - ]); - }); -}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 60d7abb77fdb9..67618b68ecfb0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -12,48 +12,13 @@ import dateMath from '@kbn/datemath'; import { TimeRange, UI_SETTINGS } from '@kbn/data-plugin/common'; import { TimeScaleUnit } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { getUISettings } from '../../../services'; -import type { Metric, MetricType, Panel, Series } from '../../../../common/types'; +import type { Metric, Panel, Series } from '../../../../common/types'; import { TIME_RANGE_DATA_MODES } from '../../../../common/enums'; import { getFilterRatioFormula } from './filter_ratio_formula'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; -export const getPercentilesSeries = ( - percentiles: Metric['percentiles'], - splitMode: string, - layerColor: string, - fieldName?: string -) => { - return percentiles?.map((percentile) => { - return { - agg: 'percentile', - isFullReference: false, - color: splitMode === 'everything' ? percentile.color : layerColor, - fieldName: fieldName ?? 'document', - params: { percentile: percentile.value }, - }; - }); -}; - -export const getPercentileRankSeries = ( - values: Metric['values'], - colors: Metric['colors'], - splitMode: string, - layerColor: string, - fieldName?: string -) => { - return values?.map((value, index) => { - return { - agg: 'percentile_rank', - isFullReference: false, - color: splitMode === 'everything' ? colors?.[index] : layerColor, - fieldName: fieldName ?? 'document', - params: { value }, - }; - }); -}; - const shouldCalculateWindow = (timeRangeMode?: string) => { return timeRangeMode === TIME_RANGE_DATA_MODES.LAST_VALUE; }; @@ -102,29 +67,10 @@ export const getTimeScale = (metric: Metric): TimeScaleUnit | undefined => { return timeScale; }; -export const getFormulaSeries = (script: string) => { - return [ - { - agg: 'formula', - isFullReference: true, - fieldName: 'document', - params: { formula: script }, - }, - ]; -}; - export const addTimeRangeToFormula = (window?: string) => { return window ? `, timeRange='${window}'` : ''; }; -export const getPipelineAgg = (agg: MetricType) => { - const pipelineAggMap = SUPPORTED_METRICS[agg]; - if (!pipelineAggMap) { - return null; - } - return pipelineAggMap; -}; - export const getFormulaEquivalent = ( currentMetric: Metric, metrics: Metric[], @@ -166,7 +112,7 @@ export const getFormulaEquivalent = ( if (!subFunctionMetric) { return null; } - const pipelineAgg = getPipelineAgg(subFunctionMetric.type); + const pipelineAgg = SUPPORTED_METRICS[subFunctionMetric.type]; if (!pipelineAgg) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts deleted file mode 100644 index db8faccf5976f..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.test.ts +++ /dev/null @@ -1,155 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import type { Metric, MetricType } from '../../../../common/types'; -import { getParentPipelineSeries } from './parent_pipeline_series'; - -describe('getParentPipelineSeries', () => { - test('should return correct config for pipeline agg on percentiles', () => { - const metrics = [ - { - field: 'AvgTicketPrice', - id: '04558549-f19f-4a87-9923-27df8b81af3e', - percentiles: [ - { - color: '#68BC00', - id: 'aef159f0-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - shade: 0.2, - value: 50, - }, - { - color: 'rgba(0,63,188,1)', - id: 'b0e0a6d0-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - percentile: '', - shade: 0.2, - value: '70', - }, - ], - type: 'percentile', - }, - { - field: '04558549-f19f-4a87-9923-27df8b81af3e[70.0]', - id: '764f4110-7db9-11ec-9fdf-91a8881dd06b', - type: 'derivative', - unit: '', - }, - ] as Metric[]; - const config = getParentPipelineSeries(METRIC_TYPES.DERIVATIVE, 1, metrics); - expect(config).toStrictEqual([ - { - agg: 'differences', - fieldName: 'AvgTicketPrice', - isFullReference: true, - params: { - percentile: 70, - }, - pipelineAggType: 'percentile', - }, - ]); - }); - - test('should return correct config for pipeline agg on percentile ranks', () => { - const metrics = [ - { - field: 'AvgTicketPrice', - id: '04558549-f19f-4a87-9923-27df8b81af3e', - values: ['400', '500', '700'], - colors: ['rgba(211,96,134,1)', 'rgba(155,33,230,1)', '#68BC00'], - type: 'percentile_rank', - }, - { - field: '04558549-f19f-4a87-9923-27df8b81af3e[400.0]', - id: '764f4110-7db9-11ec-9fdf-91a8881dd06b', - type: 'derivative', - unit: '', - }, - ] as Metric[]; - const config = getParentPipelineSeries(METRIC_TYPES.DERIVATIVE, 1, metrics); - expect(config).toStrictEqual([ - { - agg: 'differences', - fieldName: 'AvgTicketPrice', - isFullReference: true, - params: { - value: 400, - }, - pipelineAggType: 'percentile_rank', - }, - ]); - }); - - test('should return null config for pipeline agg on non-supported sub-aggregation', () => { - const metrics = [ - { - field: 'AvgTicketPrice', - id: '04558549-f19f-4a87-9923-27df8b81af3e', - type: 'sum_of_squares_bucket', - }, - { - field: '04558549-f19f-4a87-9923-27df8b81af3e', - id: '764f4110-7db9-11ec-9fdf-91a8881dd06b', - type: 'derivative', - unit: '', - }, - ] as Metric[]; - const config = getParentPipelineSeries(METRIC_TYPES.DERIVATIVE, 1, metrics); - expect(config).toBeNull(); - }); - - test('should return null config for pipeline agg when sub-agregation is not given', () => { - const metrics = [ - { - field: 'AvgTicketPrice', - id: '04558549-f19f-4a87-9923-27df8b81af3e', - type: 'avg', - }, - { - field: '123456', - id: '764f4110-7db9-11ec-9fdf-91a8881dd06b', - type: 'derivative', - unit: '', - }, - ] as Metric[]; - const config = getParentPipelineSeries(METRIC_TYPES.DERIVATIVE, 1, metrics); - expect(config).toBeNull(); - }); - - test('should return formula config for pipeline agg when applied on nested aggregations', () => { - const metrics = [ - { - field: 'AvgTicketPrice', - id: '04558549-f19f-4a87-9923-27df8b81af3e', - type: 'avg', - }, - { - field: '04558549-f19f-4a87-9923-27df8b81af3e', - id: '6e4932d0-7dbb-11ec-8d79-e163106679dc', - model_type: 'simple', - type: 'cumulative_sum', - }, - { - field: '6e4932d0-7dbb-11ec-8d79-e163106679dc', - id: 'a51de940-7dbb-11ec-8d79-e163106679dc', - type: 'moving_average', - window: 5, - }, - ] as Metric[]; - const config = getParentPipelineSeries('moving_average' as MetricType, 2, metrics); - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { formula: 'moving_average(cumulative_sum(average(AvgTicketPrice)))' }, - }, - ]); - }); -}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts deleted file mode 100644 index f1222b9b3add5..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_series.ts +++ /dev/null @@ -1,104 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { Metric, MetricType } from '../../../../common/types'; -import { getFormulaFromMetric, SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; -import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; -import { getFilterRatioFormula } from './filter_ratio_formula'; -import { getFormulaSeries, getTimeScale, getPipelineAgg } from './metrics_helpers'; - -export const computeParentSeries = ( - aggregation: MetricType, - currentMetric: Metric, - subFunctionMetric: Metric, - pipelineAgg: SupportedMetric, - { metaValue, window }: { metaValue?: number; window?: string } = {} -) => { - const aggregationMap = SUPPORTED_METRICS[aggregation]; - if (!aggregationMap) { - return null; - } - - if (subFunctionMetric.type === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric, window); - if (!script) { - return null; - } - - const aggFormula = getFormulaFromMetric(aggregationMap); - const formula = `${aggFormula}(${script})`; - return getFormulaSeries(formula); - } - const timeScale = getTimeScale(currentMetric); - const fieldName = - subFunctionMetric?.field && pipelineAgg.name !== 'count' - ? subFunctionMetric?.field - : 'document'; - - return [ - { - agg: aggregationMap.name, - isFullReference: aggregationMap!.isFullReference, - pipelineAggType: pipelineAgg.name, - fieldName, - params: { - ...(currentMetric.window && { window: currentMetric.window }), - ...(timeScale && { timeScale }), - ...(pipelineAgg.name === 'percentile' && metaValue && { percentile: metaValue }), - ...(pipelineAgg.name === 'percentile_rank' && metaValue && { value: metaValue }), - ...(pipelineAgg.name === 'formula' - ? { formula: `${pipelineAgg.formula}(${fieldName})` } - : {}), - }, - }, - ]; -}; - -export const getParentPipelineSeries = ( - aggregation: MetricType, - currentMetricIdx: number, - metrics: Metric[], - window?: string -) => { - const currentMetric = metrics[currentMetricIdx]; - // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] - const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; - const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); - - if (!subFunctionMetric || subFunctionMetric.type === 'static') { - return null; - } - const pipelineAgg = getPipelineAgg(subFunctionMetric.type); - if (!pipelineAgg) { - return null; - } - const metaValue = Number(meta?.replace(']', '')); - const subMetricField = subFunctionMetric.field; - const [nestedFieldId, _] = subMetricField?.split('[') ?? []; - // support nested aggs with formula - const additionalSubFunction = metrics.find((metric) => metric.id === nestedFieldId); - - if (additionalSubFunction) { - const formula = getParentPipelineSeriesFormula( - metrics, - subFunctionMetric, - pipelineAgg, - aggregation, - { metaValue, window } - ); - if (!formula) { - return null; - } - return getFormulaSeries(formula); - } else { - return computeParentSeries(aggregation, currentMetric, subFunctionMetric, pipelineAgg, { - metaValue, - window, - }); - } -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts deleted file mode 100644 index 80b7ba29b24c7..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.test.ts +++ /dev/null @@ -1,589 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { Metric } from '../../../../common/types'; -import { getSeries } from './get_series'; - -describe('getSeries', () => { - test('should return the correct config for an average aggregation', () => { - const metric = [ - { - id: '12345', - type: 'avg', - field: 'day_of_week_i', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'average', - fieldName: 'day_of_week_i', - isFullReference: false, - params: {}, - }, - ]); - }); - - test('should return the correct formula config for a filter ratio aggregation', () => { - const metric = [ - { - id: '12345', - type: 'filter_ratio', - field: 'day_of_week_i', - numerator: { - query: 'category.keyword : "Men\'s Clothing" ', - language: 'kuery', - }, - denominator: { - query: 'customer_gender : "FEMALE" ', - language: 'kuery', - }, - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { - formula: - "count(kql='category.keyword : \"Men\\'s Clothing\" ') / count(kql='customer_gender : \"FEMALE\" ')", - }, - }, - ]); - }); - - test('should return the correct formula config for an overall function', () => { - const metric = [ - { - field: 'day_of_week_i', - id: '123456', - type: 'max', - }, - { - id: '891011', - type: 'max_bucket', - field: '123456', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { - formula: 'overall_max(max(day_of_week_i))', - }, - }, - ]); - }); - - test('should return the correct formula config for a positive only function', () => { - const metric = [ - { - field: 'day_of_week_i', - id: '123456', - type: 'max', - }, - { - id: '891011', - type: 'positive_only', - field: '123456', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { - formula: 'pick_max(max(day_of_week_i), 0)', - }, - }, - ]); - }); - - test('should return the correct config for the cumulative sum on count', () => { - const metric = [ - { - id: '123456', - type: 'count', - }, - { - id: '7891011', - type: 'cumulative_sum', - field: '123456', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'cumulative_sum', - fieldName: 'document', - isFullReference: true, - params: {}, - pipelineAggType: 'count', - }, - ]); - }); - - test('should return the correct formula config for the cumulative sum on max', () => { - const metric = [ - { - field: 'day_of_week_i', - id: '123456', - type: 'max', - }, - { - id: '7891011', - type: 'cumulative_sum', - field: '123456', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { - formula: 'cumulative_sum(max(day_of_week_i))', - }, - }, - ]); - }); - - test('should return the correct config for the derivative aggregation', () => { - const metric = [ - { - field: 'day_of_week_i', - id: '123456', - type: 'max', - }, - { - field: '123456', - id: '7891011', - type: 'derivative', - unit: '1m', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'differences', - fieldName: 'day_of_week_i', - isFullReference: true, - params: { - timeScale: 'm', - }, - pipelineAggType: 'max', - }, - ]); - }); - - test('should return the correct config for the moving average aggregation', () => { - const metric = [ - { - field: 'day_of_week_i', - id: '123456', - type: 'max', - }, - { - field: '123456', - id: '7891011', - type: 'moving_average', - window: 6, - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'moving_average', - fieldName: 'day_of_week_i', - isFullReference: true, - params: { window: 6 }, - pipelineAggType: 'max', - }, - ]); - }); - - test('should return the correct formula for the math aggregation', () => { - const metric = [ - { - field: 'day_of_week_i', - id: '123456', - type: 'max', - }, - { - field: 'day_of_week_i', - id: '7891011', - type: 'min', - }, - { - field: '123456', - id: 'fab31880-7d11-11ec-a13a-b52b40401df4', - script: 'params.max - params.min', - type: 'math', - variables: [ - { - field: '123456', - id: 'c47c7a00-7d15-11ec-a13a-b52b40401df4', - name: 'max', - }, - { - field: '7891011', - id: 'c7a38390-7d15-11ec-a13a-b52b40401df4', - name: 'min', - }, - ], - window: 6, - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { - formula: 'max(day_of_week_i) - min(day_of_week_i)', - }, - }, - ]); - }); - - test('should return the correct config for the percentiles aggregation', () => { - const metric = [ - { - field: 'day_of_week_i', - id: 'id1', - type: 'percentile', - percentiles: [ - { - value: '90', - percentile: '', - shade: 0.2, - color: 'rgba(211,96,134,1)', - id: 'id2', - mode: 'line', - }, - { - value: '85', - percentile: '', - shade: 0.2, - color: 'rgba(155,33,230,1)', - id: 'id3', - mode: 'line', - }, - { - value: '70', - percentile: '', - shade: 0.2, - color: '#68BC00', - id: 'id4', - mode: 'line', - }, - ], - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'percentile', - color: 'rgba(211,96,134,1)', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - percentile: '90', - }, - }, - { - agg: 'percentile', - color: 'rgba(155,33,230,1)', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - percentile: '85', - }, - }, - { - agg: 'percentile', - color: '#68BC00', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - percentile: '70', - }, - }, - ]); - }); - - test('should return the correct config for the percentile ranks aggregation', () => { - const metric = [ - { - field: 'day_of_week_i', - id: 'id1', - type: 'percentile_rank', - values: ['1', '5', '7'], - colors: ['rgba(211,96,134,1)', 'rgba(155,33,230,1)', '#68BC00'], - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'percentile_rank', - color: 'rgba(211,96,134,1)', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - value: '1', - }, - }, - { - agg: 'percentile_rank', - color: 'rgba(155,33,230,1)', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - value: '5', - }, - }, - { - agg: 'percentile_rank', - color: '#68BC00', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - value: '7', - }, - }, - ]); - }); - - test('should return the correct formula config for a top_hit size 1 aggregation', () => { - const metric = [ - { - id: '12345', - type: 'top_hit', - field: 'day_of_week_i', - size: 1, - order_by: 'timestamp', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'last_value', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - sortField: 'timestamp', - }, - }, - ]); - }); - - test('should split out the series agg metric and return it as a separate property', () => { - const metric = [ - { - id: '12345', - type: 'top_hit', - field: 'day_of_week_i', - size: 1, - order_by: 'timestamp', - }, - { - id: '6789', - type: 'series_agg', - function: 'mean', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!; - expect(config).toStrictEqual({ - metrics: [ - { - agg: 'last_value', - fieldName: 'day_of_week_i', - isFullReference: false, - params: { - sortField: 'timestamp', - }, - }, - ], - seriesAgg: 'avg', - }); - }); - - test('should return null for a top_hit size >1 aggregation', () => { - const metric = [ - { - id: '12345', - type: 'top_hit', - field: 'day_of_week_i', - size: 2, - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', ''); - expect(config).toBeNull(); - }); - - test('should return null for a static aggregation with 1 layer', () => { - const metric = [ - { - id: '12345', - type: 'static', - value: '10', - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', ''); - expect(config).toBeNull(); - }); - - test('should return the correct config for a static aggregation with 2 layers', () => { - const metric = [ - { - id: '12345', - type: 'static', - value: '10', - }, - ] as Metric[]; - const config = getSeries(metric, 2, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'static_value', - fieldName: 'document', - isFullReference: true, - params: { - value: '10', - }, - }, - ]); - }); - - test('should return the correct formula for the math aggregation with percentiles as variables', () => { - const metric = [ - { - field: 'day_of_week_i', - id: 'e72265d2-2106-4af9-b646-33afd9cddcad', - percentiles: [ - { - color: 'rgba(211,96,134,1)', - id: '381a6850-7d16-11ec-a13a-b52b40401df4', - mode: 'line', - percentile: '', - shade: 0.2, - value: '90', - }, - { - color: 'rgba(0,107,188,1)', - id: '52f02970-7d1c-11ec-bfa7-3798d98f8341', - mode: 'line', - percentile: '', - shade: 0.2, - value: '50', - }, - ], - type: 'percentile', - unit: '', - }, - { - field: 'day_of_week_i', - id: '6280b080-7d1c-11ec-bfa7-3798d98f8341', - type: 'avg', - }, - { - id: '23a05540-7d18-11ec-a589-45a3784fc1ce', - script: 'params.perc90 + params.perc70 + params.avg', - type: 'math', - variables: [ - { - field: 'e72265d2-2106-4af9-b646-33afd9cddcad[90.0]', - id: '25840960-7d18-11ec-a589-45a3784fc1ce', - name: 'perc90', - }, - { - field: 'e72265d2-2106-4af9-b646-33afd9cddcad[50.0]', - id: '2a440270-7d18-11ec-a589-45a3784fc1ce', - name: 'perc70', - }, - { - field: '6280b080-7d1c-11ec-bfa7-3798d98f8341', - id: '64c82f80-7d1c-11ec-bfa7-3798d98f8341', - name: 'avg', - }, - ], - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { - formula: - 'percentile(day_of_week_i, percentile=90) + percentile(day_of_week_i, percentile=50) + average(day_of_week_i)', - }, - }, - ]); - }); - - test('should return the correct formula for the math aggregation with percentile ranks as variables', () => { - const metric = [ - { - field: 'day_of_week_i', - id: 'e72265d2-2106-4af9-b646-33afd9cddcad', - values: ['1', '5', '7'], - colors: ['rgba(211,96,134,1)', 'rgba(155,33,230,1)', '#68BC00'], - type: 'percentile_rank', - }, - { - field: 'day_of_week_i', - id: '6280b080-7d1c-11ec-bfa7-3798d98f8341', - type: 'avg', - }, - { - id: '23a05540-7d18-11ec-a589-45a3784fc1ce', - script: 'params.perc1 + params.perc5 + params.avg', - type: 'math', - variables: [ - { - field: 'e72265d2-2106-4af9-b646-33afd9cddcad[1]', - id: '25840960-7d18-11ec-a589-45a3784fc1ce', - name: 'perc1', - }, - { - field: 'e72265d2-2106-4af9-b646-33afd9cddcad[5]', - id: '2a440270-7d18-11ec-a589-45a3784fc1ce', - name: 'perc5', - }, - { - field: '6280b080-7d1c-11ec-bfa7-3798d98f8341', - id: '64c82f80-7d1c-11ec-bfa7-3798d98f8341', - name: 'avg', - }, - ], - }, - ] as Metric[]; - const config = getSeries(metric, 1, 'everything', '')!.metrics; - expect(config).toStrictEqual([ - { - agg: 'formula', - fieldName: 'document', - isFullReference: true, - params: { - formula: - 'percentile_rank(day_of_week_i, value=1) + percentile_rank(day_of_week_i, value=5) + average(day_of_week_i)', - }, - }, - ]); - }); -}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts deleted file mode 100644 index 16a8e750bd819..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series.ts +++ /dev/null @@ -1,275 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; -import type { Metric } from '../../../../common/types'; -import { getSeriesAgg } from './get_series_agg'; -import { - SUPPORTED_METRICS, - getPercentilesSeries, - getPercentileRankSeries, - getFormulaSeries, - getParentPipelineSeries, - getSiblingPipelineSeriesFormula, - getPipelineAgg, - computeParentSeries, - getFormulaEquivalent, - getParentPipelineSeriesFormula, - getFilterRatioFormula, - getTimeScale, -} from '../metrics'; - -export interface VisSeries { - metrics: VisualizeEditorLayersContext['metrics']; - seriesAgg?: string; -} - -export const getSeries = ( - initialMetrics: Metric[], - totalSeriesNum: number, - splitMode: string, - layerColor: string, - window?: string -): VisSeries | null => { - const { metrics, seriesAgg } = getSeriesAgg(initialMetrics); - const metricIdx = metrics.length - 1; - const aggregation = metrics[metricIdx].type; - const fieldName = metrics[metricIdx].field; - const aggregationMap = SUPPORTED_METRICS[aggregation]; - if (!aggregationMap) { - return null; - } - let metricsArray: VisualizeEditorLayersContext['metrics'] = []; - switch (aggregation) { - case 'percentile': { - const percentiles = metrics[metricIdx].percentiles; - if (percentiles?.length) { - const percentilesSeries = getPercentilesSeries( - percentiles, - splitMode, - layerColor, - fieldName - ) as VisualizeEditorLayersContext['metrics']; - metricsArray = [...metricsArray, ...percentilesSeries]; - } - break; - } - case 'percentile_rank': { - const values = metrics[metricIdx].values; - const colors = metrics[metricIdx].colors; - if (values?.length) { - const percentileRanksSeries = getPercentileRankSeries( - values, - colors, - splitMode, - layerColor, - fieldName - ) as VisualizeEditorLayersContext['metrics']; - metricsArray = [...metricsArray, ...percentileRanksSeries]; - } - break; - } - case 'math': { - // find the metric idx that has math expression - const mathMetricIdx = metrics.findIndex((metric) => metric.type === 'math'); - let finalScript = metrics[mathMetricIdx].script; - - const variables = metrics[mathMetricIdx].variables; - const layerMetricsArray = metrics; - if (!finalScript || !variables) return null; - const metricsWithoutMath = layerMetricsArray.filter((metric) => metric.type !== 'math'); - - // create the script - for (let layerMetricIdx = 0; layerMetricIdx < metricsWithoutMath.length; layerMetricIdx++) { - const currentMetric = metrics[layerMetricIdx]; - // We can only support top_hit with size 1 - if ( - (currentMetric.type === 'top_hit' && - currentMetric?.size && - Number(currentMetric?.size) !== 1) || - currentMetric?.order === 'asc' - ) { - return null; - } - - // should treat percentiles differently - if (currentMetric.type === 'percentile' || currentMetric.type === 'percentile_rank') { - variables.forEach((variable) => { - const [_, meta] = variable?.field?.split('[') ?? []; - const metaValue = Number(meta?.replace(']', '')); - if (!metaValue) return; - const script = getFormulaEquivalent(currentMetric, layerMetricsArray, { - metaValue, - window, - }); - if (!script) return; - finalScript = finalScript?.replace(`params.${variable.name}`, script); - }); - } else { - const script = getFormulaEquivalent(currentMetric, layerMetricsArray, { window }); - if (!script) return null; - const variable = variables.find((v) => v.field === currentMetric.id); - finalScript = finalScript?.replaceAll(`params.${variable?.name}`, script); - } - } - const scripthasNoStaticNumber = isNaN(Number(finalScript)); - if (finalScript.includes('params') || !scripthasNoStaticNumber) return null; - metricsArray = getFormulaSeries(finalScript); - break; - } - case 'moving_average': - case 'derivative': { - metricsArray = getParentPipelineSeries( - aggregation, - metricIdx, - metrics, - window - ) as VisualizeEditorLayersContext['metrics']; - break; - } - case 'cumulative_sum': { - // percentile and percentile_rank value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] - const [fieldId, meta] = metrics[metricIdx]?.field?.split('[') ?? []; - const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); - if (!subFunctionMetric || subFunctionMetric.type === 'static') { - return null; - } - const pipelineAgg = getPipelineAgg(subFunctionMetric.type); - if (!pipelineAgg) { - return null; - } - // lens supports cumulative sum for count and sum as quick function - // and everything else as formula - if (pipelineAgg.name !== 'count' && pipelineAgg.name !== 'sum') { - const metaValue = Number(meta?.replace(']', '')); - const formula = getParentPipelineSeriesFormula( - metrics, - subFunctionMetric, - pipelineAgg, - aggregation, - { metaValue, window } - ); - if (!formula) return null; - metricsArray = getFormulaSeries(formula); - } else { - const series = computeParentSeries( - aggregation, - metrics[metricIdx], - subFunctionMetric, - pipelineAgg, - { window } - ); - if (!series) return null; - metricsArray = series; - } - break; - } - case 'positive_only': - case 'avg_bucket': - case 'max_bucket': - case 'min_bucket': - case 'sum_bucket': { - const formula = getSiblingPipelineSeriesFormula( - aggregation, - metrics[metricIdx], - metrics, - window - ); - if (!formula) { - return null; - } - metricsArray = getFormulaSeries(formula) as VisualizeEditorLayersContext['metrics']; - break; - } - case 'filter_ratio': { - const formula = getFilterRatioFormula(metrics[metricIdx], window); - if (!formula) { - return null; - } - metricsArray = getFormulaSeries(formula); - break; - } - case 'top_hit': { - const currentMetric = metrics[metricIdx]; - // We can only support top_hit with size 1 - if ( - (currentMetric?.size && Number(currentMetric?.size) !== 1) || - currentMetric?.order === 'asc' - ) { - return null; - } - const timeScale = getTimeScale(currentMetric); - metricsArray = [ - { - agg: aggregationMap.name, - isFullReference: aggregationMap.isFullReference, - fieldName: fieldName ?? 'document', - params: { - ...(timeScale && { timeScale }), - ...(currentMetric?.order_by && { sortField: currentMetric?.order_by }), - }, - }, - ]; - break; - } - case 'static': { - // Lens support reference lines only when at least one layer data exists - if (totalSeriesNum === 1) { - return null; - } - const staticValue = metrics[metricIdx].value; - metricsArray = [ - { - agg: aggregationMap.name, - isFullReference: aggregationMap.isFullReference, - fieldName: 'document', - params: { - ...(staticValue && { value: staticValue }), - }, - }, - ]; - break; - } - case 'std_deviation': { - const currentMetric = metrics[metricIdx]; - if (currentMetric.mode === 'upper' || currentMetric.mode === 'lower') { - const script = getFormulaEquivalent(currentMetric, metrics, { window }); - if (!script) return null; - metricsArray = getFormulaSeries(script); - break; - } else if (currentMetric.mode === 'band') { - [ - { ...currentMetric, mode: 'upper' }, - { ...currentMetric, mode: 'lower' }, - ].forEach((metric) => { - const script = getFormulaEquivalent(metric, metrics, { window }); - if (!script) return null; - metricsArray.push(...getFormulaSeries(script)); - }); - break; - } - } - default: { - const timeScale = getTimeScale(metrics[metricIdx]); - - const field = aggregation !== 'count' && fieldName ? fieldName : 'document'; - metricsArray = [ - { - agg: aggregationMap.name, - isFullReference: aggregationMap.isFullReference, - fieldName: field, - params: { - ...(timeScale && { timeScale }), - ...(aggregationMap.isFormula ? { formula: `${aggregationMap.formula}(${field})` } : {}), - }, - }, - ]; - } - } - - return { metrics: metricsArray, seriesAgg }; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts index c10fa1846eadb..8c66fe936b711 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/index.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -export * from './get_series'; -export * from './get_series_agg'; +export * from './series_agg'; export * from './metrics_columns'; export * from './buckets_columns'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 8bc08b418d8ae..bf622adb29e31 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -8,7 +8,7 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import type { Series } from '../../../../common/types'; -import { getSeriesAgg } from './get_series_agg'; +import { getSeriesAgg } from './series_agg'; import { SUPPORTED_METRICS } from '../metrics'; import { Column, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series_agg.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/series_agg.ts similarity index 100% rename from src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/get_series_agg.ts rename to src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/series_agg.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts deleted file mode 100644 index eb500457bdac4..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/date_histogram.ts +++ /dev/null @@ -1,33 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; -import { Series } from '../../../../common/types'; -import { getFieldType } from '../datasource'; - -export const isSplitWithDateHistogram = async ( - series: Series, - splitFields: string[], - indexPatternId: string, - dataViews: DataViewsPublicPluginStart -) => { - if (series.terms_field && series.split_mode === 'terms' && splitFields) { - for (const f of splitFields) { - const fieldType = await getFieldType(indexPatternId, f, dataViews); - - if (fieldType === 'date') { - if (splitFields.length === 1) { - return true; - } else { - return null; - } - } - } - } - return false; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/filters.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/filters.ts deleted file mode 100644 index 3a22b3b70294f..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/filters.ts +++ /dev/null @@ -1,23 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; -import { Series } from '../../../../common/types'; - -export const convertSplitFilters = ( - series: Series -): Exclude => { - const splitFilters = []; - if (series.split_mode === 'filter' && series.filter) { - splitFilters.push({ filter: series.filter }); - } - if (series.split_filters) { - splitFilters.push(...series.split_filters); - } - return splitFilters; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/index.ts deleted file mode 100644 index 109178cf4d959..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/split_chart/index.ts +++ /dev/null @@ -1,10 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export * from './date_histogram'; -export * from './filters'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts deleted file mode 100644 index 7593018a22593..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts +++ /dev/null @@ -1,340 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { DataView } from '@kbn/data-plugin/common'; -import type { Panel, Series } from '../../../common/types'; -import { convertToLens } from '.'; - -const dataViewsMap: Record = { - test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, - test2: { - id: 'test2', - title: 'test2', - timeFieldName: 'timeField2', - } as DataView, - test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, -}; - -const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; -jest.mock('../../services', () => { - return { - getDataViewsStart: jest.fn(() => { - return { - getDefault: jest.fn(() => { - return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; - }), - get: getDataview, - }; - }), - }; -}); - -const model = { - axis_position: 'left', - type: 'timeseries', - index_pattern: { id: 'test2' }, - use_kibana_indexes: true, - series: [ - { - color: '#000000', - chart_type: 'line', - fill: '0', - id: '85147356-c185-4636-9182-d55f3ab2b6fa', - palette: { - name: 'default', - type: 'palette', - }, - split_mode: 'everything', - metrics: [ - { - id: '3fa8b32f-5c38-4813-9361-1f2817ae5b18', - type: 'count', - }, - ], - override_index_pattern: 0, - }, - ], -} as Panel; - -describe('convertToLens for TimeSeries', () => { - test('should return null for a non supported aggregation', async () => { - const nonSupportedAggModel = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - { - type: 'sum_of_squares_bucket', - }, - ] as Series['metrics'], - }, - ], - }; - const triggerOptions = await convertToLens(nonSupportedAggModel); - expect(triggerOptions).toBeNull(); - }); - - test('should return options for a supported aggregation', async () => { - const triggerOptions = await convertToLens(model); - expect(triggerOptions).toStrictEqual({ - configuration: { - extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, - fill: '0', - gridLinesVisibility: { x: false, yLeft: false, yRight: false }, - legend: { - isVisible: false, - maxLines: 1, - position: 'right', - shouldTruncate: false, - showSingleSeries: false, - }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'left', - chartType: 'line', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - xFieldName: 'timeField2', - xMode: 'date_histogram', - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); - - test('should return area for timeseries line chart with fill > 0', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - fill: '0.3', - stacked: 'none', - }, - ], - }; - const triggerOptions = await convertToLens(modelWithFill); - expect(triggerOptions?.layers[0].chartType).toBe('area'); - }); - - test('should return timeShift in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - offset_time: '1h', - }, - ], - }; - const triggerOptions = await convertToLens(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); - }); - - test('should return filter in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - filter: { - language: 'kuery', - query: 'test', - }, - }, - ], - }; - const triggerOptions = await convertToLens(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); - }); - - test('should return splitFilters information if the chart is broken down by filters', async () => { - const modelWithSplitFilters = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'filters', - split_filters: [ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ], - }, - ], - }; - const triggerOptions = await convertToLens(modelWithSplitFilters); - expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ]); - }); - - test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - ...model.series[0].metrics, - { - type: 'series_agg', - function: 'sum', - }, - ], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertToLens(modelWithTerms); - expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: false, - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return include exclude information if the chart is broken down by terms', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - terms_include: 't.*', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertToLens(modelWithTerms); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: true, - include: ['t.*'], - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return custom time interval if it is given', async () => { - const modelWithTerms = { - ...model, - interval: '1h', - }; - const triggerOptions = await convertToLens(modelWithTerms); - expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); - }); - - test('should return dropPartialbuckets if enabled', async () => { - const modelWithDropBuckets = { - ...model, - drop_last_bucket: 1, - }; - const triggerOptions = await convertToLens(modelWithDropBuckets); - expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); - }); - - test('should return the correct chart configuration', async () => { - const modelWithConfig = { - ...model, - show_legend: 1, - legend_position: 'bottom', - truncate_legend: 0, - show_grid: 1, - series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], - }; - const triggerOptions = await convertToLens(modelWithConfig); - expect(triggerOptions).toStrictEqual({ - configuration: { - extents: { yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' } }, - fill: '0.3', - gridLinesVisibility: { x: true, yLeft: true, yRight: true }, - legend: { - isVisible: true, - maxLines: 1, - position: 'bottom', - shouldTruncate: false, - showSingleSeries: true, - }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'right', - chartType: 'area_stacked', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - xFieldName: 'timeField2', - xMode: 'date_histogram', - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); -}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index bbf3c51bdd13d..b7429dd67eca5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -6,96 +6,110 @@ * Side Public License, v 1. */ -import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; +import { Position } from '@elastic/charts'; +import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import uuid from 'uuid'; +import { Panel } from '../../../common/types'; import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; -import { getSeries } from '../lib/series'; -import { getFieldsForTerms } from '../../../common/fields_utils'; -import { ConvertTsvbToLensVisualization } from '../types'; -import { getChartType, getYExtents } from '../lib/configurations/xy'; -import { getLayerConfiguration } from '../lib/layers'; -import { isSplitWithDateHistogram } from '../lib/split_chart'; +import { getMetricsColumns, getBucketsColumns } from '../lib/series'; +import { getLayers, getYExtents } from '../lib/configurations/xy'; +import { + Layer as ExtendedLayer, + convertToDateHistogramColumn, + excludeMetaFromColumn, +} from '../lib/convert'; import { isValidMetrics } from '../lib/metrics'; +import { ConvertTsvbToLensVisualization } from '../types'; -export const convertToLens: ConvertTsvbToLensVisualization = async (model) => { - const layersConfiguration: { [key: string]: VisualizeEditorLayersContext } = {}; +const excludeMetaFromLayers = (layers: Record): Record => { + const newLayers: Record = {}; + Object.entries(layers).forEach(([layerId, layer]) => { + const columns = layer.columns.map(excludeMetaFromColumn); + newLayers[layerId] = { ...layer, columns }; + }); - // get the active series number - const seriesNum = model.series.filter((series) => !series.hidden).length; + return newLayers; +}; + +export const convertToLens: ConvertTsvbToLensVisualization = async (model: Panel) => { const dataViews = getDataViewsStart(); + const extendedLayers: Record = {}; + const seriesNum = model.series.filter((series) => !series.hidden).length; // handle multiple layers/series - for (let layerIdx = 0; layerIdx < model.series.length; layerIdx++) { - const layer = model.series[layerIdx]; - if (layer.hidden) { + for (const [layerIdx, series] of model.series.entries()) { + if (series.hidden) { continue; } - if (!isValidMetrics(layer.metrics, PANEL_TYPES.TIMESERIES)) { + if (!isValidMetrics(series.metrics, PANEL_TYPES.TIMESERIES)) { return null; } - const { indexPatternId, timeField } = await getDataSourceInfo( + const { indexPatternId, indexPattern, timeField } = await getDataSourceInfo( model.index_pattern, model.time_field, - Boolean(layer.override_index_pattern), - layer.series_index_pattern, + Boolean(series.override_index_pattern), + series.series_index_pattern, + series.series_time_field, dataViews ); - // handle multiple metrics - const series = getSeries(layer.metrics, seriesNum, layer.split_mode, layer.color); - if (!series || !series.metrics) { + if (!timeField) { return null; } - const splitFields = getFieldsForTerms(layer.terms_field); - - // in case of terms in a date field, we want to apply the date_histogram - const splitWithDateHistogram = await isSplitWithDateHistogram( - layer, - splitFields, - indexPatternId, - dataViews - ); - - if (splitWithDateHistogram === null) { + const dateHistogramColumn = convertToDateHistogramColumn(model, series, indexPattern!, { + fieldName: timeField, + isSplit: false, + }); + if (dateHistogramColumn === null) { + return null; + } + // handle multiple metrics + const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum); + if (!metricsColumns) { return null; } - const chartType = getChartType(layer, model.type); + const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, true); + if (bucketsColumns === null) { + return null; + } - layersConfiguration[layerIdx] = getLayerConfiguration( + const layerId = uuid(); + extendedLayers[layerIdx] = { indexPatternId, - layerIdx, - chartType, - model, - series, - { splitFields, xFieldName: timeField, xMode: 'date_histogram', splitWithDateHistogram } - ); + layerId, + columns: [...metricsColumns, dateHistogramColumn, ...bucketsColumns], + columnOrder: [], + }; } const extents = getYExtents(model); return { - layers: layersConfiguration, type: 'lnsXY', + layers: excludeMetaFromLayers(extendedLayers), configuration: { - fill: model.series[0].fill ?? 0.3, + layers: getLayers(extendedLayers, model), + fillOpacity: Number(model.series[0].fill) ?? 0.3, legend: { isVisible: Boolean(model.show_legend), showSingleSeries: Boolean(model.show_legend), - position: model.legend_position ?? 'right', + position: (model.legend_position as Position) ?? Position.Right, shouldTruncate: Boolean(model.truncate_legend), maxLines: model.max_lines_legend ?? 1, }, - gridLinesVisibility: { + gridlinesVisibilitySettings: { x: Boolean(model.show_grid), yLeft: Boolean(model.show_grid), yRight: Boolean(model.show_grid), }, - extents, + yLeftExtent: extents.yLeftExtent, + yRightExtent: extents.yRightExtent, }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts deleted file mode 100644 index f7f5514563cb1..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/new.index.ts +++ /dev/null @@ -1,120 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { Position } from '@elastic/charts'; -import { - Layer, - NavigateToLensContext, - XYConfiguration, -} from '@kbn/visualizations-plugin/common/convert_to_lens'; -import uuid from 'uuid'; -import { Panel } from '../../../common/types'; -import { PANEL_TYPES } from '../../../common/enums'; -import { getDataViewsStart } from '../../services'; -import { getDataSourceInfo } from '../lib/datasource'; -import { getMetricsColumns, getBucketsColumns } from '../lib/series'; -import { getLayers, getYExtents } from '../lib/configurations/xy'; -import { - Layer as ExtendedLayer, - convertToDateHistogramColumn, - excludeMetaFromColumn, -} from '../lib/convert'; -import { isValidMetrics } from '../lib/metrics'; - -const excludeMetaFromLayers = (layers: Record): Record => { - const newLayers: Record = {}; - Object.entries(layers).forEach(([layerId, layer]) => { - const columns = layer.columns.map(excludeMetaFromColumn); - newLayers[layerId] = { ...layer, columns }; - }); - - return newLayers; -}; - -export const convertToLens = async ( - model: Panel -): Promise | null> => { - const dataViews = getDataViewsStart(); - const extendedLayers: Record = {}; - const seriesNum = model.series.filter((series) => !series.hidden).length; - - // handle multiple layers/series - for (const [layerIdx, series] of model.series.entries()) { - if (series.hidden) { - continue; - } - - if (!isValidMetrics(series.metrics, PANEL_TYPES.TIMESERIES)) { - return null; - } - - const { indexPatternId, indexPattern, timeField } = await getDataSourceInfo( - model.index_pattern, - model.time_field, - Boolean(series.override_index_pattern), - series.series_index_pattern, - series.series_time_field, - dataViews - ); - - if (!timeField) { - return null; - } - - const dateHistogramColumn = convertToDateHistogramColumn(model, series, indexPattern!, { - fieldName: timeField, - isSplit: false, - }); - if (dateHistogramColumn === null) { - return null; - } - // handle multiple metrics - const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum); - if (!metricsColumns) { - return null; - } - - const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, true); - if (bucketsColumns === null) { - return null; - } - - const layerId = uuid(); - extendedLayers[layerIdx] = { - indexPatternId, - layerId, - columns: [...metricsColumns, dateHistogramColumn, ...bucketsColumns], - columnOrder: [], - }; - } - - const extents = getYExtents(model); - - return { - type: 'lnsXY', - layers: excludeMetaFromLayers(extendedLayers), - configuration: { - layers: getLayers(extendedLayers, model), - fillOpacity: Number(model.series[0].fill) ?? 0.3, - legend: { - isVisible: Boolean(model.show_legend), - showSingleSeries: Boolean(model.show_legend), - position: (model.legend_position as Position) ?? Position.Right, - shouldTruncate: Boolean(model.truncate_legend), - maxLines: model.max_lines_legend ?? 1, - }, - gridlinesVisibilitySettings: { - x: Boolean(model.show_grid), - yLeft: Boolean(model.show_grid), - yRight: Boolean(model.show_grid), - }, - yLeftExtent: extents.yLeftExtent, - yRightExtent: extents.yRightExtent, - }, - }; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts deleted file mode 100644 index 1f408bf3dfa89..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts +++ /dev/null @@ -1,329 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { DataView } from '@kbn/data-plugin/common'; -import type { Panel, Series } from '../../../common/types'; -import { convertToLens } from '.'; - -const dataViewsMap: Record = { - test1: { id: 'test1', title: 'test1', timeFieldName: 'timeField1' } as DataView, - test2: { - id: 'test2', - title: 'test2', - timeFieldName: 'timeField2', - } as DataView, - test3: { id: 'test3', title: 'test3', timeFieldName: 'timeField3' } as DataView, -}; - -const getDataview = (id: string): DataView | undefined => dataViewsMap[id]; -jest.mock('../../services', () => { - return { - getDataViewsStart: jest.fn(() => { - return { - getDefault: jest.fn(() => { - return { id: '12345', title: 'default', timeFieldName: '@timestamp' }; - }), - get: getDataview, - }; - }), - }; -}); - -const model = { - axis_position: 'left', - type: 'timeseries', - index_pattern: { id: 'test2' }, - use_kibana_indexes: true, - series: [ - { - color: '#000000', - chart_type: 'line', - fill: '0', - id: '85147356-c185-4636-9182-d55f3ab2b6fa', - palette: { - name: 'default', - type: 'palette', - }, - split_mode: 'everything', - metrics: [ - { - id: '3fa8b32f-5c38-4813-9361-1f2817ae5b18', - type: 'count', - }, - ], - override_index_pattern: 0, - }, - ], -} as Panel; - -describe('convertToLens for Top N', () => { - test('should return null for a non supported aggregation', async () => { - const nonSupportedAggModel = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - { - type: 'sum_of_squares_bucket', - }, - ] as Series['metrics'], - }, - ], - }; - const triggerOptions = await convertToLens(nonSupportedAggModel); - expect(triggerOptions).toBeNull(); - }); - - test('should return options for a supported aggregation', async () => { - const triggerOptions = await convertToLens(model); - expect(triggerOptions).toStrictEqual({ - configuration: { - fill: '0', - gridLinesVisibility: { x: false, yLeft: false, yRight: false }, - legend: { - isVisible: false, - maxLines: 1, - position: 'right', - shouldTruncate: false, - showSingleSeries: false, - }, - valueLabels: true, - tickLabelsVisibility: { x: true, yLeft: false, yRight: false }, - axisTitlesVisibility: { x: false, yLeft: false, yRight: false }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'left', - chartType: 'bar_horizontal', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - xFieldName: undefined, - xMode: undefined, - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); - - test('should return timeShift in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - offset_time: '1h', - }, - ], - }; - const triggerOptions = await convertToLens(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.shift).toBe('1h'); - }); - - test('should return filter in the params if it is provided', async () => { - const modelWithFill = { - ...model, - series: [ - { - ...model.series[0], - filter: { - language: 'kuery', - query: 'test', - }, - }, - ], - }; - const triggerOptions = await convertToLens(modelWithFill); - expect(triggerOptions?.layers[0]?.metrics?.[0]?.params?.kql).toBe('test'); - }); - - test('should return splitFilters information if the chart is broken down by filters', async () => { - const modelWithSplitFilters = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'filters', - split_filters: [ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ], - }, - ], - }; - const triggerOptions = await convertToLens(modelWithSplitFilters); - expect(triggerOptions?.layers[0]?.splitFilters).toStrictEqual([ - { - color: 'rgba(188,0,85,1)', - filter: { - language: 'kuery', - query: '', - }, - id: '89afac60-7d2b-11ec-917c-c18cd38d60b5', - }, - ]); - }); - - test('should return termsParams information if the chart is broken down by terms including series agg collapse fn', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - metrics: [ - ...model.series[0].metrics, - { - type: 'series_agg', - function: 'sum', - }, - ], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertToLens(modelWithTerms); - expect(triggerOptions?.layers[0]?.collapseFn).toStrictEqual('sum'); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: false, - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return include exclude information if the chart is broken down by terms', async () => { - const modelWithTerms = { - ...model, - series: [ - { - ...model.series[0], - split_mode: 'terms', - terms_size: 6, - terms_direction: 'desc', - terms_order_by: '_key', - terms_include: 't.*', - }, - ] as unknown as Series[], - }; - const triggerOptions = await convertToLens(modelWithTerms); - expect(triggerOptions?.layers[0]?.termsParams).toStrictEqual({ - size: 6, - otherBucket: false, - orderDirection: 'desc', - orderBy: { type: 'alphabetical' }, - includeIsRegex: true, - include: ['t.*'], - excludeIsRegex: false, - parentFormat: { - id: 'terms', - }, - }); - }); - - test('should return custom time interval if it is given', async () => { - const modelWithTerms = { - ...model, - interval: '1h', - }; - const triggerOptions = await convertToLens(modelWithTerms); - expect(triggerOptions?.layers[0]?.timeInterval).toBe('1h'); - }); - - test('should return dropPartialbuckets if enabled', async () => { - const modelWithDropBuckets = { - ...model, - drop_last_bucket: 1, - }; - const triggerOptions = await convertToLens(modelWithDropBuckets); - expect(triggerOptions?.layers[0]?.dropPartialBuckets).toBe(true); - }); - - test('should return the correct chart configuration', async () => { - const modelWithConfig = { - ...model, - show_legend: 1, - legend_position: 'bottom', - truncate_legend: 0, - show_grid: 1, - series: [{ ...model.series[0], fill: '0.3', separate_axis: 1, axis_position: 'right' }], - }; - const triggerOptions = await convertToLens(modelWithConfig); - expect(triggerOptions).toStrictEqual({ - configuration: { - fill: '0.3', - gridLinesVisibility: { x: false, yLeft: false, yRight: false }, - legend: { - isVisible: true, - maxLines: 1, - position: 'bottom', - shouldTruncate: false, - showSingleSeries: true, - }, - valueLabels: true, - tickLabelsVisibility: { x: true, yLeft: false, yRight: false }, - axisTitlesVisibility: { x: false, yLeft: false, yRight: false }, - }, - type: 'lnsXY', - layers: { - '0': { - axisPosition: 'right', - chartType: 'bar_horizontal', - collapseFn: undefined, - indexPatternId: 'test2', - metrics: [ - { - agg: 'count', - color: '#000000', - fieldName: 'document', - isFullReference: false, - params: {}, - }, - ], - palette: { - name: 'default', - type: 'palette', - }, - splitWithDateHistogram: false, - xFieldName: undefined, - xMode: undefined, - timeInterval: 'auto', - dropPartialBuckets: false, - }, - }, - }); - }); -}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts index 61d5b0948021a..3a06da582f186 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -6,110 +6,103 @@ * Side Public License, v 1. */ -import { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; -import { PANEL_TYPES, TIME_RANGE_DATA_MODES } from '../../../common/enums'; +import uuid from 'uuid'; +import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { Position } from '@elastic/charts'; +import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; -import { getSeries } from '../lib/series'; -import { getFieldsForTerms } from '../../../common/fields_utils'; -import { ConvertTsvbToLensVisualization } from '../types'; -import { isSplitWithDateHistogram } from '../lib/split_chart'; -import { getLayerConfiguration } from '../lib/layers'; +import { getMetricsColumns, getBucketsColumns } from '../lib/series'; +import { getLayers } from '../lib/configurations/xy'; import { getWindow, isValidMetrics } from '../lib/metrics'; +import { ConvertTsvbToLensVisualization } from '../types'; +import { Layer as ExtendedLayer, excludeMetaFromColumn } from '../lib/convert'; -export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeRange) => { - const layersConfiguration: { [key: string]: VisualizeEditorLayersContext } = {}; +const excludeMetaFromLayers = (layers: Record): Record => { + const newLayers: Record = {}; + Object.entries(layers).forEach(([layerId, layer]) => { + const columns = layer.columns.map(excludeMetaFromColumn); + newLayers[layerId] = { ...layer, columns }; + }); - // get the active series number - const seriesNum = model.series.filter((series) => !series.hidden).length; + return newLayers; +}; + +export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeRange) => { const dataViews = getDataViewsStart(); + const extendedLayers: Record = {}; + const seriesNum = model.series.filter((series) => !series.hidden).length; // handle multiple layers/series - for (let layerIdx = 0; layerIdx < model.series.length; layerIdx++) { - const layer = model.series[layerIdx]; - if (layer.hidden) { + for (const [layerIdx, series] of model.series.entries()) { + if (series.hidden) { continue; } - if (!isValidMetrics(layer.metrics, PANEL_TYPES.TOP_N, layer.time_range_mode)) { + if (!isValidMetrics(series.metrics, PANEL_TYPES.TOP_N, series.time_range_mode)) { return null; } - const { indexPatternId } = await getDataSourceInfo( + const { indexPatternId, indexPattern } = await getDataSourceInfo( model.index_pattern, model.time_field, - Boolean(layer.override_index_pattern), - layer.series_index_pattern, + Boolean(series.override_index_pattern), + series.series_index_pattern, + series.series_time_field, dataViews ); - const window = - model.time_range_mode === TIME_RANGE_DATA_MODES.LAST_VALUE - ? getWindow(model.interval, timeRange) - : undefined; + const window = getWindow(model, series, timeRange); // handle multiple metrics - const series = getSeries(layer.metrics, seriesNum, layer.split_mode, layer.color, window); - if (!series || !series.metrics) { + const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, window); + if (!metricsColumns) { return null; } - const splitFields = getFieldsForTerms(layer.terms_field); - - // in case of terms in a date field, we want to apply the date_histogram - const splitWithDateHistogram = await isSplitWithDateHistogram( - layer, - splitFields, - indexPatternId, - dataViews - ); - - if (splitWithDateHistogram === null) { + const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, false); + if (bucketsColumns === null) { return null; } - layersConfiguration[layerIdx] = getLayerConfiguration( + const layerId = uuid(); + extendedLayers[layerIdx] = { indexPatternId, - layerIdx, - 'bar_horizontal', - model, - series, - { - splitFields, - splitWithDateHistogram, - window, - } - ); + layerId, + columns: [...metricsColumns, ...bucketsColumns], + columnOrder: [], + }; } return { - layers: layersConfiguration, type: 'lnsXY', + layers: excludeMetaFromLayers(extendedLayers), configuration: { + layers: getLayers(extendedLayers, model), fill: model.series[0].fill ?? 0.3, legend: { isVisible: Boolean(model.show_legend), showSingleSeries: Boolean(model.show_legend), - position: model.legend_position ?? 'right', + position: (model.legend_position as Position) ?? Position.Right, shouldTruncate: Boolean(model.truncate_legend), maxLines: model.max_lines_legend ?? 1, }, - gridLinesVisibility: { + gridlinesVisibilitySettings: { x: false, yLeft: false, yRight: false, }, - tickLabelsVisibility: { + tickLabelsVisibilitySettings: { x: true, yLeft: false, yRight: false, }, - axisTitlesVisibility: { + axisTitlesVisibilitySettings: { x: false, yLeft: false, yRight: false, }, - valueLabels: true, + valueLabels: 'show', }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts deleted file mode 100644 index 3a06da582f186..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts +++ /dev/null @@ -1,108 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import uuid from 'uuid'; -import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { Position } from '@elastic/charts'; -import { PANEL_TYPES } from '../../../common/enums'; -import { getDataViewsStart } from '../../services'; -import { getDataSourceInfo } from '../lib/datasource'; -import { getMetricsColumns, getBucketsColumns } from '../lib/series'; -import { getLayers } from '../lib/configurations/xy'; -import { getWindow, isValidMetrics } from '../lib/metrics'; -import { ConvertTsvbToLensVisualization } from '../types'; -import { Layer as ExtendedLayer, excludeMetaFromColumn } from '../lib/convert'; - -const excludeMetaFromLayers = (layers: Record): Record => { - const newLayers: Record = {}; - Object.entries(layers).forEach(([layerId, layer]) => { - const columns = layer.columns.map(excludeMetaFromColumn); - newLayers[layerId] = { ...layer, columns }; - }); - - return newLayers; -}; - -export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeRange) => { - const dataViews = getDataViewsStart(); - const extendedLayers: Record = {}; - const seriesNum = model.series.filter((series) => !series.hidden).length; - - // handle multiple layers/series - for (const [layerIdx, series] of model.series.entries()) { - if (series.hidden) { - continue; - } - - if (!isValidMetrics(series.metrics, PANEL_TYPES.TOP_N, series.time_range_mode)) { - return null; - } - - const { indexPatternId, indexPattern } = await getDataSourceInfo( - model.index_pattern, - model.time_field, - Boolean(series.override_index_pattern), - series.series_index_pattern, - series.series_time_field, - dataViews - ); - - const window = getWindow(model, series, timeRange); - - // handle multiple metrics - const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, window); - if (!metricsColumns) { - return null; - } - - const bucketsColumns = getBucketsColumns(model, series, metricsColumns, indexPattern!, false); - if (bucketsColumns === null) { - return null; - } - - const layerId = uuid(); - extendedLayers[layerIdx] = { - indexPatternId, - layerId, - columns: [...metricsColumns, ...bucketsColumns], - columnOrder: [], - }; - } - - return { - type: 'lnsXY', - layers: excludeMetaFromLayers(extendedLayers), - configuration: { - layers: getLayers(extendedLayers, model), - fill: model.series[0].fill ?? 0.3, - legend: { - isVisible: Boolean(model.show_legend), - showSingleSeries: Boolean(model.show_legend), - position: (model.legend_position as Position) ?? Position.Right, - shouldTruncate: Boolean(model.truncate_legend), - maxLines: model.max_lines_legend ?? 1, - }, - gridlinesVisibilitySettings: { - x: false, - yLeft: false, - yRight: false, - }, - tickLabelsVisibilitySettings: { - x: true, - yLeft: false, - yRight: false, - }, - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: false, - }, - valueLabels: 'show', - }, - }; -}; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/context.ts b/src/plugins/visualizations/common/convert_to_lens/types/context.ts index f3cc17b19e639..c398f79bbc224 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/context.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/context.ts @@ -16,7 +16,7 @@ export interface Layer { columnOrder: string[]; } -export interface NavigateToLensContext { +export interface NavigateToLensContext { layers: Record; type: string; configuration: T; diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index 78ba1d19a982f..39fc5e570a9cf 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -24,15 +24,7 @@ export { getVisSchemas } from './vis_schemas'; /** @public types */ export type { VisualizationsSetup, VisualizationsStart }; export { VisGroups } from './vis_types/vis_groups_enum'; -export type { - BaseVisType, - VisTypeAlias, - VisTypeDefinition, - Schema, - ISchemas, - NavigateToLensContext, - VisualizeEditorLayersContext, -} from './vis_types'; +export type { BaseVisType, VisTypeAlias, VisTypeDefinition, Schema, ISchemas } from './vis_types'; export type { Vis, SerializedVis, SerializedVisData, VisData } from './vis'; export type VisualizeEmbeddableFactoryContract = PublicContract; export type VisualizeEmbeddableContract = PublicContract; diff --git a/src/plugins/visualizations/public/vis_types/types.ts b/src/plugins/visualizations/public/vis_types/types.ts index 47c314e9d175c..56fc90d2bb4cb 100644 --- a/src/plugins/visualizations/public/vis_types/types.ts +++ b/src/plugins/visualizations/public/vis_types/types.ts @@ -8,14 +8,13 @@ import type { IconType } from '@elastic/eui'; import type { ReactNode } from 'react'; -import type { PaletteOutput } from '@kbn/coloring'; import type { Adapters } from '@kbn/inspector-plugin/common'; import { TimeRange } from '@kbn/data-plugin/common'; -import type { Query } from '@kbn/es-query'; import type { AggGroupNames, AggParam, AggGroupName } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { Vis, VisEditorOptionsProps, VisParams, VisToExpressionAst } from '../types'; import { VisGroups } from './vis_groups_enum'; +import { NavigateToLensContext } from '../../common'; export interface VisTypeOptions { showTimePicker: boolean; @@ -73,87 +72,6 @@ interface CustomEditorConfig { editor: string; } -interface SplitByFilters { - color?: string; - filter?: Query; - id?: string; - label?: string; -} - -interface VisualizeEditorMetricContext { - agg: string; - fieldName: string; - pipelineAggType?: string; - params?: Record; - isFullReference: boolean; - color?: string; - accessor?: string; -} - -export interface VisualizeEditorLayersContext { - indexPatternId: string; - splitWithDateHistogram?: boolean; - xFieldName?: string; - xMode?: string; - chartType?: string; - axisPosition?: string; - termsParams?: Record; - splitFields?: string[]; - splitMode?: string; - collapseFn?: string; - splitFilters?: SplitByFilters[]; - palette?: PaletteOutput; - metrics: VisualizeEditorMetricContext[]; - timeInterval?: string; - format?: string; - label?: string; - layerId?: string; - dropPartialBuckets?: boolean; -} - -interface AxisExtents { - mode: string; - lowerBound?: number; - upperBound?: number; -} - -export interface NavigateToLensContext { - layers: { - [key: string]: VisualizeEditorLayersContext; - }; - type: string; - configuration: { - fill: number | string; - legend: { - isVisible: boolean; - position: string; - shouldTruncate: boolean; - maxLines: number; - showSingleSeries: boolean; - }; - gridLinesVisibility: { - x: boolean; - yLeft: boolean; - yRight: boolean; - }; - tickLabelsVisibility?: { - x: boolean; - yLeft: boolean; - yRight: boolean; - }; - axisTitlesVisibility?: { - x: boolean; - yLeft: boolean; - yRight: boolean; - }; - valueLabels?: boolean; - extents?: { - yLeftExtent?: AxisExtents; - yRightExtent?: AxisExtents; - }; - }; -} - /** * A visualization type definition representing a spec of one specific type of "classical" * visualizations (i.e. not Lens visualizations). From 8ddaed9825085e937bfd2dd20d7671d242f3b100 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 12:45:08 +0300 Subject: [PATCH 059/129] Removed unused import. --- .../timeseries/public/convert_to_lens/lib/datasource/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/index.ts index befb8af63a745..a3a34212f48b6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/index.ts @@ -7,4 +7,3 @@ */ export * from './get_datasource_info'; -export * from './get_field_type'; From f49d11a832e28365e0ae09d476e7dbf8cf6c8285 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 13:27:52 +0300 Subject: [PATCH 060/129] Fixed types. --- .../convert_to_lens/timeseries/index.ts | 2 +- .../public/convert_to_lens/top_n/index.ts | 2 +- .../common/convert_to_lens/types/context.ts | 2 +- .../visualizations/public/vis_types/index.ts | 8 +- .../components/visualize_top_nav.tsx | 2 +- .../utils/get_top_nav_config.tsx | 8 +- x-pack/plugins/lens/public/types.ts | 42 +-- .../visualizations/xy/visualization.test.ts | 292 +----------------- 8 files changed, 12 insertions(+), 346 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index b7429dd67eca5..cc0b68df24a2a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -92,7 +92,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model: Panel return { type: 'lnsXY', - layers: excludeMetaFromLayers(extendedLayers), + layers: Object.values(excludeMetaFromLayers(extendedLayers)), configuration: { layers: getLayers(extendedLayers, model), fillOpacity: Number(model.series[0].fill) ?? 0.3, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts index 3a06da582f186..d992a199dd349 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -76,7 +76,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR return { type: 'lnsXY', - layers: excludeMetaFromLayers(extendedLayers), + layers: Object.values(excludeMetaFromLayers(extendedLayers)), configuration: { layers: getLayers(extendedLayers, model), fill: model.series[0].fill ?? 0.3, diff --git a/src/plugins/visualizations/common/convert_to_lens/types/context.ts b/src/plugins/visualizations/common/convert_to_lens/types/context.ts index c398f79bbc224..037d1c8c96a1c 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/context.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/context.ts @@ -17,7 +17,7 @@ export interface Layer { } export interface NavigateToLensContext { - layers: Record; + layers: Layer[]; type: string; configuration: T; } diff --git a/src/plugins/visualizations/public/vis_types/index.ts b/src/plugins/visualizations/public/vis_types/index.ts index e297d9192ed21..365f0d51bf4f3 100644 --- a/src/plugins/visualizations/public/vis_types/index.ts +++ b/src/plugins/visualizations/public/vis_types/index.ts @@ -10,10 +10,4 @@ export * from './types_service'; export { Schemas } from './schemas'; export { VisGroups } from './vis_groups_enum'; export { BaseVisType } from './base_vis_type'; -export type { - VisTypeDefinition, - ISchemas, - Schema, - NavigateToLensContext, - VisualizeEditorLayersContext, -} from './types'; +export type { VisTypeDefinition, ISchemas, Schema } from './types'; diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx index c80492b45c5cb..3ba6d035f31fb 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx @@ -21,7 +21,7 @@ import type { } from '../types'; import { VISUALIZE_APP_NAME } from '../../../common/constants'; import { getTopNavConfig, isFallbackDataView } from '../utils'; -import type { NavigateToLensContext } from '../..'; +import type { NavigateToLensContext } from '../../../common'; const LOCAL_STORAGE_EDIT_IN_LENS_BADGE = 'EDIT_IN_LENS_BADGE_VISIBLE'; diff --git a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx index 8b9b42201a442..db5f02312238b 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx +++ b/src/plugins/visualizations/public/visualize_app/utils/get_top_nav_config.tsx @@ -27,18 +27,14 @@ import { import { unhashUrl } from '@kbn/kibana-utils-plugin/public'; import { EmbeddableStateTransfer } from '@kbn/embeddable-plugin/public'; import { saveVisualization } from '../../utils/saved_visualize_utils'; -import { - VISUALIZE_EMBEDDABLE_TYPE, - VisualizeInput, - getFullPath, - NavigateToLensContext, -} from '../..'; +import { VISUALIZE_EMBEDDABLE_TYPE, VisualizeInput, getFullPath } from '../..'; import { VisualizeServices, VisualizeAppStateContainer, VisualizeEditorVisInstance, } from '../types'; +import { NavigateToLensContext } from '../../../common'; import { VisualizeConstants } from '../../../common/constants'; import { getEditBreadcrumbs } from './breadcrumbs'; import { VISUALIZE_APP_LOCATOR, VisualizeLocatorParams } from '../../../common/locator'; diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 865cba22157a5..67f6db15f8f40 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -17,8 +17,7 @@ import type { IInterpreterRenderHandlers, Datatable, } from '@kbn/expressions-plugin/public'; -import type { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; -import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import type { NavigateToLensContext } from '@kbn/visualizations-plugin/common'; import type { Query } from '@kbn/es-query'; import type { UiActionsStart, @@ -209,35 +208,13 @@ export interface InitializationOptions { isFullEditor?: boolean; } -interface AxisExtents { - mode: string; - lowerBound?: number; - upperBound?: number; -} - -export interface VisualizeEditorContext { - layers: VisualizeEditorLayersContext[]; - configuration: ChartSettings; +export type VisualizeEditorContext = { savedObjectId?: string; embeddableId?: string; vizEditorOriginatingAppUrl?: string; originatingApp?: string; isVisualizeAction: boolean; - type: string; -} - -interface ChartSettings { - fill?: string; - legend?: Record; - gridLinesVisibility?: Record; - tickLabelsVisibility?: Record; - axisTitlesVisibility?: Record; - valueLabels?: boolean; - extents?: { - yLeftExtent: AxisExtents; - yRightExtent: AxisExtents; - }; -} +} & NavigateToLensContext; export interface GetDropPropsArgs { state: T; @@ -358,7 +335,7 @@ export interface Datasource { ) => Array>; getDatasourceSuggestionsForVisualizeCharts: ( state: T, - context: Layer[], + context: NavigateToLensContext['layers'], indexPatterns: IndexPatternMap ) => Array>; getDatasourceSuggestionsForVisualizeField: ( @@ -731,17 +708,6 @@ export interface Suggestion { keptLayerIds: string[]; } -interface VisualizationConfigurationFromContextChangeProps { - layerId: string; - prevState: T; - context: VisualizeEditorLayersContext; -} - -interface VisualizationStateFromContextChangeProps { - suggestions: Suggestion[]; - context: VisualizeEditorContext; -} - /** * Object passed to `getSuggestions` of a visualization. * It contains a possible table the current datasource could diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts index ad26ea92762bf..5a8596e542030 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts @@ -7,17 +7,10 @@ import { getXyVisualization } from './visualization'; import { Position } from '@elastic/charts'; -import { - Operation, - VisualizeEditorContext, - Suggestion, - OperationDescriptor, - DatasourcePublicAPI, -} from '../../types'; +import { Operation, OperationDescriptor, DatasourcePublicAPI } from '../../types'; import type { State, XYState, - XYSuggestion, XYLayerConfig, XYDataLayerConfig, XYReferenceLineLayerConfig, @@ -26,7 +19,6 @@ import type { import { layerTypes } from '../../../common'; import { createMockDatasource, createMockFramePublicAPI } from '../../mocks'; import { IconChartBar } from '@kbn/chart-icons'; -import type { VisualizeEditorLayersContext } from '@kbn/visualizations-plugin/public'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { Datatable } from '@kbn/expressions-plugin/common'; @@ -752,288 +744,6 @@ describe('xy_visualization', () => { }); }); - describe('#updateLayersConfigurationFromContext', () => { - let mockDatasource: ReturnType; - let frame: ReturnType; - let context: VisualizeEditorLayersContext; - - beforeEach(() => { - frame = createMockFramePublicAPI(); - mockDatasource = createMockDatasource('testDatasource'); - - mockDatasource.publicAPIMock.getTableSpec.mockReturnValue([ - { columnId: 'd', fields: [] }, - { columnId: 'a', fields: [] }, - { columnId: 'b', fields: [] }, - { columnId: 'c', fields: [] }, - ]); - - frame.datasourceLayers = { - first: mockDatasource.publicAPIMock, - }; - - frame.activeData = { - first: { - type: 'datatable', - rows: [], - columns: [], - }, - }; - - context = { - chartType: 'area', - axisPosition: 'right', - palette: { - name: 'temperature', - type: 'palette', - }, - metrics: [ - { - agg: 'count', - isFullReference: false, - fieldName: 'document', - params: {}, - color: '#68BC00', - }, - ], - timeInterval: 'auto', - format: 'bytes', - } as VisualizeEditorLayersContext; - }); - - it('sets the context configuration correctly', () => { - const state = xyVisualization?.updateLayersConfigurationFromContext?.({ - prevState: { - ...exampleState(), - layers: [ - { - layerId: 'first', - layerType: layerTypes.DATA, - seriesType: 'line', - xAccessor: undefined, - accessors: ['a'], - }, - ], - }, - layerId: 'first', - context, - }); - expect(state?.layers[0]).toHaveProperty('seriesType', 'area'); - expect((state?.layers[0] as XYDataLayerConfig).yConfig).toStrictEqual([ - { - axisMode: 'right', - color: '#68BC00', - forAccessor: 'a', - }, - ]); - - expect((state?.layers[0] as XYDataLayerConfig).palette).toStrictEqual({ - name: 'temperature', - type: 'palette', - }); - }); - - it('sets the context configuration correctly for reference lines', () => { - const newContext = { - ...context, - metrics: [ - { - agg: 'static_value', - fieldName: 'document', - isFullReference: true, - color: '#68BC00', - params: { - value: '10', - }, - }, - ], - }; - const state = xyVisualization?.updateLayersConfigurationFromContext?.({ - prevState: { - ...exampleState(), - layers: [ - { - layerId: 'first', - layerType: layerTypes.DATA, - seriesType: 'line', - xAccessor: undefined, - accessors: ['a'], - }, - ], - }, - layerId: 'first', - context: newContext, - }); - const firstLayer = state?.layers[0] as XYDataLayerConfig; - expect(firstLayer).toHaveProperty('seriesType', 'area'); - expect(firstLayer).toHaveProperty('layerType', 'referenceLine'); - expect(firstLayer.yConfig).toStrictEqual([ - { - axisMode: 'right', - color: '#68BC00', - forAccessor: 'a', - fill: 'below', - }, - ]); - }); - }); - - describe('#getVisualizationSuggestionFromContext', () => { - let context: VisualizeEditorContext; - let suggestions: Suggestion[]; - - beforeEach(() => { - suggestions = [ - { - title: 'Average of AvgTicketPrice over timestamp', - score: 0.3333333333333333, - hide: true, - visualizationId: 'lnsXY', - visualizationState: { - legend: { - isVisible: true, - position: 'right', - }, - valueLabels: 'hide', - fittingFunction: 'None', - axisTitlesVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - tickLabelsVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - labelsOrientation: { - x: 0, - yLeft: 0, - yRight: 0, - }, - gridlinesVisibilitySettings: { - x: true, - yLeft: true, - yRight: true, - }, - preferredSeriesType: 'bar_stacked', - layers: [ - { - layerId: 'e71c3459-ddcf-4a13-94a1-bf91f7b40175', - seriesType: 'bar_stacked', - xAccessor: '911abe51-36ca-42ba-ae4e-bcf3f941f3c1', - accessors: ['0ffeb3fb-86fd-42d1-ab62-5a00b7000a7b'], - layerType: 'data', - }, - ], - }, - keptLayerIds: [], - datasourceState: { - layers: { - 'e71c3459-ddcf-4a13-94a1-bf91f7b40175': { - indexPatternId: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', - columns: { - '911abe51-36ca-42ba-ae4e-bcf3f941f3c1': { - label: 'timestamp', - dataType: 'date', - operationType: 'date_histogram', - sourceField: 'timestamp', - isBucketed: true, - scale: 'interval', - params: { - interval: 'auto', - }, - }, - '0ffeb3fb-86fd-42d1-ab62-5a00b7000a7b': { - label: 'Average of AvgTicketPrice', - dataType: 'number', - operationType: 'average', - sourceField: 'AvgTicketPrice', - isBucketed: false, - scale: 'ratio', - }, - }, - columnOrder: [ - '911abe51-36ca-42ba-ae4e-bcf3f941f3c1', - '0ffeb3fb-86fd-42d1-ab62-5a00b7000a7b', - ], - incompleteColumns: {}, - }, - }, - }, - datasourceId: 'indexpattern', - columns: 2, - changeType: 'initial', - }, - ] as unknown as Suggestion[]; - - context = { - layers: [ - { - indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - xFieldName: 'order_date', - xMode: 'date_histogram', - chartType: 'area', - axisPosition: 'left', - palette: { - type: 'palette', - name: 'default', - }, - metrics: [ - { - agg: 'count', - isFullReference: false, - fieldName: 'document', - params: {}, - color: '#68BC00', - }, - ], - timeInterval: 'auto', - }, - ], - type: 'lnsXY', - configuration: { - fill: '0.5', - legend: { - isVisible: true, - position: 'right', - shouldTruncate: true, - maxLines: true, - }, - gridLinesVisibility: { - x: true, - yLeft: true, - yRight: true, - }, - extents: { - yLeftExtent: { - mode: 'full', - }, - yRightExtent: { - mode: 'full', - }, - }, - }, - isVisualizeAction: true, - } as VisualizeEditorContext; - }); - - it('updates the visualization state correctly based on the context', () => { - const suggestion = xyVisualization?.getVisualizationSuggestionFromContext?.({ - suggestions, - context, - }) as XYSuggestion; - expect(suggestion?.visualizationState?.fillOpacity).toEqual(0.5); - expect(suggestion?.visualizationState?.yRightExtent).toEqual({ mode: 'full' }); - expect(suggestion?.visualizationState?.legend).toEqual({ - isVisible: true, - maxLines: true, - position: 'right', - shouldTruncate: true, - }); - }); - }); - describe('#removeDimension', () => { let mockDatasource: ReturnType; let frame: ReturnType; From f472b4247706c541bcd16e7dff237240c0b4af19 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 13:28:29 +0300 Subject: [PATCH 061/129] Removed tests with type troubles. --- .../editor_frame/suggestion_helpers.test.ts | 177 +----------------- .../indexpattern_datasource/loader.test.ts | 46 ----- 2 files changed, 1 insertion(+), 222 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts index e566443640d85..7adcf2d708ae2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts @@ -13,12 +13,7 @@ import { DatasourceMock, createMockFramePublicAPI, } from '../../mocks'; -import { - TableSuggestion, - DatasourceSuggestion, - Visualization, - VisualizeEditorContext, -} from '../../types'; +import { TableSuggestion, DatasourceSuggestion, Visualization } from '../../types'; import { DatasourceStates, DataViewsState } from '../../state_management'; const generateSuggestion = (state = {}, layerId: string = 'first'): DatasourceSuggestion => ({ @@ -276,176 +271,6 @@ describe('suggestion helpers', () => { ).not.toHaveBeenCalled(); }); - it('should call getDatasourceSuggestionsForVisualizeCharts when a visualizeChartTrigger is passed', () => { - datasourceMap.mock.getDatasourceSuggestionsForVisualizeCharts.mockReturnValue([ - generateSuggestion(), - ]); - - const visualizationMap = { - testVis: createMockVisualization(), - }; - const triggerContext = { - layers: [ - { - indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - xFieldName: 'order_date', - xMode: 'date_histogram', - chartType: 'area', - axisPosition: 'left', - palette: { - type: 'palette', - name: 'default', - }, - metrics: [ - { - agg: 'count', - isFullReference: false, - fieldName: 'document', - params: {}, - color: '#68BC00', - }, - ], - timeInterval: 'auto', - }, - ], - type: 'lnsXY', - configuration: { - fill: '0.5', - legend: { - isVisible: true, - position: 'right', - shouldTruncate: true, - maxLines: true, - }, - gridLinesVisibility: { - x: true, - yLeft: true, - yRight: true, - }, - extents: { - yLeftExtent: { - mode: 'full', - }, - yRightExtent: { - mode: 'full', - }, - }, - }, - isVisualizeAction: true, - } as VisualizeEditorContext; - - getSuggestions({ - visualizationMap, - activeVisualization: visualizationMap.testVis, - visualizationState: {}, - datasourceMap, - datasourceStates, - visualizeTriggerFieldContext: triggerContext, - dataViews, - }); - expect(datasourceMap.mock.getDatasourceSuggestionsForVisualizeCharts).toHaveBeenCalledWith( - datasourceStates.mock.state, - triggerContext.layers, - dataViews.indexPatterns - ); - }); - - it('should call getDatasourceSuggestionsForVisualizeCharts from all datasources with a state', () => { - const multiDatasourceStates = { - mock: { - isLoading: false, - state: {}, - }, - mock2: { - isLoading: false, - state: {}, - }, - }; - const multiDatasourceMap = { - mock: createMockDatasource('a'), - mock2: createMockDatasource('a'), - mock3: createMockDatasource('a'), - }; - const triggerContext = { - layers: [ - { - indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - xFieldName: 'order_date', - xMode: 'date_histogram', - chartType: 'area', - axisPosition: 'left', - palette: { - type: 'palette', - name: 'default', - }, - metrics: [ - { - agg: 'count', - isFullReference: false, - fieldName: 'document', - params: {}, - color: '#68BC00', - }, - ], - timeInterval: 'auto', - }, - ], - type: 'lnsXY', - configuration: { - fill: '0.5', - legend: { - isVisible: true, - position: 'right', - shouldTruncate: true, - maxLines: true, - }, - gridLinesVisibility: { - x: true, - yLeft: true, - yRight: true, - }, - extents: { - yLeftExtent: { - mode: 'full', - }, - yRightExtent: { - mode: 'full', - }, - }, - }, - isVisualizeAction: true, - } as VisualizeEditorContext; - - const visualizationMap = { - testVis: createMockVisualization(), - }; - getSuggestions({ - visualizationMap, - activeVisualization: visualizationMap.testVis, - visualizationState: {}, - datasourceMap: multiDatasourceMap, - datasourceStates: multiDatasourceStates, - visualizeTriggerFieldContext: triggerContext, - dataViews, - }); - expect(multiDatasourceMap.mock.getDatasourceSuggestionsForVisualizeCharts).toHaveBeenCalledWith( - datasourceStates.mock.state, - triggerContext.layers, - dataViews.indexPatterns - ); - - expect( - multiDatasourceMap.mock2.getDatasourceSuggestionsForVisualizeCharts - ).toHaveBeenCalledWith( - multiDatasourceStates.mock2.state, - triggerContext.layers, - dataViews.indexPatterns - ); - expect( - multiDatasourceMap.mock3.getDatasourceSuggestionsForVisualizeCharts - ).not.toHaveBeenCalled(); - }); - it('should rank the visualizations by score', () => { const mockVisualization1 = createMockVisualization(); const mockVisualization2 = createMockVisualization(); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts index 80f6eaecd3a8a..6b5f30d36bdcc 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts @@ -140,52 +140,6 @@ describe('loader', () => { }); }); - it('should use the indexPatternId of the visualize trigger chart context, if provided', () => { - const storage = createMockStorage(); - const state = loadInitialState({ - storage, - initialContext: { - layers: [ - { - indexPatternId: '1', - xFieldName: 'timestamp', - xMode: 'date_histogram', - chartType: 'area', - axisPosition: 'left', - metrics: [], - timeInterval: 'auto', - }, - ], - type: 'lnsXY', - configuration: { - legend: { - isVisible: true, - position: 'right', - shouldTruncate: true, - maxLines: true, - }, - gridLinesVisibility: { - x: true, - yLeft: true, - yRight: true, - }, - }, - savedObjectId: '', - isVisualizeAction: true, - }, - indexPatternRefs, - indexPatterns: sampleIndexPatterns, - }); - - expect(state).toMatchObject({ - currentIndexPatternId: '1', - layers: {}, - }); - expect(storage.set).toHaveBeenCalledWith('lens-settings', { - indexPatternId: '1', - }); - }); - it('should initialize all the embeddable references without local storage', () => { const savedState: IndexPatternPersistedState = { layers: { From 3ffa2c681d7d5354835c1d7d2874e6478aae5263 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 16:05:35 +0300 Subject: [PATCH 062/129] Some code refactoring + formatter. --- .../convert_to_lens/lib/convert/column.ts | 31 +++++-- .../lib/convert/counter_rate.ts | 22 +++-- .../lib/convert/cumulative_sum.ts | 32 +++----- .../lib/convert/filter_ratio.ts | 12 ++- .../convert_to_lens/lib/convert/formula.ts | 34 ++++---- .../convert_to_lens/lib/convert/index.ts | 2 +- .../convert_to_lens/lib/convert/last_value.ts | 13 ++- .../lib/convert/parent_pipeline.ts | 82 +++++++++---------- .../convert_to_lens/lib/convert/percentile.ts | 26 +++--- .../lib/convert/percentile_rank.ts | 15 ++-- .../lib/convert/static_value.ts | 14 ++-- .../lib/convert/std_deviation.ts | 45 +++++----- .../convert_to_lens/lib/convert/terms.ts | 4 +- .../convert_to_lens/lib/convert/types.ts | 14 ++++ .../lib/series/metrics_columns.ts | 44 +++++----- .../public/convert_to_lens/types.ts | 9 +- .../common/convert_to_lens/types/params.ts | 76 +++++------------ 17 files changed, 229 insertions(+), 246 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index c7a491b9371a0..7db35011e47fc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -12,12 +12,13 @@ import { Operation, DataType, ColumnWithMeta as GenericColumnWithMeta, + FormatParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; import { ConvertToColumnsFn } from '../../types'; import { getTimeScale } from '../metrics'; -import { ColumnWithMeta, Meta, Column } from './types'; +import { ColumnWithMeta, Meta, Column, CommonColumnsConverterArgs } from './types'; type GeneralColumn = Omit, 'operationType' | 'params'>; type GeneralColumnWithMeta = GenericColumnWithMeta; @@ -27,6 +28,28 @@ interface ExtraColumnFields { window?: string; } +export const getFormat = ( + series: Series, + fieldName: string | undefined, + dataView: DataView +): FormatParams => { + if (series.formatter === 'default') { + if (!fieldName) { + return {}; + } + + const field = dataView.getFieldByName(fieldName); + if (!field) { + return {}; + } + + const formatter = dataView.getFormatterForField(field); + const id = formatter.type.id; + return { format: { id } }; + } + return { format: { id: series.formatter } }; // TODO: fix this formatter later, after investigation... +}; + export const createColumn = ( series: Series, metric: Metric, @@ -45,12 +68,10 @@ export const createColumn = ( }); export const convertMetricsToColumns = ( - series: Series, - metrics: Metric[], - dataView: DataView, + { series, metrics, dataView }: CommonColumnsConverterArgs, convertToFn: ConvertToColumnsFn, window?: string -) => metrics.flatMap((metric) => convertToFn(series, metric, dataView, window)); +) => metrics.flatMap((metric) => convertToFn({ series, metric, dataView }, window)); export const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { if ((column as ColumnWithMeta).meta) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts index e39f9f1378580..a83c29d63ef55 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts @@ -6,24 +6,22 @@ * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-views-plugin/common'; -import type { Metric, Series } from '../../../../common/types'; import { buildCounterRateFormula } from '../metrics'; import { createFormulaColumn } from './formula'; -import { FormulaColumn } from './types'; +import { CommonColumnsConverterArgs, FormulaColumn } from './types'; -export const convertToCounterRateFormulaColumn = ( - series: Series, - metrics: Metric[], - dataView: DataView -): FormulaColumn | null => { - const currentMetric = metrics[metrics.length - 1]; +export const convertToCounterRateFormulaColumn = ({ + series, + metrics, + dataView, +}: CommonColumnsConverterArgs): FormulaColumn | null => { + const metric = metrics[metrics.length - 1]; - const field = currentMetric.field ? dataView.getFieldByName(currentMetric.field) : undefined; + const field = metric.field ? dataView.getFieldByName(metric.field) : undefined; if (!field) { return null; } - const formula = buildCounterRateFormula(currentMetric, field); - return createFormulaColumn(formula, series, currentMetric); + const formula = buildCounterRateFormula(metric, field); + return createFormulaColumn(formula, { series, metric, dataView }); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index bd55b51e67758..c797ab90f25a4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -7,26 +7,23 @@ */ import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import type { DataView } from '@kbn/data-views-plugin/common'; -import type { Metric, Series } from '../../../../common/types'; import { SUPPORTED_METRICS, getParentPipelineSeriesFormula } from '../metrics'; import { createFormulaColumn } from './formula'; import { computeParentPipelineColumns } from './parent_pipeline'; +import { CommonColumnsConverterArgs } from './types'; export const convertToCumulativeSumColumns = ( - series: Series, - metrics: Metric[], - dataView: DataView, + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ) => { - const currentMetric = metrics[metrics.length - 1]; - if (!currentMetric) { + const metric = metrics[metrics.length - 1]; + if (!metric) { return null; } // percentile and percentile_rank value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] - const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; - const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); + const [fieldId, meta] = metric?.field?.split('[') ?? []; + const subFunctionMetric = metrics.find(({ id }) => id === fieldId); if (!subFunctionMetric || subFunctionMetric.type === 'static') { return null; } @@ -39,18 +36,15 @@ export const convertToCumulativeSumColumns = ( // and everything else as formula if (pipelineAgg.name !== 'count' && pipelineAgg.name !== 'sum') { const metaValue = Number(meta?.replace(']', '')); - formula = getParentPipelineSeriesFormula( - metrics, - subFunctionMetric, - pipelineAgg, - currentMetric.type, - { metaValue, window } - ); + formula = getParentPipelineSeriesFormula(metrics, subFunctionMetric, pipelineAgg, metric.type, { + metaValue, + window, + }); if (!formula) { return null; } - return createFormulaColumn(formula, series, currentMetric); + return createFormulaColumn(formula, { series, metric, dataView }); } else { const agg = SUPPORTED_METRICS[METRIC_TYPES.CUMULATIVE_SUM]; if (!agg) { @@ -59,9 +53,7 @@ export const convertToCumulativeSumColumns = ( return computeParentPipelineColumns( agg.name, - series, - currentMetric, - dataView, + { series, metric, dataView }, subFunctionMetric, pipelineAgg, { window } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts index 66b3dadf57a48..6c850fa332967 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -6,23 +6,21 @@ * Side Public License, v 1. */ -import type { Metric, Series } from '../../../../common/types'; import { getFilterRatioFormula } from '../metrics'; import { createFormulaColumn } from './formula'; -import { FormulaColumn } from './types'; +import { CommonColumnsConverterArgs, FormulaColumn } from './types'; export const convertFilterRatioToFormulaColumn = ( - series: Series, - metrics: Metric[], + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ): FormulaColumn | null => { - const currentMetric = metrics[metrics.length - 1]; + const metric = metrics[metrics.length - 1]; - const formula = getFilterRatioFormula(currentMetric, window); + const formula = getFilterRatioFormula(metric, window); if (!formula) { return null; } - return createFormulaColumn(formula, series, currentMetric); + return createFormulaColumn(formula, { series, metric, dataView }); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 00570a28c80cf..3056bba88af3f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -8,11 +8,11 @@ import { METRIC_TYPES } from '@kbn/data-plugin/public'; import { FormulaParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { FormulaColumn } from './types'; +import { CommonColumnConverterArgs, CommonColumnsConverterArgs, FormulaColumn } from './types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; -import type { Metric, Series } from '../../../../common/types'; +import type { Metric } from '../../../../common/types'; import { getFormulaEquivalent, getSiblingPipelineSeriesFormula } from '../metrics'; -import { createColumn } from './column'; +import { createColumn, getFormat } from './column'; type OtherFormulaAggregations = | typeof TSVB_METRIC_TYPES.POSITIVE_ONLY @@ -27,9 +27,7 @@ const convertToFormulaParams = (formula: string): FormulaParams | null => ({ export const createFormulaColumn = ( mathScript: string, - series: Series, - metric: Metric, - formatParams: Omit = {} + { series, metric, dataView }: CommonColumnConverterArgs ): FormulaColumn | null => { const params = convertToFormulaParams(mathScript); if (!params) { @@ -40,7 +38,7 @@ export const createFormulaColumn = ( operationType: 'formula', references: [], ...createColumn(series, metric), - params: { ...params, ...formatParams }, + params: { ...params, ...getFormat(series, metric.field, dataView) }, }; }; @@ -82,25 +80,24 @@ const convertFormulaScriptForAggs = ( }; export const convertMathToFormulaColumn = ( - series: Series, - metrics: Metric[], + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ): FormulaColumn | null => { // find the metric idx that has math expression - const mathMetric = metrics.find((metric) => metric.type === 'math'); + const metric = metrics.find(({ type }) => type === 'math'); let script: string | null | undefined = metrics[metrics.length - 1].script; - if (!mathMetric) { + if (!metric) { return null; } - const { variables } = mathMetric; + const { variables } = metric; if (!script || !variables) { return null; } - const metricsWithoutMath = metrics.filter((metric) => metric.type !== 'math'); + const metricsWithoutMath = metrics.filter(({ type }) => type !== 'math'); // create the script for (const notMathMetric of metricsWithoutMath) { @@ -137,20 +134,19 @@ export const convertMathToFormulaColumn = ( return null; } - return createFormulaColumn(script, series, mathMetric); + return createFormulaColumn(script, { series, metric, dataView }); }; export const convertOtherAggsToFormulaColumn = ( aggregation: OtherFormulaAggregations, - series: Series, - metrics: Metric[], + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ): FormulaColumn | null => { - const currentMetric = metrics[metrics.length - 1]; + const metric = metrics[metrics.length - 1]; - const formula = getSiblingPipelineSeriesFormula(aggregation, currentMetric, metrics, window); + const formula = getSiblingPipelineSeriesFormula(aggregation, metric, metrics, window); if (!formula) { return null; } - return createFormulaColumn(formula, series, currentMetric); + return createFormulaColumn(formula, { series, metric, dataView }); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index e51849c11b2c0..f46000727fd3f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -12,7 +12,7 @@ export { convertToPercentileRankColumns, isPercentileRanksColumnWithMeta } from export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './formula'; export { convertParentPipelineAggToColumns, - convertMetricAggregationColumnWithoutParams, + convertMetricAggregationColumnWithoutSpecialParams, } from './parent_pipeline'; export { convertToCumulativeSumColumns } from './cumulative_sum'; export { convertFilterRatioToFormulaColumn } from './filter_ratio'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index 923f800c8b765..99bad5e607fab 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -6,11 +6,10 @@ * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-views-plugin/common'; import { LastValueParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { LastValueColumn } from './types'; -import type { Metric, Series } from '../../../../common/types'; -import { createColumn } from './column'; +import { CommonColumnsConverterArgs, LastValueColumn } from './types'; +import type { Metric } from '../../../../common/types'; +import { createColumn, getFormat } from './column'; const convertToLastValueParams = (metric: Metric): LastValueParams | null => ({ sortField: metric.order_by, @@ -18,9 +17,7 @@ const convertToLastValueParams = (metric: Metric): LastValueParams | null => ({ }); export const convertToLastValueColumn = ( - series: Series, - metrics: Metric[], - dataView: DataView, + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ): LastValueColumn | null => { const currentMetric = metrics[metrics.length - 1]; @@ -46,6 +43,6 @@ export const convertToLastValueColumn = ( operationType: 'last_value', sourceField: field.name ?? 'document', ...createColumn(series, currentMetric, undefined, { window }), - params, + params: { ...params, ...getFormat(series, currentMetric.field, dataView) }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index c00d45cc4fbce..db31fa5d310bc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -12,6 +12,8 @@ import { Operations } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { AvgColumn, CardinalityColumn, + CommonColumnConverterArgs, + CommonColumnsConverterArgs, CountColumn, CounterRateColumn, CumulativeSumColumn, @@ -33,7 +35,7 @@ import { SupportedMetric, SUPPORTED_METRICS, } from '../metrics'; -import { createColumn } from './column'; +import { createColumn, getFormat } from './column'; import { createFormulaColumn } from './formula'; import { convertToMovingAverageParams } from './moving_average'; import { convertToPercentileColumn } from './percentile'; @@ -55,9 +57,12 @@ type MetricAggregation = | typeof Operations.PERCENTILE | typeof Operations.PERCENTILE_RANK; -type MetricAggregationColumnWithParams = PercentileColumn | PercentileRanksColumn | LastValueColumn; +type MetricAggregationColumnWithSpecialParams = + | PercentileColumn + | PercentileRanksColumn + | LastValueColumn; -type MetricAggregationColumnWithoutParams = +type MetricAggregationColumnWithoutSpecialParams = | AvgColumn | CountColumn | CardinalityColumn @@ -67,8 +72,8 @@ type MetricAggregationColumnWithoutParams = | SumColumn; type MetricAggregationColumn = - | MetricAggregationColumnWithoutParams - | MetricAggregationColumnWithParams; + | MetricAggregationColumnWithoutSpecialParams + | MetricAggregationColumnWithSpecialParams; type ParentPipelineAggregation = | typeof Operations.MOVING_AVERAGE @@ -105,16 +110,15 @@ const isSupportedAggregationWithoutParams = ( return (SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS as string[]).includes(agg); }; -export const convertMetricAggregationColumnWithoutParams = ( +export const convertMetricAggregationColumnWithoutSpecialParams = ( aggregation: SupportedMetric, - series: Series, - metric: Metric, - dataView: DataView, + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string -): MetricAggregationColumnWithoutParams | null => { +): MetricAggregationColumnWithoutSpecialParams | null => { if (!isSupportedAggregationWithoutParams(aggregation.name)) { return null; } + const metric = metrics[metrics.length - 1]; const sourceField = aggregation.isFieldRequired && metric.field ? metric.field : 'document'; const field = dataView.getFieldByName(sourceField); @@ -126,8 +130,8 @@ export const convertMetricAggregationColumnWithoutParams = ( operationType: aggregation.name, sourceField, ...createColumn(series, metric, field, { window }), - params: {}, - } as MetricAggregationColumnWithoutParams; + params: { ...getFormat(series, field?.name, dataView) }, + } as MetricAggregationColumnWithoutSpecialParams; }; export const convertMetricAggregationToColumn = ( @@ -147,7 +151,7 @@ export const convertMetricAggregationToColumn = ( } if (aggregation.name === Operations.PERCENTILE) { - return convertToPercentileColumn(metaValue, series, metric, dataView, { window }); + return convertToPercentileColumn(metaValue, { series, metric, dataView }, { window }); } if (aggregation.name === Operations.PERCENTILE_RANK) { @@ -160,19 +164,21 @@ export const convertMetricAggregationToColumn = ( return null; } - return convertMetricAggregationColumnWithoutParams(aggregation, series, metric, dataView, window); + return convertMetricAggregationColumnWithoutSpecialParams( + aggregation, + { series, metrics: [metric], dataView }, + window + ); }; export const computeParentPipelineColumns = ( aggregation: ParentPipelineAggregation, - series: Series, - currentMetric: Metric, - dataView: DataView, + { series, metric, dataView }: CommonColumnConverterArgs, subFunctionMetric: Metric, pipelineAgg: SupportedMetric, { metaValue, window }: { metaValue?: number; window?: string } = {} ) => { - const agg = SUPPORTED_METRICS[currentMetric.type]; + const agg = SUPPORTED_METRICS[metric.type]; if (!agg) { return null; } @@ -185,7 +191,7 @@ export const computeParentPipelineColumns = ( return null; } const formula = `${aggFormula}(${script})`; - return createFormulaColumn(formula, series, currentMetric); + return createFormulaColumn(formula, { series, metric, dataView }); } const metricAggregationColumn = convertMetricAggregationToColumn( @@ -202,7 +208,7 @@ export const computeParentPipelineColumns = ( return [ metricAggregationColumn, - createParentPipelineAggregationColumn(aggregation, series, currentMetric, [ + createParentPipelineAggregationColumn(aggregation, { series, metric, dataView }, [ metricAggregationColumn.columnId, ]), ]; @@ -210,15 +216,13 @@ export const computeParentPipelineColumns = ( const convertMovingAvgOrDerivativeToColumns = ( aggregation: typeof METRIC_TYPES.DERIVATIVE | typeof TSVB_METRIC_TYPES.MOVING_AVERAGE, - currentMetric: Metric, - series: Series, - metrics: Metric[], - dataView: DataView, + metric: Metric, + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ) => { // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] - const [fieldId, meta] = currentMetric?.field?.split('[') ?? []; - const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); + const [fieldId, meta] = metric?.field?.split('[') ?? []; + const subFunctionMetric = metrics.find(({ id }) => id === fieldId); if (!subFunctionMetric || subFunctionMetric.type === 'static') { return null; } @@ -231,20 +235,20 @@ const convertMovingAvgOrDerivativeToColumns = ( const subMetricField = subFunctionMetric.field; const [nestedFieldId, _] = subMetricField?.split('[') ?? []; // support nested aggs with formula - const additionalSubFunction = metrics.find((metric) => metric.id === nestedFieldId); + const additionalSubFunction = metrics.find(({ id }) => id === nestedFieldId); if (additionalSubFunction) { const formula = getParentPipelineSeriesFormula( metrics, subFunctionMetric, pipelineAgg, - currentMetric.type, + metric.type, { metaValue, window } ); if (!formula) { return null; } - return createFormulaColumn(formula, series, currentMetric); + return createFormulaColumn(formula, { series, metric, dataView }); } else { const agg = SUPPORTED_METRICS[aggregation]; if (!agg) { @@ -253,9 +257,7 @@ const convertMovingAvgOrDerivativeToColumns = ( return computeParentPipelineColumns( agg.name, - series, - currentMetric, - dataView, + { series, metric, dataView }, subFunctionMetric, pipelineAgg, { metaValue, window } @@ -264,9 +266,7 @@ const convertMovingAvgOrDerivativeToColumns = ( }; export const convertParentPipelineAggToColumns = ( - series: Series, - metrics: Metric[], - dataView: DataView, + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ) => { const currentMetric = metrics[metrics.length - 1]; @@ -275,9 +275,7 @@ export const convertParentPipelineAggToColumns = ( return convertMovingAvgOrDerivativeToColumns( currentMetric.type, currentMetric, - series, - metrics, - dataView, + { series, metrics, dataView }, window ); } @@ -286,12 +284,14 @@ export const convertParentPipelineAggToColumns = ( export const createParentPipelineAggregationColumn = ( aggregation: ParentPipelineAggregation, - series: Series, - metric: Metric, + { series, metric, dataView }: CommonColumnConverterArgs, references: string[] = [] ) => { const params = - aggregation === 'moving_average' ? convertToMovingAverageParams(metric) : undefined; + aggregation === 'moving_average' + ? convertToMovingAverageParams(metric) + : getFormat(series, metric.field, dataView); + if (params === null) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index d0172e41bb963..1157afb7e794f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -6,11 +6,15 @@ * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-views-plugin/common'; import { Operations, PercentileParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import type { Metric, Percentile, Series } from '../../../../common/types'; -import { createColumn } from './column'; -import { PercentileColumnWithExtendedMeta, PercentileColumn, Column } from './types'; +import type { Percentile } from '../../../../common/types'; +import { createColumn, getFormat } from './column'; +import { + PercentileColumnWithExtendedMeta, + PercentileColumn, + Column, + CommonColumnConverterArgs, +} from './types'; export const isPercentileColumnWithMeta = ( column: Column @@ -27,9 +31,7 @@ export const convertToPercentileParams = (value?: string | number): PercentilePa export const convertToPercentileColumn = ( percentile: Percentile['value'], - series: Series, - metric: Metric, - dataView: DataView, + { series, metric, dataView }: CommonColumnConverterArgs, { index, window }: { index?: number; window?: string } = {} ): PercentileColumn | null => { const params = convertToPercentileParams(percentile); @@ -46,7 +48,7 @@ export const convertToPercentileColumn = ( operationType: 'percentile', sourceField: field.name, ...commonColumnParams, - params, + params: { ...params, ...getFormat(series, metric.field, dataView) }, meta: index !== undefined ? { @@ -58,18 +60,16 @@ export const convertToPercentileColumn = ( }; export const convertToPercentileColumns = ( - series: Series, - metric: Metric, - dataView: DataView, + columnConverterArgs: CommonColumnConverterArgs, window?: string ): Array | null => { - const { percentiles } = metric; + const { percentiles } = columnConverterArgs.metric; if (!percentiles) { return null; } return percentiles.map((p, index) => - convertToPercentileColumn(p.value, series, metric, dataView, { index, window }) + convertToPercentileColumn(p.value, columnConverterArgs, { index, window }) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index c7f4116b65b14..9cb8c097b0a0a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -12,8 +12,13 @@ import { PercentileRanksParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Series } from '../../../../common/types'; -import { createColumn } from './column'; -import { PercentileRanksColumn, Column, PercentileRanksColumnWithExtendedMeta } from './types'; +import { createColumn, getFormat } from './column'; +import { + PercentileRanksColumn, + Column, + PercentileRanksColumnWithExtendedMeta, + CommonColumnConverterArgs, +} from './types'; export const isPercentileRanksColumnWithMeta = ( column: Column @@ -50,7 +55,7 @@ export const convertToPercentileRankColumn = ( operationType: 'percentile_rank', sourceField: field.name, ...commonColumnParams, - params, + params: { ...params, ...getFormat(series, metric.field, dataView) }, meta: index !== undefined ? { @@ -62,9 +67,7 @@ export const convertToPercentileRankColumn = ( }; export const convertToPercentileRankColumns = ( - series: Series, - metric: Metric, - dataView: DataView, + { series, metric, dataView }: CommonColumnConverterArgs, window?: string ): Array | null => { const { values } = metric; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index 59b0f8844ec5b..912736e14e780 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -7,17 +7,16 @@ */ import { StaticValueParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { StaticValueColumn } from './types'; -import type { Metric, Series } from '../../../../common/types'; -import { createColumn } from './column'; +import { CommonColumnsConverterArgs, StaticValueColumn } from './types'; +import type { Metric } from '../../../../common/types'; +import { createColumn, getFormat } from './column'; export const convertToStaticValueParams = ({ value }: Metric): StaticValueParams => ({ value, }); export const convertToStaticValueColumn = ( - series: Series, - metrics: Metric[], + { series, metrics, dataView }: CommonColumnsConverterArgs, { visibleSeriesCount = 0, window }: { visibleSeriesCount?: number; window?: string } = {} ): StaticValueColumn | null => { // Lens support reference lines only when at least one layer data exists @@ -29,6 +28,9 @@ export const convertToStaticValueColumn = ( operationType: 'static_value', references: [], ...createColumn(series, currentMetric, undefined, { window }), - params: convertToStaticValueParams(currentMetric), + params: { + ...convertToStaticValueParams(currentMetric), + ...getFormat(series, currentMetric.field, dataView), + }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts index 8a989904b718f..2ebe75d3e81f5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts @@ -6,54 +6,53 @@ * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-views-plugin/common'; -import type { Metric, Series } from '../../../../common/types'; +import type { Metric } from '../../../../common/types'; import { getFormulaEquivalent, SUPPORTED_METRICS } from '../metrics'; import { createFormulaColumn } from './formula'; -import { convertMetricAggregationColumnWithoutParams } from './parent_pipeline'; +import { convertMetricAggregationColumnWithoutSpecialParams } from './parent_pipeline'; +import { CommonColumnConverterArgs, CommonColumnsConverterArgs } from './types'; const createStandartDeviationFormulaColumn = ( - series: Series, - currentMetric: Metric, + { series, metric, dataView }: CommonColumnConverterArgs, metrics: Metric[], window?: string ) => { - const script = getFormulaEquivalent(currentMetric, metrics, { window }); + const script = getFormulaEquivalent(metric, metrics, { window }); if (!script) return null; - return createFormulaColumn(script, series, currentMetric); + return createFormulaColumn(script, { series, metric, dataView }); }; export const convertToStandartDeviationColumn = ( - series: Series, - metrics: Metric[], - dataView: DataView, + { series, metrics, dataView }: CommonColumnsConverterArgs, window?: string ) => { - const currentMetric = metrics[metrics.length - 1]; + const metric = metrics[metrics.length - 1]; - const field = currentMetric.field ? dataView.getFieldByName(currentMetric.field) : undefined; + const field = metric.field ? dataView.getFieldByName(metric.field) : undefined; if (!field) { return null; } const columns = []; - if (currentMetric.mode === 'upper' || currentMetric.mode === 'lower') { - columns.push(createStandartDeviationFormulaColumn(series, currentMetric, metrics, window)); - } else if (currentMetric.mode === 'band') { + if (metric.mode === 'upper' || metric.mode === 'lower') { + columns.push( + createStandartDeviationFormulaColumn({ series, metric, dataView }, metrics, window) + ); + } else if (metric.mode === 'band') { [ - { ...currentMetric, mode: 'upper' }, - { ...currentMetric, mode: 'lower' }, - ].forEach((metric) => { - columns.push(createStandartDeviationFormulaColumn(series, metric, metrics, window)); + { ...metric, mode: 'upper' }, + { ...metric, mode: 'lower' }, + ].forEach((m) => { + columns.push( + createStandartDeviationFormulaColumn({ series, metric: m, dataView }, metrics, window) + ); }); } else { columns.push( - convertMetricAggregationColumnWithoutParams( + convertMetricAggregationColumnWithoutSpecialParams( SUPPORTED_METRICS.std_deviation, - series, - currentMetric, - dataView, + { series, metrics: [metric], dataView }, window ) ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts index 91a115c167ba4..8b601742a5bd0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts @@ -10,7 +10,7 @@ import type { DataView } from '@kbn/data-views-plugin/common'; import { DataType, TermsParams } from '@kbn/visualizations-plugin/common'; import uuid from 'uuid'; import { Series } from '../../../../common/types'; -import { excludeMetaFromColumn, isColumnWithMeta } from './column'; +import { excludeMetaFromColumn, getFormat, isColumnWithMeta } from './column'; import { Column, TermsColumn } from './types'; interface OrderByWithAgg { @@ -109,6 +109,6 @@ export const converToTermsColumn = ( sourceField: field.name, isBucketed: true, isSplit, - params, + params: { ...params, ...getFormat(series, field.name, dataView) }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts index 350c87f7cdffd..07d174e9b985f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import type { DataView } from '@kbn/data-views-plugin/common'; import { Layer as BaseLayer, Column as BaseColumn, @@ -33,6 +34,7 @@ import { StaticValueColumn as BaseStaticValueColumn, AnyColumnWithReferences as BaseAnyColumnWithReferences, } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import type { Metric, Series } from '../../../../common/types'; export interface Meta { metricId: string; @@ -97,4 +99,16 @@ export type Layer = Omit & { columns: Column[]; }; +export interface CommonColumnsConverterArgs { + series: Series; + metrics: Metric[]; + dataView: DataView; +} + +export interface CommonColumnConverterArgs { + series: Series; + metric: Metric; + dataView: DataView; +} + export { FiltersColumn, TermsColumn, DateHistogramColumn }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index bf622adb29e31..725f239abcf8f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -22,7 +22,7 @@ import { convertFilterRatioToFormulaColumn, convertToLastValueColumn, convertToStaticValueColumn, - convertMetricAggregationColumnWithoutParams, + convertMetricAggregationColumnWithoutSpecialParams, convertToCounterRateFormulaColumn, convertToStandartDeviationColumn, } from '../convert'; @@ -46,12 +46,11 @@ export const getMetricsColumns = ( return null; } + const columnsConverterArgs = { series, metrics, dataView }; switch (aggregation) { case 'percentile': { const percentileColumns = convertMetricsToColumns( - series, - metrics, - dataView, + columnsConverterArgs, convertToPercentileColumns, window ); @@ -59,38 +58,34 @@ export const getMetricsColumns = ( } case 'percentile_rank': { const percentileRankColumns = convertMetricsToColumns( - series, - metrics, - dataView, + columnsConverterArgs, convertToPercentileRankColumns, window ); return getValidColumns(percentileRankColumns); } case 'math': { - const formulaColumn = convertMathToFormulaColumn(series, metrics, window); + const formulaColumn = convertMathToFormulaColumn(columnsConverterArgs, window); return getValidColumns(formulaColumn); } case 'derivative': case 'moving_average': { const movingAverageOrDerivativeColumns = convertParentPipelineAggToColumns( - series, - metrics, - dataView, + columnsConverterArgs, window ); return getValidColumns(movingAverageOrDerivativeColumns); } case 'cumulative_sum': { - const cumulativeSumColumns = convertToCumulativeSumColumns(series, metrics, dataView, window); + const cumulativeSumColumns = convertToCumulativeSumColumns(columnsConverterArgs, window); return getValidColumns(cumulativeSumColumns); } case 'filter_ratio': { - const formulaColumn = convertFilterRatioToFormulaColumn(series, metrics, window); + const formulaColumn = convertFilterRatioToFormulaColumn(columnsConverterArgs, window); return getValidColumns(formulaColumn); } case 'positive_rate': { - const formulaColumn = convertToCounterRateFormulaColumn(series, metrics, dataView); + const formulaColumn = convertToCounterRateFormulaColumn(columnsConverterArgs); return getValidColumns(formulaColumn); } case 'positive_only': @@ -98,27 +93,32 @@ export const getMetricsColumns = ( case 'max_bucket': case 'min_bucket': case 'sum_bucket': { - const formulaColumn = convertOtherAggsToFormulaColumn(aggregation, series, metrics, window); + const formulaColumn = convertOtherAggsToFormulaColumn( + aggregation, + columnsConverterArgs, + window + ); return getValidColumns(formulaColumn); } case 'top_hit': { - const column = convertToLastValueColumn(series, metrics, dataView, window); + const column = convertToLastValueColumn(columnsConverterArgs, window); return getValidColumns(column); } case 'static': { - const column = convertToStaticValueColumn(series, metrics, { visibleSeriesCount, window }); + const column = convertToStaticValueColumn(columnsConverterArgs, { + visibleSeriesCount, + window, + }); return getValidColumns(column); } case 'std_deviation': { - const column = convertToStandartDeviationColumn(series, metrics, dataView, window); + const column = convertToStandartDeviationColumn(columnsConverterArgs, window); return getValidColumns(column); } default: { - const column = convertMetricAggregationColumnWithoutParams( + const column = convertMetricAggregationColumnWithoutSpecialParams( aggregationMap, - series, - metrics[metricIdx], - dataView, + columnsConverterArgs, window ); return getValidColumns(column); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index 5dababb63a7f6..0f0dcbf041a38 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -6,11 +6,10 @@ * Side Public License, v 1. */ -import type { DataView } from '@kbn/data-views-plugin/common'; import { NavigateToLensContext, XYConfiguration } from '@kbn/visualizations-plugin/common'; import { TimeRange } from '@kbn/data-plugin/common'; -import type { Metric, Panel, Series } from '../../common/types'; -import { Column } from './lib/convert'; +import type { Panel } from '../../common/types'; +import { Column, CommonColumnConverterArgs } from './lib/convert'; export type ConvertTsvbToLensVisualization = ( model: Panel, @@ -23,8 +22,6 @@ export interface Filter { } export type ConvertToColumnsFn = ( - series: Series, - metric: Metric, - dataView: DataView, + { series: Series, metric: Metric, dataView: DataView }: CommonColumnConverterArgs, window?: string ) => Array | null; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/params.ts b/src/plugins/visualizations/common/convert_to_lens/types/params.ts index 272ec8200ccfd..05375a99619d6 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/params.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/params.ts @@ -9,15 +9,18 @@ import { Column } from './columns'; import { Filter, NumberValueFormat } from './common'; +export interface FormatParams { + format?: NumberValueFormat; +} + export interface FiltersParams { filters: Filter[]; } -export interface RangeParams { +export interface RangeParams extends FormatParams { type: 'histogram' | 'range'; maxBars: 'auto' | number; ranges: Range[]; - format?: NumberValueFormat; includeEmptyRows?: boolean; parentFormat?: { id: string; @@ -29,7 +32,7 @@ export interface RangeParams { }; } -export interface TermsParams { +export interface TermsParams extends FormatParams { size: number; include?: string[] | number[]; exclude?: string[] | number[]; @@ -45,7 +48,6 @@ export interface TermsParams { otherBucket?: boolean; missingBucket?: boolean; secondaryFields?: string[]; - format?: NumberValueFormat; parentFormat?: { id: string }; } @@ -56,78 +58,42 @@ export interface DateHistogramParams { dropPartials?: boolean; } -export interface MinParams { - format?: NumberValueFormat; -} +export type MinParams = FormatParams; +export type MaxParams = FormatParams; +export type AvgParams = FormatParams; +export type SumParams = FormatParams; +export type MedianParams = FormatParams; +export type StandardDeviationParams = FormatParams; +export type CardinalityParams = FormatParams; +export type CumulativeSumParams = FormatParams; +export type CounterRateParams = FormatParams; +export type DerivativeParams = FormatParams; +export type CountParams = FormatParams; -export interface MaxParams { - format?: NumberValueFormat; -} - -export interface AvgParams { - format?: NumberValueFormat; -} - -export interface SumParams { - format?: NumberValueFormat; -} - -export interface MedianParams { - format?: NumberValueFormat; -} - -export interface StandardDeviationParams { - format?: NumberValueFormat; -} - -export interface CardinalityParams { - format?: NumberValueFormat; -} - -export interface PercentileParams { +export interface PercentileParams extends FormatParams { percentile: number; - format?: NumberValueFormat; } export interface PercentileRanksParams { value: number; } -export interface CountParams { - format?: NumberValueFormat; -} - -export interface LastValueParams { +export interface LastValueParams extends FormatParams { sortField?: string; showArrayValues: boolean; - format?: NumberValueFormat; -} - -export interface CumulativeSumParams { - format?: NumberValueFormat; -} - -export interface CounterRateParams { - format?: NumberValueFormat; -} - -export interface DerivativeParams { - format?: NumberValueFormat; } export interface MovingAverageParams { window: number; } -export interface FormulaParams { +export interface FormulaParams extends FormatParams { formula?: string; isFormulaBroken?: boolean; - format?: NumberValueFormat; } -export interface StaticValueParams { +export interface StaticValueParams extends FormatParams { value?: string; - format?: NumberValueFormat; } export interface TimeScaleParams { From 1380bb8ef7e3271280f70b20231120d043cef490 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 16:14:36 +0300 Subject: [PATCH 063/129] Removed not used comment. --- .../timeseries/public/convert_to_lens/lib/convert/column.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 7db35011e47fc..ad110e024c1bd 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -47,7 +47,7 @@ export const getFormat = ( const id = formatter.type.id; return { format: { id } }; } - return { format: { id: series.formatter } }; // TODO: fix this formatter later, after investigation... + return { format: { id: series.formatter } }; }; export const createColumn = ( From 51ef4913a2db81b3eb509989b0477aacd28d39d4 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 16:22:34 +0300 Subject: [PATCH 064/129] Added formatter validation. --- .../public/convert_to_lens/lib/convert/column.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index ad110e024c1bd..6de87f52ac6c9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -28,6 +28,8 @@ interface ExtraColumnFields { window?: string; } +const isSupportedFormat = (format: string) => ['bytes', 'number', 'percent'].includes(format); + export const getFormat = ( series: Series, fieldName: string | undefined, @@ -45,8 +47,17 @@ export const getFormat = ( const formatter = dataView.getFormatterForField(field); const id = formatter.type.id; + + if (!isSupportedFormat(id)) { + return {}; + } return { format: { id } }; } + + if (!isSupportedFormat(series.formatter)) { + return {}; + } + return { format: { id: series.formatter } }; }; From 01055360a8910c3393e8cfecbdc2cb13ea576def Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 17:46:20 +0300 Subject: [PATCH 065/129] Added tests for getFormat. --- src/plugins/field_formats/common/mocks.ts | 1 + .../convert_to_lens/lib/__mocks__/index.ts | 35 ++++++++ .../lib/convert/column.test.ts | 86 +++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts diff --git a/src/plugins/field_formats/common/mocks.ts b/src/plugins/field_formats/common/mocks.ts index 9d2038e18611a..c03b51bb12337 100644 --- a/src/plugins/field_formats/common/mocks.ts +++ b/src/plugins/field_formats/common/mocks.ts @@ -13,6 +13,7 @@ export const fieldFormatsMock: IFieldFormatsRegistry = { getByFieldType: jest.fn(), getDefaultConfig: jest.fn(), getDefaultInstance: jest.fn().mockImplementation(() => ({ + type: { id: 'bytes' }, convert: jest.fn().mockImplementation((t: string) => t), getConverterFor: jest.fn().mockImplementation(() => (t: string) => t), })), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts new file mode 100644 index 0000000000000..885b8124575d8 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts @@ -0,0 +1,35 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Series } from '../../../../common/types'; + +export const createSeries = (partialSeries?: Partial): Series => ({ + axis_position: 'right', + chart_type: 'line', + color: '#68BC00', + fill: '0.5', + formatter: 'default', + id: '3bb3c1d2-5af8-44cc-9759-86725e34b157', + label: '', + line_width: 1, + metrics: [], + override_index_pattern: 0, + palette: { name: 'default', type: 'palette' }, + point_size: 1, + separate_axis: 0, + series_drop_last_bucket: 0, + split_mode: 'everything', + stacked: 'none', + time_range_mode: 'entire_time_range', + value_template: '{{value}}', + seperate_axis: 0, + series_index_pattern: { id: 'test' }, + series_max_bars: 0, + steps: 0, + ...partialSeries, +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts new file mode 100644 index 0000000000000..1cc38cda7f7d4 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -0,0 +1,86 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { + createStubDataView, + stubLogstashDataView, +} from '@kbn/data-views-plugin/common/data_view.stub'; +import { stubLogstashFieldSpecMap } from '@kbn/data-views-plugin/common/field.stub'; +import { createSeries } from '../__mocks__'; +import { getFormat } from './column'; + +describe('getFormat', () => { + const series = createSeries(); + const dataViewWithoutSupportedFormatsFields = createStubDataView({ + spec: { + id: 'logstash-*', + title: 'logstash-*', + timeFieldName: 'time', + fields: stubLogstashFieldSpecMap, + }, + }); + + beforeEach(() => { + dataViewWithoutSupportedFormatsFields.getFormatterForField = jest + .fn() + .mockImplementation(() => ({ + type: { + id: 'date', + }, + })); + }); + + afterEach(() => { + jest.clearAllMocks(); + jest.resetAllMocks(); + }); + + test('should return formatter of the field, if formatter is set to default', () => { + expect(getFormat(series, stubLogstashDataView.fields[0].name, stubLogstashDataView)).toEqual({ + format: { id: 'bytes' }, + }); + }); + + test("should return no formatter, if a field with a specified name doesn't exist", () => { + expect(getFormat(series, 'some-other-name', stubLogstashDataView)).toEqual({}); + }); + + test('should return no formatter, if the type of the field is not supported', () => { + expect( + getFormat( + series, + dataViewWithoutSupportedFormatsFields.fields[2].name, + dataViewWithoutSupportedFormatsFields + ) + ).toEqual({}); + }); + + test('should return formatter value, if formatter is not set to default', () => { + const formatter = 'percent'; + expect( + getFormat( + createSeries({ formatter }), + stubLogstashDataView.fields[0].name, + stubLogstashDataView + ) + ).toEqual({ + format: { id: formatter }, + }); + }); + + test('should not return formatter value, if formatter is set to not suppported format', () => { + const formatter = 'date'; + expect( + getFormat( + createSeries({ formatter }), + stubLogstashDataView.fields[0].name, + stubLogstashDataView + ) + ).toEqual({}); + }); +}); From 26bf0a49e5368d7531ef368f3a47a4d79b505184 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Fri, 26 Aug 2022 18:00:21 +0300 Subject: [PATCH 066/129] Fix `getFormat` method --- .../public/convert_to_lens/lib/convert/column.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 6de87f52ac6c9..d12df89e7122f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -30,17 +30,27 @@ interface ExtraColumnFields { const isSupportedFormat = (format: string) => ['bytes', 'number', 'percent'].includes(format); +const findField = (series: Series, field?: string): string | undefined => { + const subMetric = series.metrics.find((m) => m.id === field); + if (subMetric) { + return findField(series, subMetric.field); + } + return field; +}; + export const getFormat = ( series: Series, fieldName: string | undefined, dataView: DataView ): FormatParams => { if (series.formatter === 'default') { - if (!fieldName) { + const correctFieldName = findField(series, fieldName); + + if (!correctFieldName) { return {}; } - const field = dataView.getFieldByName(fieldName); + const field = dataView.getFieldByName(correctFieldName); if (!field) { return {}; } From 8576a9b88be1ad8e44e1eb71b85f0e5dd672469e Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 18:29:45 +0300 Subject: [PATCH 067/129] createColumn test added. --- .../lib/convert/column.test.ts | 87 ++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts index 1cc38cda7f7d4..34a2fc8dc9094 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -6,13 +6,15 @@ * Side Public License, v 1. */ +import { METRIC_TYPES } from '@kbn/data-plugin/public'; import { createStubDataView, stubLogstashDataView, } from '@kbn/data-views-plugin/common/data_view.stub'; import { stubLogstashFieldSpecMap } from '@kbn/data-views-plugin/common/field.stub'; +import { Metric } from '../../../../common/types'; import { createSeries } from '../__mocks__'; -import { getFormat } from './column'; +import { createColumn, getFormat } from './column'; describe('getFormat', () => { const series = createSeries(); @@ -84,3 +86,86 @@ describe('getFormat', () => { ).toEqual({}); }); }); + +describe('createColumn', () => { + const field = stubLogstashDataView.fields[0]; + const scaleUnit = 's'; + const metric: Metric = { + id: 'some-id', + type: METRIC_TYPES.AVG, + field: field.name, + }; + + const metricWithTimeScale: Metric = { + id: 'some-other-id', + type: METRIC_TYPES.TOP_HITS, + field: field.name, + unit: `1${scaleUnit}`, + }; + + const customLabel = 'some custom'; + const window = 'some-window'; + const filter = { query: 'some-query', language: 'lucene' }; + + test.each([ + [ + 'with default params', + { seriesArgs: { metrics: [metric], label: '' }, field, metric, extraFields: undefined }, + { + isBucketed: false, + isSplit: false, + label: '', + meta: { metricId: metric.id }, + dataType: field?.type, + }, + ], + [ + 'with specified params', + { + seriesArgs: { + metrics: [metricWithTimeScale], + label: customLabel, + filter, + }, + field, + metric: metricWithTimeScale, + extraFields: { window, isBucketed: true, isSplit: true }, + }, + { + isBucketed: true, + isSplit: true, + window, + label: customLabel, + meta: { metricId: metricWithTimeScale.id }, + filter, + timeScale: scaleUnit, + dataType: field?.type, + }, + ], + [ + 'without field', + { + seriesArgs: { metrics: [metric], label: '' }, + field: undefined, + metric, + extraFields: undefined, + }, + { + isBucketed: false, + isSplit: false, + label: '', + meta: { metricId: metric.id }, + dataType: undefined, + }, + ], + ])( + 'should create column by metric %s', + (_, { seriesArgs, field: specifiedField, metric: specifiedMetric, extraFields }, expected) => { + const series = createSeries(seriesArgs); + const column = createColumn(series, specifiedMetric, specifiedField, extraFields); + + expect(column).toEqual(expect.objectContaining(expected)); + expect(typeof column.columnId === 'string' && column.columnId.length > 0).toBeTruthy(); + } + ); +}); From dcbf498dd71a9d5f9d532ce02a967844da07e092 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 26 Aug 2022 18:49:31 +0300 Subject: [PATCH 068/129] Added tests for `excludeMetaFromColumn` and `isColumnWithMeta`. --- .../lib/convert/column.test.ts | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts index 34a2fc8dc9094..cd99e1a5e5189 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -12,9 +12,11 @@ import { stubLogstashDataView, } from '@kbn/data-views-plugin/common/data_view.stub'; import { stubLogstashFieldSpecMap } from '@kbn/data-views-plugin/common/field.stub'; +import { MaxColumn as BaseMaxColumn } from '@kbn/visualizations-plugin/common'; import { Metric } from '../../../../common/types'; import { createSeries } from '../__mocks__'; -import { createColumn, getFormat } from './column'; +import { createColumn, excludeMetaFromColumn, getFormat, isColumnWithMeta } from './column'; +import { MaxColumn } from './types'; describe('getFormat', () => { const series = createSeries(); @@ -169,3 +171,36 @@ describe('createColumn', () => { } ); }); + +const column1: BaseMaxColumn = { + sourceField: 'some-field', + columnId: 'some-id', + operationType: 'max', + isBucketed: false, + isSplit: false, + dataType: 'string', + params: {}, +}; + +const column2: MaxColumn = { + ...column1, + meta: { metricId: 'metric-id' }, +}; + +describe('isColumnWithMeta', () => { + test.each([ + ['without meta', column1 as MaxColumn, false], + ['with meta', column2, true], + ])('should check if column is %s', (_, input, expected) => { + expect(isColumnWithMeta(input)).toBe(expected); + }); +}); + +describe('excludeMetaFromColumn', () => { + test.each([ + ['without meta', column1 as MaxColumn, column1], + ['with meta', column2, column1], + ])('should exclude meta if column is %s', (_, input, expected) => { + expect(excludeMetaFromColumn(input)).toEqual(expected); + }); +}); From ab7ed74993256fcba8b57388f2a9b7d670409be0 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 10:36:34 +0300 Subject: [PATCH 069/129] Added tests for counter_rate. --- .../lib/convert/counter_rate.test.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts new file mode 100644 index 0000000000000..f456e04fbe349 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts @@ -0,0 +1,49 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import type { Metric } from '../../../../common/types'; +import { createSeries } from '../__mocks__'; +import { convertToCounterRateFormulaColumn } from './counter_rate'; + +describe('convertToCounterRateFormulaColumn', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.POSITIVE_RATE, + }; + + test.each([ + ['null if metric contains empty field param', { series, metrics: [metric], dataView }, null], + [ + 'formula column if metric contains field param', + { series, metrics: [{ ...metric, field: dataView.fields[0].name }], dataView }, + { + operationType: 'formula', + params: { formula: 'pick_max(differences(max(bytes)), 0)', format: { id: 'bytes' } }, + meta: { metricId: 'some-id' }, + }, + ], + [ + 'differences formula with shift if metric contains unit', + { series, metrics: [{ ...metric, field: dataView.fields[0].name, unit: '1h' }], dataView }, + { + operationType: 'formula', + params: { + formula: 'pick_max(differences(max(bytes), shift=1h), 0)', + format: { id: 'bytes' }, + }, + meta: { metricId: 'some-id' }, + }, + ], + ])('should return %s', (_, input, expected) => { + expect(convertToCounterRateFormulaColumn(input)).toEqual(expect.objectContaining(expected)); + }); +}); From 3233c5129905955e9a17e81d2f3d53d7f012d26c Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 12:10:35 +0300 Subject: [PATCH 070/129] Added tests for cumulative_sum. --- .../lib/convert/counter_rate.test.ts | 9 +- .../lib/convert/cumulative_sum.test.ts | 220 ++++++++++++++++++ .../lib/convert/cumulative_sum.ts | 6 - .../convert_to_lens/lib/convert/types.ts | 2 +- .../lib/metrics/metrics_helpers.ts | 2 +- .../lib/series/metrics_columns.ts | 11 +- 6 files changed, 238 insertions(+), 12 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts index f456e04fbe349..dbc06f5eec880 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts @@ -11,6 +11,7 @@ import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric } from '../../../../common/types'; import { createSeries } from '../__mocks__'; import { convertToCounterRateFormulaColumn } from './counter_rate'; +import { CommonColumnsConverterArgs, FormulaColumn } from './types'; describe('convertToCounterRateFormulaColumn', () => { const dataView = stubLogstashDataView; @@ -20,7 +21,7 @@ describe('convertToCounterRateFormulaColumn', () => { type: TSVB_METRIC_TYPES.POSITIVE_RATE, }; - test.each([ + test.each<[string, CommonColumnsConverterArgs, Partial | null]>([ ['null if metric contains empty field param', { series, metrics: [metric], dataView }, null], [ 'formula column if metric contains field param', @@ -44,6 +45,10 @@ describe('convertToCounterRateFormulaColumn', () => { }, ], ])('should return %s', (_, input, expected) => { - expect(convertToCounterRateFormulaColumn(input)).toEqual(expect.objectContaining(expected)); + if (expected === null) { + expect(convertToCounterRateFormulaColumn(input)).toBeNull(); + } else { + expect(convertToCounterRateFormulaColumn(input)).toEqual(expect.objectContaining(expected)); + } }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts new file mode 100644 index 0000000000000..ecc4811a4bd47 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts @@ -0,0 +1,220 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import type { Metric } from '../../../../common/types'; +import { createSeries } from '../__mocks__'; +import { convertToCumulativeSumColumns } from './cumulative_sum'; +import { Column, CommonColumnsConverterArgs, FormulaColumn } from './types'; + +describe('convertToCumulativeSumColumns', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const metric: Metric = { + id: 'some-id', + type: METRIC_TYPES.CUMULATIVE_SUM, + }; + const subAggMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, + }; + const notSupportedSubAggMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.MEDIAN, + }; + const staticSubAggMetric: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.STATIC, + }; + const metaValue = `50`; + const window = '1h'; + + test.each< + [ + string, + [common: CommonColumnsConverterArgs, window?: string], + Partial | Array> | null + ] + >([ + ['null if metric contains empty field param', [{ series, metrics: [metric], dataView }], null], + [ + "null if metrics array doesn't contain metric with specified id", + [ + { + series, + metrics: [subAggMetric, { ...metric, field: dataView.fields[0].name }], + dataView, + }, + ], + null, + ], + [ + 'null if submetric is pointing to the static aggregation', + [ + { + series, + metrics: [staticSubAggMetric, { ...metric, field: `${staticSubAggMetric.id}[50]` }], + dataView, + }, + ], + null, + ], + [ + 'null if submetric is pointing to the not supported aggregation', + [ + { + series, + metrics: [ + notSupportedSubAggMetric, + { ...metric, field: `${notSupportedSubAggMetric.id}[50]` }, + ], + dataView, + }, + ], + null, + ], + [ + 'formula if submetric is pointing to aggregation', + [ + { + series, + metrics: [subAggMetric, { ...metric, field: `${subAggMetric.id}[50]` }], + dataView, + }, + ], + { + operationType: 'formula', + meta: { metricId: metric.id }, + params: { formula: 'cumulative_sum(average(bytes))' }, + }, + ], + [ + 'columns with parent aggregation if submetric is count', + [ + { + series, + metrics: [ + { ...subAggMetric, type: METRIC_TYPES.COUNT }, + { ...metric, field: `${subAggMetric.id}[50]` }, + ], + dataView, + }, + ], + [ + { + operationType: 'count', + sourceField: 'document', + meta: { metricId: subAggMetric.id }, + }, + { + operationType: 'cumulative_sum', + meta: { metricId: metric.id }, + }, + ], + ], + [ + 'columns with parent aggregation if submetric is sum', + [ + { + series, + metrics: [ + { ...subAggMetric, type: METRIC_TYPES.SUM }, + { ...metric, field: `${subAggMetric.id}[50]` }, + ], + dataView, + }, + ], + [ + { + operationType: 'sum', + sourceField: subAggMetric.field, + meta: { metricId: subAggMetric.id }, + }, + { + operationType: 'cumulative_sum', + meta: { metricId: metric.id }, + }, + ], + ], + [ + 'formula with used meta if submetric is percentile', + [ + { + series, + metrics: [ + { ...subAggMetric, type: TSVB_METRIC_TYPES.PERCENTILE }, + { ...metric, field: `${subAggMetric.id}[${metaValue}]` }, + ], + dataView, + }, + ], + { + operationType: 'formula', + meta: { metricId: 'some-id' }, + params: { + formula: `cumulative_sum(percentile(${subAggMetric.field}, percentile=${metaValue}))`, + }, + }, + ], + [ + 'formula with used meta if submetric is percentile rank', + [ + { + series, + metrics: [ + { ...subAggMetric, type: TSVB_METRIC_TYPES.PERCENTILE_RANK }, + { ...metric, field: `${subAggMetric.id}[${metaValue}]` }, + ], + dataView, + }, + ], + { + operationType: 'formula', + meta: { metricId: metric.id }, + params: { + formula: `cumulative_sum(percentile_rank(${subAggMetric.field}, value=${metaValue}))`, + }, + }, + ], + [ + 'formula with time range if submetric is percentile and window is specified', + [ + { + series, + metrics: [ + { ...subAggMetric, type: TSVB_METRIC_TYPES.PERCENTILE }, + { ...metric, field: `${subAggMetric.id}[${metaValue}]` }, + ], + dataView, + }, + window, + ], + { + operationType: 'formula', + meta: { metricId: metric.id }, + params: { + formula: `cumulative_sum(percentile(${subAggMetric.field}, percentile=${metaValue}, timeRange='${window}'))`, + }, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToCumulativeSumColumns(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToCumulativeSumColumns(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertToCumulativeSumColumns(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index c797ab90f25a4..ec4bdc74420bd 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -17,9 +17,6 @@ export const convertToCumulativeSumColumns = ( window?: string ) => { const metric = metrics[metrics.length - 1]; - if (!metric) { - return null; - } // percentile and percentile_rank value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] const [fieldId, meta] = metric?.field?.split('[') ?? []; @@ -47,9 +44,6 @@ export const convertToCumulativeSumColumns = ( return createFormulaColumn(formula, { series, metric, dataView }); } else { const agg = SUPPORTED_METRICS[METRIC_TYPES.CUMULATIVE_SUM]; - if (!agg) { - return null; - } return computeParentPipelineColumns( agg.name, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts index 07d174e9b985f..2b8e831d3f5c3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts @@ -101,7 +101,7 @@ export type Layer = Omit & { export interface CommonColumnsConverterArgs { series: Series; - metrics: Metric[]; + metrics: [Metric, ...Metric[]]; dataView: DataView; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 67618b68ecfb0..5c76707706af5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -147,7 +147,7 @@ export const getFormulaEquivalent = ( return `${aggFormula}(${currentMetric.field})`; } default: { - return `${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + return `${aggFormula}(${currentMetric.field ?? ''}${addTimeRangeToFormula(window)})`; } } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 725f239abcf8f..e0688549db95a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -7,7 +7,7 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; -import type { Series } from '../../../../common/types'; +import type { Metric, Series } from '../../../../common/types'; import { getSeriesAgg } from './series_agg'; import { SUPPORTED_METRICS } from '../metrics'; import { @@ -34,7 +34,14 @@ export const getMetricsColumns = ( visibleSeriesCount: number, window?: string ): Column[] | null => { - const { metrics, seriesAgg } = getSeriesAgg(series.metrics); + const { metrics: validMetrics, seriesAgg } = getSeriesAgg( + series.metrics as [Metric, ...Metric[]] + ); + + if (!validMetrics.length) { + return null; + } + const metrics = validMetrics as [Metric, ...Metric[]]; // series agg supported as collapseFn if we have split if (seriesAgg && series.split_mode === 'everything') { return null; From 3bce624051a822211622cb1e4fe15275fc67badd Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 14:48:24 +0300 Subject: [PATCH 071/129] Updated cumulative_sum tests. --- .../lib/convert/cumulative_sum.test.ts | 44 +++++++++---------- .../lib/convert/cumulative_sum.ts | 1 - 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts index ecc4811a4bd47..fc724dcd69b1f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts @@ -14,29 +14,29 @@ import { createSeries } from '../__mocks__'; import { convertToCumulativeSumColumns } from './cumulative_sum'; import { Column, CommonColumnsConverterArgs, FormulaColumn } from './types'; -describe('convertToCumulativeSumColumns', () => { - const dataView = stubLogstashDataView; - const series = createSeries(); - const metric: Metric = { - id: 'some-id', - type: METRIC_TYPES.CUMULATIVE_SUM, - }; - const subAggMetric: Metric = { - id: 'some-random-value', - type: METRIC_TYPES.AVG, - field: dataView.fields[0].name, - }; - const notSupportedSubAggMetric: Metric = { - id: 'some-random-value', - type: METRIC_TYPES.MEDIAN, - }; - const staticSubAggMetric: Metric = { - id: 'some-random-value', - type: TSVB_METRIC_TYPES.STATIC, - }; - const metaValue = `50`; - const window = '1h'; +const dataView = stubLogstashDataView; +const series = createSeries(); +const metric: Metric = { + id: 'some-id', + type: METRIC_TYPES.CUMULATIVE_SUM, +}; +const subAggMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, +}; +const notSupportedSubAggMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.MEDIAN, +}; +const staticSubAggMetric: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.STATIC, +}; +const metaValue = `50`; +const window = '1h'; +describe('convertToCumulativeSumColumns', () => { test.each< [ string, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index ec4bdc74420bd..1429936039061 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -44,7 +44,6 @@ export const convertToCumulativeSumColumns = ( return createFormulaColumn(formula, { series, metric, dataView }); } else { const agg = SUPPORTED_METRICS[METRIC_TYPES.CUMULATIVE_SUM]; - return computeParentPipelineColumns( agg.name, { series, metric, dataView }, From a7a6e8f0bdf235055247aed3b877cd55103644df Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 16:25:21 +0300 Subject: [PATCH 072/129] Added date_histogram tests. --- .../convert_to_lens/lib/__mocks__/index.ts | 28 +++- .../lib/convert/date_histogram.test.ts | 131 ++++++++++++++++++ .../lib/convert/date_histogram.ts | 4 +- 3 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts index 885b8124575d8..aa07ffe34c3d3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -import { Series } from '../../../../common/types'; +import { PANEL_TYPES } from '../../../../common/enums'; +import { Panel, Series } from '../../../../common/types'; export const createSeries = (partialSeries?: Partial): Series => ({ axis_position: 'right', @@ -33,3 +34,28 @@ export const createSeries = (partialSeries?: Partial): Series => ({ steps: 0, ...partialSeries, }); + +export const createPanel = (parialPanel?: Partial): Panel => ({ + annotations: [], + axis_formatter: '', + axis_max: 100, + axis_min: 0, + axis_position: 'right', + axis_scale: '', + bar_color_rules: [], + drop_last_bucket: 0, + hide_last_value_indicator: false, + id: 'some-id', + ignore_daylight_time: true, + index_pattern: { id: 'test' }, + interval: '', + // eslint-disable-next-line @typescript-eslint/naming-convention + markdown_openLinksInNewTab: 0, + markdown_scrollbars: 0, + max_bars: 0, + series: [createSeries()], + show_grid: 0, + show_legend: 0, + type: PANEL_TYPES.TIMESERIES, + ...parialPanel, +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.ts new file mode 100644 index 0000000000000..1c90018a715ab --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { + DateHistogramColumn, + DateHistogramParams, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import type { Panel, Series } from '../../../../common/types'; +import { createPanel, createSeries } from '../__mocks__'; +import { convertToDateHistogramColumn, convertToDateHistogramParams } from './date_histogram'; + +describe('convertToDateHistogramParams', () => { + const series = createSeries(); + const seriesWithInverval = createSeries({ override_index_pattern: 1, series_interval: '1h' }); + const seriesWithDropLastBucket = createSeries({ + override_index_pattern: 1, + series_drop_last_bucket: 2, + }); + const seriesWithOIPFalse = createSeries({ override_index_pattern: 0 }); + + test.each<[string, [Panel, Series], DateHistogramParams]>([ + [ + 'with interval=auto if series inverval is empty and should override index pattern', + [createPanel({ series: [series] }), series], + { dropPartials: false, includeEmptyRows: true, interval: 'auto' }, + ], + [ + 'with specified interval if series interval is set and should override index pattern', + [createPanel({ series: [seriesWithInverval] }), seriesWithInverval], + { dropPartials: false, includeEmptyRows: true, interval: '1h' }, + ], + [ + 'with specified interval if should not override index pattern', + [createPanel({ series: [seriesWithOIPFalse], interval: '2h' }), seriesWithOIPFalse], + { dropPartials: false, includeEmptyRows: true, interval: '2h' }, + ], + [ + 'with dropPartials to true if should override index pattern and last bucket is dropped in series', + [createPanel({ series: [seriesWithDropLastBucket] }), seriesWithDropLastBucket], + { dropPartials: true, includeEmptyRows: true, interval: 'auto' }, + ], + [ + 'with dropPartials to true if should override index pattern and last bucket is dropped in panel', + [createPanel({ series: [series], drop_last_bucket: 2 }), series], + { dropPartials: true, includeEmptyRows: true, interval: 'auto' }, + ], + ])('should return date histogram params %s', (_, input, expected) => { + if (expected === null) { + expect(convertToDateHistogramParams(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToDateHistogramParams(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToDateHistogramParams(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); + +describe('convertToDateHistogramColumn', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + + test.each< + [string, Parameters, Partial | null] + >([ + [ + 'null if field is not correct', + [ + createPanel({ series: [series] }), + series, + dataView, + { fieldName: 'some-wrong-name', isSplit: false }, + ], + null, + ], + [ + 'null if field is empty', + [createPanel({ series: [series] }), series, dataView, { fieldName: '', isSplit: false }], + null, + ], + [ + 'date histogram column if field is present and valid', + [ + createPanel({ series: [series] }), + series, + dataView, + { fieldName: dataView.fields[0].name, isSplit: false }, + ], + { + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'date_histogram', + params: { dropPartials: false, includeEmptyRows: true, interval: 'auto' }, + sourceField: dataView.fields[0].name, + }, + ], + [ + 'date histogram column with isSplit=true if isSplit=true is passed as a parameter', + [ + createPanel({ series: [series] }), + series, + dataView, + { fieldName: dataView.fields[0].name, isSplit: true }, + ], + { + dataType: 'number', + isBucketed: true, + isSplit: true, + operationType: 'date_histogram', + params: { dropPartials: false, includeEmptyRows: true, interval: 'auto' }, + sourceField: dataView.fields[0].name, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToDateHistogramColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToDateHistogramColumn(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToDateHistogramColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts index 1a0ff798c737f..da3768ba30ca1 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts @@ -40,14 +40,14 @@ export const convertToDateHistogramColumn = ( dataView: DataView, { fieldName, isSplit }: { fieldName: string; isSplit: boolean } ): DateHistogramColumn | null => { - const params = convertToDateHistogramParams(model, series); - const dateField = dataView.getFieldByName(fieldName); if (!dateField) { return null; } + const params = convertToDateHistogramParams(model, series); + return { columnId: uuid(), operationType: 'date_histogram', From 74ed9d6dac4336dcc63228a50e6f1fb4ed6306c1 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 16:40:35 +0300 Subject: [PATCH 073/129] Added filter ratio tests. --- .../lib/convert/filter_ratio.test.ts | 79 +++++++++++++++++++ .../lib/convert/filter_ratio.ts | 1 - 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts new file mode 100644 index 0000000000000..40014bef0b1f5 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts @@ -0,0 +1,79 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { FormulaColumn } from './types'; +import type { Metric } from '../../../../common/types'; +import { createSeries } from '../__mocks__'; +import { convertFilterRatioToFormulaColumn } from './filter_ratio'; + +describe('convertFilterRatioToFormulaColumn', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const metric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, + }; + + const metricWithMetricAgg: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, + metric_agg: METRIC_TYPES.COUNT, + }; + + const metricWithNotSupportedMetricAgg: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, + metric_agg: METRIC_TYPES.MEDIAN, + }; + + test.each< + [string, Parameters, Partial | null] + >([ + [ + 'null if metric_agg is not supported', + [{ series, dataView, metrics: [metricWithNotSupportedMetricAgg] }], + null, + ], + [ + 'formula column if metric_agg is supported', + [{ series, dataView, metrics: [metricWithMetricAgg] }], + { + meta: { metricId: metricWithMetricAgg.id }, + operationType: 'formula', + params: { format: { id: 'bytes' }, formula: "count(kql='*') / count(kql='*')" }, + }, + ], + [ + 'formula column if metric_agg is not specified', + [{ series, dataView, metrics: [metric] }], + { + meta: { metricId: metric.id }, + operationType: 'formula', + params: { format: { id: 'bytes' }, formula: "count(kql='*') / count(kql='*')" }, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertFilterRatioToFormulaColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertFilterRatioToFormulaColumn(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertFilterRatioToFormulaColumn(...input)).toEqual( + expect.objectContaining(expected) + ); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts index 6c850fa332967..cdd150e9a9c36 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -15,7 +15,6 @@ export const convertFilterRatioToFormulaColumn = ( window?: string ): FormulaColumn | null => { const metric = metrics[metrics.length - 1]; - const formula = getFilterRatioFormula(metric, window); if (!formula) { From 2e1cafa906bd4afc933dae743cb38b3ff41b1f8e Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 17:07:53 +0300 Subject: [PATCH 074/129] Filters test added. --- .../lib/convert/filters.test.ts | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts new file mode 100644 index 0000000000000..d01e9fd88a345 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts @@ -0,0 +1,130 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FiltersParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { createSeries } from '../__mocks__'; +import { convertToFiltersColumn, convertToFiltersParams } from './filters'; +import { FiltersColumn } from './types'; + +describe('convertToFiltersParams', () => { + const filter = { language: 'lucene', query: 'some query' }; + const splitFilters = [ + { filter: { language: 'lucene', query: 'some other query' }, label: 'split' }, + ]; + + const series = createSeries(); + const seriesWithFilter = createSeries({ + split_mode: 'filter', + filter, + }); + + const seriesWithSplitFilters = createSeries({ + split_filters: splitFilters, + }); + + const seriesWithFilterAndSplitFilters = createSeries({ + split_mode: 'filter', + filter, + split_filters: splitFilters, + }); + + test.each<[string, Parameters, Partial | null]>([ + [ + 'empty filters if split_mode is not split and no split filters are specified', + [series], + { filters: [] }, + ], + [ + 'filters which contains data from filter if split mode is set to filter', + [seriesWithFilter], + { filters: [{ input: { query: filter.query, language: filter.language }, label: '' }] }, + ], + [ + 'filters which contains data from filters', + [seriesWithSplitFilters], + { filters: [{ input: { language: 'lucene', query: 'some other query' }, label: 'split' }] }, + ], + [ + 'filters which contains data from filters and filter if split mode is set to filter', + [seriesWithFilterAndSplitFilters], + { + filters: [ + { input: { query: filter.query, language: filter.language }, label: '' }, + { input: { language: 'lucene', query: 'some other query' }, label: 'split' }, + ], + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToFiltersParams(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToFiltersParams(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToFiltersParams(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); + +describe('convertToFiltersColumn', () => { + const filter = { language: 'lucene', query: 'some query' }; + const splitFilters = [ + { filter: { language: 'lucene', query: 'some other query' }, label: 'split' }, + ]; + + const series = createSeries(); + const seriesWithFilterAndSplitFilters = createSeries({ + split_mode: 'filter', + filter, + split_filters: splitFilters, + }); + + test.each<[string, Parameters, Partial | null]>([ + ['null if no filters was collected', [series, false], null], + [ + 'filters column if filters were collected', + [seriesWithFilterAndSplitFilters, false], + { + dataType: 'string', + isBucketed: true, + operationType: 'filters', + params: { + filters: [ + { input: { language: 'lucene', query: 'some query' }, label: '' }, + { input: { language: 'lucene', query: 'some other query' }, label: 'split' }, + ], + }, + }, + ], + [ + 'filters column with isSplit=true', + [seriesWithFilterAndSplitFilters, true], + { + dataType: 'string', + isBucketed: true, + isSplit: true, + operationType: 'filters', + params: { + filters: [ + { input: { language: 'lucene', query: 'some query' }, label: '' }, + { input: { language: 'lucene', query: 'some other query' }, label: 'split' }, + ], + }, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToFiltersColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToFiltersColumn(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToFiltersColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From b653473dd2cfc3e47eeb0e9d08676477edf2bd0e Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 17:32:12 +0300 Subject: [PATCH 075/129] createFormulaColumn test added. --- .../lib/convert/formula.test.ts | 123 ++++++++++++++++++ .../convert_to_lens/lib/convert/formula.ts | 10 +- 2 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts new file mode 100644 index 0000000000000..506ea54c6bf5e --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts @@ -0,0 +1,123 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createSeries } from '../__mocks__'; +import { createFormulaColumn } from './formula'; +import { FormulaColumn } from './types'; +import { Metric } from '../../../../common/types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { + createStubDataView, + stubLogstashDataView, +} from '@kbn/data-views-plugin/common/data_view.stub'; +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { stubLogstashFieldSpecMap } from '@kbn/data-views-plugin/common/field.stub'; + +describe('createFormulaColumn', () => { + const dataView = stubLogstashDataView; + const dataViewWithInvalidFormats = createStubDataView({ + spec: { + id: 'logstash-*', + title: 'logstash-*', + timeFieldName: 'time', + fields: stubLogstashFieldSpecMap, + }, + }); + + dataViewWithInvalidFormats.getFormatterForField = jest.fn().mockImplementation(() => ({ + type: { + id: 'date', + }, + })); + + const series = createSeries(); + const seriesWithValidFormatter = createSeries({ formatter: 'percent' }); + const seriesWithInvalidFormatter = createSeries({ formatter: 'date' }); + + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.MATH, + }; + const metricWithField: Metric = { + id: 'some-id', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, + }; + + const metricWithFieldWithUnsupportedFormat: Metric = { + id: 'some-id', + type: METRIC_TYPES.AVG, + field: dataView.fields[2].name, // 'date' formatter + }; + + const formula = 'count() / 2'; + + test.each<[string, Parameters, Partial | null]>([ + [ + 'formula column', + [formula, { series, metric, dataView }], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { formula }, + }, + ], + [ + 'formula column with format of the field', + [formula, { series, metric: metricWithField, dataView }], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { format: { id: 'bytes' }, formula }, + }, + ], + [ + 'formula column with format of series', + [formula, { series: seriesWithValidFormatter, metric: metricWithField, dataView }], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { format: { id: 'percent' }, formula }, + }, + ], + [ + 'formula column without format if custom formatter is not supported', + [formula, { series: seriesWithInvalidFormatter, metric: metricWithField, dataView }], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { formula }, + }, + ], + [ + 'formula column without format if field format is not supported', + [ + formula, + { + series, + metric: metricWithFieldWithUnsupportedFormat, + dataView: dataViewWithInvalidFormats, + }, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { formula }, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(createFormulaColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(createFormulaColumn(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(createFormulaColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 3056bba88af3f..b1d86b008cfb9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -21,19 +21,15 @@ type OtherFormulaAggregations = | typeof METRIC_TYPES.MIN_BUCKET | typeof METRIC_TYPES.SUM_BUCKET; -const convertToFormulaParams = (formula: string): FormulaParams | null => ({ +const convertToFormulaParams = (formula: string): FormulaParams => ({ formula, }); export const createFormulaColumn = ( - mathScript: string, + formula: string, { series, metric, dataView }: CommonColumnConverterArgs ): FormulaColumn | null => { - const params = convertToFormulaParams(mathScript); - if (!params) { - return null; - } - + const params = convertToFormulaParams(formula); return { operationType: 'formula', references: [], From 299033f939f24ac484d0e22313159406a44f1d0b Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 18:36:25 +0300 Subject: [PATCH 076/129] convertMathToFormulaColumn test added. --- .../lib/convert/formula.test.ts | 172 +++++++++++++++++- .../convert_to_lens/lib/convert/formula.ts | 6 +- 2 files changed, 173 insertions(+), 5 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts index 506ea54c6bf5e..60f987c560a6a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts @@ -7,7 +7,7 @@ */ import { createSeries } from '../__mocks__'; -import { createFormulaColumn } from './formula'; +import { createFormulaColumn, convertMathToFormulaColumn } from './formula'; import { FormulaColumn } from './types'; import { Metric } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; @@ -121,3 +121,173 @@ describe('createFormulaColumn', () => { } }); }); + +describe('convertMathToFormulaColumn', () => { + const dataView = stubLogstashDataView; + const dataViewWithInvalidFormats = createStubDataView({ + spec: { + id: 'logstash-*', + title: 'logstash-*', + timeFieldName: 'time', + fields: stubLogstashFieldSpecMap, + }, + }); + + dataViewWithInvalidFormats.getFormatterForField = jest.fn().mockImplementation(() => ({ + type: { + id: 'date', + }, + })); + + const series = createSeries(); + const avgMetric: Metric = { + id: 'some-id-0', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, + }; + + const notSupportedMetric: Metric = { + id: 'some-id-0', + type: METRIC_TYPES.MEDIAN, + field: dataView.fields[0].name, + }; + + const notSupportedTopHitMetricWithSize: Metric = { + id: 'some-id-0', + type: TSVB_METRIC_TYPES.TOP_HIT, + field: dataView.fields[0].name, + size: 2, + }; + + const notSupportedAvgMetric: Metric = { + ...avgMetric, + order: 'asc', + }; + + const script = 'params.avg_bytes / 2'; + + const mathMetricWithoutScript: Metric = { + id: 'some-id-1', + type: TSVB_METRIC_TYPES.MATH, + }; + + const mathMetricWithoutVariables: Metric = { + ...mathMetricWithoutScript, + script, + }; + + const mathMetric: Metric = { + ...mathMetricWithoutVariables, + variables: [{ id: 'params.avg_bytes-id', field: avgMetric.id, name: 'avg_bytes' }], + }; + + const percentileScript = 'params.percentile_bytes / 2'; + + const percentileMetric: Metric = { + id: 'percentile_id', + type: TSVB_METRIC_TYPES.PERCENTILE, + field: dataView.fields[0].name, + }; + + const mathMetricWithPercentile: Metric = { + ...mathMetricWithoutVariables, + script: percentileScript, + variables: [ + { + id: 'params.percentile_bytes_id', + field: `${percentileMetric.id}[50]`, + name: 'percentile_bytes', + }, + ], + }; + + const percentileRankMetric: Metric = { + id: 'percentile_rank_id', + type: TSVB_METRIC_TYPES.PERCENTILE_RANK, + field: dataView.fields[0].name, + }; + + const mathMetricWithPercentileRank: Metric = { + ...mathMetricWithoutVariables, + script: percentileScript, + variables: [ + { + id: 'params.percentile_bytes_id', + field: `${percentileRankMetric.id}[50]`, + name: 'percentile_bytes', + }, + ], + }; + + test.each<[string, Parameters, Partial | null]>( + [ + ['null if no math metric was provided', [{ series, metrics: [avgMetric], dataView }], null], + [ + "null if math metric doesn't contain script", + [{ series, metrics: [mathMetricWithoutScript], dataView }], + null, + ], + [ + 'null if not supported metric is provided', + [{ series, metrics: [notSupportedMetric], dataView }], + null, + ], + [ + "null if math metric doesn't contain variables", + [{ series, metrics: [mathMetricWithoutVariables], dataView }], + null, + ], + [ + "null if math metric's script contains params, not covered by other metrics", + [{ series, metrics: [mathMetric], dataView }], + null, + ], + [ + 'null if some of the metrics is top_hit with size more than 1', + [{ series, metrics: [notSupportedTopHitMetricWithSize, mathMetric], dataView }], + null, + ], + [ + 'null if some of the metrics contains order=asc', + [{ series, metrics: [notSupportedAvgMetric, mathMetric], dataView }], + null, + ], + [ + 'formula column if it is possible to convert script with vars to math formula', + [{ series, metrics: [avgMetric, mathMetric], dataView }], + { + meta: { metricId: 'some-id-1' }, + operationType: 'formula', + params: { formula: 'average(bytes) / 2' }, + }, + ], + [ + 'formula column if percentile metric is provided', + [{ series, metrics: [percentileMetric, mathMetricWithPercentile], dataView }], + { + meta: { metricId: 'some-id-1' }, + operationType: 'formula', + params: { formula: 'percentile(bytes, percentile=50) / 2' }, + }, + ], + [ + 'formula column if percentile_rank metric is provided', + [{ series, metrics: [percentileRankMetric, mathMetricWithPercentileRank], dataView }], + { + meta: { metricId: 'some-id-1' }, + operationType: 'formula', + params: { formula: 'percentile_rank(bytes, value=50) / 2' }, + }, + ], + ] + )('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertMathToFormulaColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertMathToFormulaColumn(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertMathToFormulaColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index b1d86b008cfb9..cd85c0c9e4888 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -81,15 +81,13 @@ export const convertMathToFormulaColumn = ( ): FormulaColumn | null => { // find the metric idx that has math expression const metric = metrics.find(({ type }) => type === 'math'); - let script: string | null | undefined = metrics[metrics.length - 1].script; - if (!metric) { return null; } const { variables } = metric; - - if (!script || !variables) { + let script: string | null | undefined = metrics[metrics.length - 1].script; + if (!script || !variables || !variables.length) { return null; } From 6594b8fb5f11053c52c55d4bed5d85bf6d08f982 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 18:44:35 +0300 Subject: [PATCH 077/129] Added one more case to check. --- .../convert_to_lens/lib/convert/formula.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts index 60f987c560a6a..35bea1f266681 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts @@ -279,6 +279,20 @@ describe('convertMathToFormulaColumn', () => { params: { formula: 'percentile_rank(bytes, value=50) / 2' }, }, ], + [ + 'formula column if script is purely math and has something except static number', + [{ series, metrics: [{ ...mathMetric, script: 'a' }], dataView }], + { + meta: { metricId: 'some-id-1' }, + operationType: 'formula', + params: { formula: 'a' }, + }, + ], + [ + 'null if script is purely math and contains static number only', + [{ series, metrics: [{ ...mathMetric, script: '1' }], dataView }], + null, + ], ] )('should return %s', (_, input, expected) => { if (expected === null) { From c9d089cc2c88ff204fde27aa6934443ea7858a43 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Sat, 27 Aug 2022 18:58:29 +0300 Subject: [PATCH 078/129] Added test for convertOtherAggsToFormulaColumn --- .../lib/convert/formula.test.ts | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts index 35bea1f266681..2df6aeb20f6c2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts @@ -7,7 +7,11 @@ */ import { createSeries } from '../__mocks__'; -import { createFormulaColumn, convertMathToFormulaColumn } from './formula'; +import { + createFormulaColumn, + convertMathToFormulaColumn, + convertOtherAggsToFormulaColumn, +} from './formula'; import { FormulaColumn } from './types'; import { Metric } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; @@ -305,3 +309,56 @@ describe('convertMathToFormulaColumn', () => { } }); }); + +describe('convertOtherAggsToFormulaColumn', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const avgMetric: Metric = { + id: 'some-id-0', + type: METRIC_TYPES.AVG, + field: dataView.fields[0].name, + }; + + const field = `${avgMetric.id}`; + const id = 'some-id-1[50]'; + + test.each< + [string, Parameters, Partial | null] + >([ + [ + 'null if no nested metric was provided', + [ + TSVB_METRIC_TYPES.POSITIVE_ONLY, + { series, metrics: [{ type: TSVB_METRIC_TYPES.POSITIVE_ONLY, id, field }], dataView }, + ], + null, + ], + [ + 'formula column if no nested metric was provided', + [ + TSVB_METRIC_TYPES.POSITIVE_ONLY, + { + series, + metrics: [avgMetric, { type: TSVB_METRIC_TYPES.POSITIVE_ONLY, id, field }], + dataView, + }, + ], + { + meta: { metricId: id }, + operationType: 'formula', + params: { formula: 'pick_max(average(bytes), 0)' }, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertOtherAggsToFormulaColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertOtherAggsToFormulaColumn(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertOtherAggsToFormulaColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From 875e6ed9bf3a96f965a6b03ac8bca8ba8e58a41b Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 10:15:52 +0300 Subject: [PATCH 079/129] added more tests for formula. --- .../lib/convert/formula.test.ts | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts index 2df6aeb20f6c2..58620606e5b4e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts @@ -327,6 +327,30 @@ describe('convertOtherAggsToFormulaColumn', () => { >([ [ 'null if no nested metric was provided', + [ + METRIC_TYPES.AVG_BUCKET, + { series, metrics: [{ type: METRIC_TYPES.AVG_BUCKET, id, field }], dataView }, + ], + null, + ], + [ + 'formula column if no nested metric was provided', + [ + METRIC_TYPES.AVG_BUCKET, + { + series, + metrics: [avgMetric, { type: METRIC_TYPES.AVG_BUCKET, id, field }], + dataView, + }, + ], + { + meta: { metricId: 'some-id-1[50]' }, + operationType: 'formula', + params: { formula: 'overall_average(average(bytes))' }, + }, + ], + [ + 'null if no nested metric was provided and aggregation is positive_only', [ TSVB_METRIC_TYPES.POSITIVE_ONLY, { series, metrics: [{ type: TSVB_METRIC_TYPES.POSITIVE_ONLY, id, field }], dataView }, @@ -334,7 +358,7 @@ describe('convertOtherAggsToFormulaColumn', () => { null, ], [ - 'formula column if no nested metric was provided', + 'formula column if no nested metric was provided and aggregation is positive_only', [ TSVB_METRIC_TYPES.POSITIVE_ONLY, { From 133cd0bfdcb65546d59411cce2a75eadbb020a73 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 11:13:09 +0300 Subject: [PATCH 080/129] Added last_value tests. --- .../lib/convert/last_value.test.ts | 103 ++++++++++++++++++ .../convert_to_lens/lib/convert/last_value.ts | 12 +- 2 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts new file mode 100644 index 0000000000000..59de79679f9db --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts @@ -0,0 +1,103 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createSeries } from '../__mocks__'; +import { convertToLastValueParams, convertToLastValueColumn } from './last_value'; +import { Metric } from '../../../../common/types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { LastValueColumn } from './types'; +import { LastValueParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; + +describe('convertToLastValueParams', () => { + const commonMetric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.TOP_HIT, + }; + const sortField = 'some-field'; + test.each<[string, Parameters, LastValueParams]>([ + [ + 'params with emtpy sortField if metric.order_by is emtpy', + [commonMetric], + { showArrayValues: false, sortField: undefined }, + ], + [ + 'params with sortField if metric.order_by is set', + [{ ...commonMetric, order_by: sortField }], + { showArrayValues: false, sortField }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToLastValueParams(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToLastValueParams(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToLastValueParams(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); + +describe('convertToLastValueColumn', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const metric: Metric = { + id: 'some-id-0', + type: TSVB_METRIC_TYPES.TOP_HIT, + field: dataView.fields[0].name, + order_by: dataView.fields[2].name, + }; + + test.each<[string, Parameters, Partial | null]>( + [ + [ + 'null if size is greater than 1 (unsupported)', + [{ series, metrics: [{ ...metric, size: 2 }], dataView }], + null, + ], + [ + 'null if order is equal to asc (unsupported)', + [{ series, metrics: [{ ...metric, order: 'asc' }], dataView }], + null, + ], + [ + 'null if field does not exist', + [{ series, metrics: [{ ...metric, field: 'unknown' }], dataView }], + null, + ], + [ + 'last value column', + [{ series, metrics: [metric], dataView }], + { + meta: { metricId: 'some-id-0' }, + operationType: 'last_value', + params: { format: { id: 'bytes' }, showArrayValues: false, sortField: '@timestamp' }, + }, + ], + [ + 'last value column with window', + [{ series, metrics: [metric], dataView }, '10'], + { + meta: { metricId: 'some-id-0' }, + operationType: 'last_value', + params: { format: { id: 'bytes' }, showArrayValues: false, sortField: '@timestamp' }, + window: '10', + }, + ], + ] + )('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToLastValueColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToLastValueColumn(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToLastValueColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index 99bad5e607fab..6a954d4e86dd2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -11,7 +11,7 @@ import { CommonColumnsConverterArgs, LastValueColumn } from './types'; import type { Metric } from '../../../../common/types'; import { createColumn, getFormat } from './column'; -const convertToLastValueParams = (metric: Metric): LastValueParams | null => ({ +export const convertToLastValueParams = (metric: Metric): LastValueParams => ({ sortField: metric.order_by, showArrayValues: false, }); @@ -29,11 +29,6 @@ export const convertToLastValueColumn = ( return null; } - const params = convertToLastValueParams(currentMetric); - if (!params) { - return null; - } - const field = dataView.getFieldByName(currentMetric.field ?? 'document'); if (!field) { return null; @@ -43,6 +38,9 @@ export const convertToLastValueColumn = ( operationType: 'last_value', sourceField: field.name ?? 'document', ...createColumn(series, currentMetric, undefined, { window }), - params: { ...params, ...getFormat(series, currentMetric.field, dataView) }, + params: { + ...convertToLastValueParams(currentMetric), + ...getFormat(series, currentMetric.field, dataView), + }, }; }; From fcf971138e05b2d9e59ee68ed7eb10477b8d037a Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 11:18:06 +0300 Subject: [PATCH 081/129] Added tests for moving average. --- .../lib/convert/moving_average.test.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts new file mode 100644 index 0000000000000..4a248d66723b7 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts @@ -0,0 +1,26 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { convertToMovingAverageParams } from './moving_average'; +import { Metric } from '../../../../common/types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { MovingAverageParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; + +describe('convertToMovingAverageParams', () => { + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + }; + const window = 10; + test.each<[string, Parameters, MovingAverageParams]>([ + ['params with default window if no window is specified in metric', [metric], { window: 0 }], + ['params with window', [{ ...metric, window }], { window }], + ])('should return %s', (_, input, expected) => { + expect(convertToMovingAverageParams(...input)).toEqual(expect.objectContaining(expected)); + }); +}); From 6947132e3ab206bb5b15520f205ecfd9b940884e Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 11:18:41 +0300 Subject: [PATCH 082/129] Style fix. --- .../public/convert_to_lens/lib/convert/moving_average.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts index 4a248d66723b7..8b4747175c553 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts @@ -17,6 +17,7 @@ describe('convertToMovingAverageParams', () => { type: TSVB_METRIC_TYPES.MOVING_AVERAGE, }; const window = 10; + test.each<[string, Parameters, MovingAverageParams]>([ ['params with default window if no window is specified in metric', [metric], { window: 0 }], ['params with window', [{ ...metric, window }], { window }], From 00e3fb61aeafae3180383ea81bd5218b13e44434 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 12:33:52 +0300 Subject: [PATCH 083/129] Added test for convertMetricAggregationColumnWithoutSpecialParams --- .../lib/convert/parent_pipeline.test.ts | 139 ++++++++++++++++++ .../lib/convert/parent_pipeline.ts | 10 +- 2 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts new file mode 100644 index 0000000000000..5452163029de7 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -0,0 +1,139 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createSeries } from '../__mocks__'; +import { MetricType } from '../../../../common/types'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { convertMetricAggregationColumnWithoutSpecialParams } from './parent_pipeline'; +import { SupportedMetric, SUPPORTED_METRICS } from '../metrics'; +import { ColumnWithMeta } from './types'; + +describe('convertMetricAggregationColumnWithoutSpecialParams', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + + test.each<[string, SupportedMetric]>([ + [SUPPORTED_METRICS.top_hit.name, SUPPORTED_METRICS.top_hit], + [SUPPORTED_METRICS.percentile.name, SUPPORTED_METRICS.percentile], + [SUPPORTED_METRICS.percentile_rank.name, SUPPORTED_METRICS.percentile_rank], + [SUPPORTED_METRICS.positive_rate.name, SUPPORTED_METRICS.positive_rate], + ])('should return null for metric %s', (_, operation) => { + expect( + convertMetricAggregationColumnWithoutSpecialParams(operation, { + series, + dataView, + metrics: [{ type: operation.name as MetricType, id: 'some-id' }], + }) + ).toBeNull(); + }); + + test.each<[string, SupportedMetric]>([ + [SUPPORTED_METRICS.avg.name, SUPPORTED_METRICS.avg], + [SUPPORTED_METRICS.cardinality.name, SUPPORTED_METRICS.cardinality], + [SUPPORTED_METRICS.max.name, SUPPORTED_METRICS.max], + [SUPPORTED_METRICS.min.name, SUPPORTED_METRICS.min], + [SUPPORTED_METRICS.sum.name, SUPPORTED_METRICS.sum], + [SUPPORTED_METRICS.std_deviation.name, SUPPORTED_METRICS.std_deviation], + ])('should return null for metric %s without valid field', (_, operation) => { + expect( + convertMetricAggregationColumnWithoutSpecialParams(operation, { + series, + dataView, + metrics: [{ type: operation.name as MetricType, id: 'some-id' }], + }) + ).toBeNull(); + }); + + test.each<[string, SupportedMetric, Partial]>([ + [ + SUPPORTED_METRICS.count.name, + SUPPORTED_METRICS.count, + { + meta: { metricId: 'some-id' }, + operationType: 'count', + params: {}, + sourceField: 'document', + }, + ], + ])('should return column for metric %s without valid field', (_, operation, expected) => { + expect( + convertMetricAggregationColumnWithoutSpecialParams(operation, { + series, + dataView, + metrics: [{ type: operation.name as MetricType, id: 'some-id' }], + }) + ).toEqual(expect.objectContaining(expected)); + }); + + test.each<[string, SupportedMetric, Partial]>([ + [ + SUPPORTED_METRICS.avg.name, + SUPPORTED_METRICS.avg, + { + meta: { metricId: 'some-id' }, + operationType: 'average', + params: { format: { id: 'bytes' } }, + }, + ], + [ + SUPPORTED_METRICS.cardinality.name, + SUPPORTED_METRICS.cardinality, + { + meta: { metricId: 'some-id' }, + operationType: 'unique_count', + params: { format: { id: 'bytes' } }, + }, + ], + [ + SUPPORTED_METRICS.max.name, + SUPPORTED_METRICS.max, + { + meta: { metricId: 'some-id' }, + operationType: 'max', + params: { format: { id: 'bytes' } }, + }, + ], + [ + SUPPORTED_METRICS.min.name, + SUPPORTED_METRICS.min, + { + meta: { metricId: 'some-id' }, + operationType: 'min', + params: { format: { id: 'bytes' } }, + }, + ], + [ + SUPPORTED_METRICS.sum.name, + SUPPORTED_METRICS.sum, + { + meta: { metricId: 'some-id' }, + operationType: 'sum', + params: { format: { id: 'bytes' } }, + }, + ], + [ + SUPPORTED_METRICS.std_deviation.name, + SUPPORTED_METRICS.std_deviation, + { + meta: { metricId: 'some-id' }, + operationType: 'standard_deviation', + params: { format: { id: 'bytes' } }, + }, + ], + ])('should return column for metric %s with valid field', (_, operation, expected) => { + expect( + convertMetricAggregationColumnWithoutSpecialParams(operation, { + series, + dataView, + metrics: [ + { type: operation.name as MetricType, id: 'some-id', field: dataView.fields[0].name }, + ], + }) + ).toEqual(expect.objectContaining(expected)); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index db31fa5d310bc..f4ab97919ac89 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -25,6 +25,7 @@ import { PercentileColumn, PercentileRanksColumn, SumColumn, + FormulaColumn, } from './types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { Metric, Series } from '../../../../common/types'; @@ -40,6 +41,7 @@ import { createFormulaColumn } from './formula'; import { convertToMovingAverageParams } from './moving_average'; import { convertToPercentileColumn } from './percentile'; import { convertToPercentileRankColumn } from './percentile_rank'; +import { convertToCounterRateFormulaColumn } from './counter_rate'; type MetricAggregationWithoutParams = | typeof Operations.AVERAGE @@ -60,7 +62,8 @@ type MetricAggregation = type MetricAggregationColumnWithSpecialParams = | PercentileColumn | PercentileRanksColumn - | LastValueColumn; + | LastValueColumn + | FormulaColumn; type MetricAggregationColumnWithoutSpecialParams = | AvgColumn @@ -86,7 +89,6 @@ const SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS: MetricAggregationWithoutParams[] = Operations.AVERAGE, Operations.COUNT, Operations.UNIQUE_COUNT, - Operations.COUNTER_RATE, Operations.MAX, Operations.MIN, Operations.SUM, @@ -98,6 +100,7 @@ const SUPPORTED_METRIC_AGGS: MetricAggregation[] = [ Operations.LAST_VALUE, Operations.PERCENTILE, Operations.PERCENTILE_RANK, + Operations.COUNTER_RATE, ]; const isSupportedAggregation = (agg: string): agg is MetricAggregation => { @@ -159,6 +162,9 @@ export const convertMetricAggregationToColumn = ( window, }); } + if (aggregation.name === Operations.COUNTER_RATE) { + return convertToCounterRateFormulaColumn({ series, metrics: [metric], dataView }); + } if (aggregation.name === Operations.LAST_VALUE) { return null; From 4d45e3fac74285d59a4aca5de9fad7459282eff9 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 29 Aug 2022 13:49:18 +0300 Subject: [PATCH 084/129] Add tests for metrics_helper. Update tests for filter ratio and counter rate formulas --- .../lib/convert/counter_rate.ts | 2 +- .../lib/metrics/counter_rate_formula.test.ts | 26 ++ .../lib/metrics/counter_rate_formula.ts | 5 +- .../lib/metrics/filter_ratio_formula.test.ts | 81 +++--- .../lib/metrics/filter_ratio_formula.ts | 12 +- .../lib/metrics/metrics_helpers.test.ts | 241 ++++++++++++++++++ .../lib/metrics/metrics_helpers.ts | 3 +- 7 files changed, 321 insertions(+), 49 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts index a83c29d63ef55..7030ddef33a60 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts @@ -22,6 +22,6 @@ export const convertToCounterRateFormulaColumn = ({ return null; } - const formula = buildCounterRateFormula(metric, field); + const formula = buildCounterRateFormula(metric, field.name); return createFormulaColumn(formula, { series, metric, dataView }); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts new file mode 100644 index 0000000000000..aa1d367be6c11 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts @@ -0,0 +1,26 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { Metric } from '../../../../common/types'; +import { buildCounterRateFormula } from './counter_rate_formula'; + +describe('buildCounterRateFormula', () => { + test('should return correct formula for counter rate', () => { + const dataView = stubLogstashDataView; + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.POSITIVE_RATE, + unit: '1h', + }; + + const formula = buildCounterRateFormula(metric, dataView.fields[0].name); + expect(formula).toStrictEqual('pick_max(differences(max(bytes), shift=1h), 0)'); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts index 77b7ab1fdc778..f19daa8225f1b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { DataViewField } from '@kbn/data-views-plugin/common'; import type { Metric } from '../../../../common/types'; import { TimeScaleValue, isTimeScaleValue } from './metrics_helpers'; @@ -22,8 +21,8 @@ const buildDifferencesFormula = (selector: string, shift?: TimeScaleValue) => { return `differences(${selector}${shift ? `, shift=${shift}` : ''})`; }; -export const buildCounterRateFormula = (metric: Metric, field: DataViewField) => { - const maxFormula = buildMaxFormula(field.name); +export const buildCounterRateFormula = (metric: Metric, fieldName: string) => { + const maxFormula = buildMaxFormula(fieldName); const unit = metric.unit && isTimeScaleValue(metric.unit) ? metric.unit : undefined; const diffOfMaxFormula = buildDifferencesFormula(maxFormula, unit); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts index 1d5ae66ce958b..4ad05ea94d15b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts @@ -6,48 +6,53 @@ * Side Public License, v 1. */ +import { METRIC_TYPES } from '@kbn/data-plugin/public'; import type { Metric } from '../../../../common/types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { getFilterRatioFormula } from './filter_ratio_formula'; describe('getFilterRatioFormula', () => { - test('should return correct formula for filter ratio', () => { - const metric = { - id: '12345', - type: 'filter_ratio', - field: 'day_of_week_i', - numerator: { - query: 'category.keyword : "Men\'s Clothing" ', - language: 'kuery', - }, - denominator: { - query: 'customer_gender : "FEMALE" ', - language: 'kuery', - }, - } as Metric; - const formula = getFilterRatioFormula(metric); - expect(formula).toStrictEqual( - "count(kql='category.keyword : \"Men\\'s Clothing\" ') / count(kql='customer_gender : \"FEMALE\" ')" - ); - }); + const metric: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.FILTER_RATIO, + field: 'test-1', + }; + + const metricWithMetricAgg: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.FILTER_RATIO, + field: 'test-1', + metric_agg: METRIC_TYPES.AVG, + }; + + const metricWithNotSupportedMetricAgg: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.FILTER_RATIO, + field: 'test-1', + metric_agg: METRIC_TYPES.MEDIAN, + }; - test('should return correct formula for positive rate', () => { - const metric = { - id: '12345', - type: 'filter_ratio', - field: 'day_of_week_i', - numerator: { - query: 'category.keyword : "Men\'s Clothing" ', - language: 'kuery', - }, - denominator: { - query: 'customer_gender : "FEMALE" ', - language: 'kuery', - }, - metric_agg: 'positive_rate', - } as Metric; - const formula = getFilterRatioFormula(metric); - expect(formula).toStrictEqual( - "counter_rate(max('day_of_week_i',kql='category.keyword : \"Men\\'s Clothing\" ')) / counter_rate(max('day_of_week_i',kql='customer_gender : \"FEMALE\" '))" - ); + test.each<[string, [Metric, string | undefined], string | null]>([ + ['null if metric_agg is not supported', [metricWithNotSupportedMetricAgg, undefined], null], + [ + 'filter ratio formula if metric_agg is not specified', + [metric, undefined], + "count(kql='*') / count(kql='*')", + ], + [ + 'filter ratio formula if metric_agg is specified', + [metricWithMetricAgg, undefined], + "average('test-1',kql='*') / average('test-1',kql='*')", + ], + [ + 'filter ratio formula if window is provided', + [metricWithMetricAgg, '1h'], + "average('test-1',kql='*', timeRange='1h') / average('test-1',kql='*', timeRange='1h')", + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(getFilterRatioFormula(...input)).toBeNull(); + } + expect(getFilterRatioFormula(...input)).toEqual(expected); }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index 26a4ef328c663..d6613c6182eff 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -38,16 +38,16 @@ export const getFilterRatioFormula = (currentMetric: Metric, window?: string) => const operation = metric_agg && metric_agg !== 'count' ? `${aggFormula}('${field}',` : 'count('; if (aggregation.name === 'counter_rate') { - const numeratorFormula = constructFilterRationFormula( - `${aggregation.name}(max('${field}',`, + const numeratorFormula = `max(${constructFilterRationFormula( + `differences(max('${field}',`, numerator, window - ); - const denominatorFormula = constructFilterRationFormula( - `${aggregation.name}(max('${field}',`, + )})`; + const denominatorFormula = `max(${constructFilterRationFormula( + `differences(max('${field}',`, denominator, window - ); + )})`; return `${numeratorFormula}) / ${denominatorFormula})`; } else { const numeratorFormula = constructFilterRationFormula(operation, numerator, window); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts new file mode 100644 index 0000000000000..fb3133634090a --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts @@ -0,0 +1,241 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { TimeRange } from '@kbn/data-plugin/common'; +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import type { Metric, Series, Panel } from '../../../../common/types'; +import { TIME_RANGE_DATA_MODES, TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { getFormulaEquivalent, getWindow } from './metrics_helpers'; +import { createPanel, createSeries } from '../__mocks__'; + +jest.mock('../../../services', () => ({ + getUISettings: () => ({ get: () => 50 }), +})); + +describe('getFormulaEquivalent', () => { + const notSupportedMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.MEDIAN, + field: 'test-1', + }; + + const supportedMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + field: 'test-1', + }; + + const countMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.COUNT, + field: 'test-1', + }; + + const staticValue: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.STATIC, + value: '100', + }; + + const filterRatioMetric: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.FILTER_RATIO, + field: 'test-1', + metric_agg: METRIC_TYPES.AVG, + }; + + const stdDeviationMetricWithLowerMode: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.STD_DEVIATION, + field: 'test-1', + mode: 'lower', + }; + + const stdDeviationMetricWithUpperMode: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.STD_DEVIATION, + field: 'test-1', + mode: 'upper', + }; + + const sibblingPipelineMetric: Metric[] = [ + { + id: 'test-1', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'some-random-value', + type: METRIC_TYPES.AVG_BUCKET, + field: 'test-1', + }, + ]; + + const parentPipelineMetric: Metric[] = [ + { + id: 'test-1', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: 'test-1', + }, + ]; + + const percentileMetric: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.PERCENTILE, + field: 'test-1', + }; + + const percentileRankMetric: Metric = { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.PERCENTILE_RANK, + field: 'test-1', + }; + + test.each<[string, [Metric, Metric[], { metaValue?: number; window?: string }], string | null]>([ + ['null if metric is not supported', [notSupportedMetric, [notSupportedMetric], {}], null], + [ + 'correct formula if metric is sibling pipeline agg', + [sibblingPipelineMetric[1], sibblingPipelineMetric, {}], + 'overall_average(average(test-field-1))', + ], + [ + 'correct formula if metric is percentile agg', + [percentileMetric, [percentileMetric], { metaValue: 50 }], + 'percentile(test-1, percentile=50)', + ], + [ + 'correct formula if metric is percentile rank agg', + [percentileRankMetric, [percentileRankMetric], { metaValue: 5 }], + 'percentile_rank(test-1, value=5)', + ], + [ + 'correct formula if metric is parent pipeline agg', + [parentPipelineMetric[1], parentPipelineMetric, {}], + 'moving_average(average(test-field-1))', + ], + ['correct formula if metric is count agg', [countMetric, [countMetric], {}], 'count()'], + ['correct formula if metric is static value', [staticValue, [staticValue], {}], '100'], + [ + 'correct formula if metric is filter ratio', + [filterRatioMetric, [filterRatioMetric], {}], + "average('test-1',kql='*') / average('test-1',kql='*')", + ], + [ + 'correct formula if metric is standart deviation with lower mode', + [stdDeviationMetricWithLowerMode, [stdDeviationMetricWithLowerMode], {}], + 'average(test-1) - 1.5 * standard_deviation(test-1)', + ], + [ + 'correct formula if metric is standart deviation with upper mode', + [stdDeviationMetricWithUpperMode, [stdDeviationMetricWithUpperMode], {}], + 'average(test-1) + 1.5 * standard_deviation(test-1)', + ], + [ + 'correct formula if metric is supported', + [supportedMetric, [supportedMetric], {}], + 'average(test-1)', + ], + [ + 'correct formula if metric is supported and window is provided', + [supportedMetric, [supportedMetric], { window: '1h' }], + "average(test-1, timeRange='1h')", + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(getFormulaEquivalent(...input)).toBeNull(); + } + expect(getFormulaEquivalent(...input)).toEqual(expected); + }); +}); + +describe('getWindow', () => { + const timeRange: TimeRange = { + from: '2022-02-04', + to: '2022-02-05', + }; + const series = createSeries(); + const seriesWithInverval = createSeries({ + override_index_pattern: 1, + series_interval: '10h', + time_range_mode: TIME_RANGE_DATA_MODES.LAST_VALUE, + }); + const seriesWithEntireTimeRangeMode = createSeries({ + override_index_pattern: 1, + series_interval: '10h', + time_range_mode: TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, + }); + + test.each<[string, [Panel, Series, TimeRange], string | undefined]>([ + [ + 'undefined if panel time range mode is entire time range', + [ + createPanel({ series: [series], time_range_mode: TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE }), + series, + timeRange, + ], + undefined, + ], + [ + 'undefined if series time range mode is entire time range and should override index pattern', + [ + createPanel({ + series: [seriesWithEntireTimeRangeMode], + time_range_mode: TIME_RANGE_DATA_MODES.LAST_VALUE, + }), + seriesWithEntireTimeRangeMode, + timeRange, + ], + undefined, + ], + [ + 'specified interval if panel interval is set and should not override index pattern', + [ + createPanel({ + series: [series], + time_range_mode: TIME_RANGE_DATA_MODES.LAST_VALUE, + interval: '5h', + }), + series, + timeRange, + ], + '5h', + ], + [ + 'specified interval if series interval is set and should override index pattern', + [createPanel({ series: [seriesWithInverval] }), seriesWithInverval, timeRange], + '10h', + ], + [ + 'calculated interval if panel interal is not defined', + [ + createPanel({ series: [series], time_range_mode: TIME_RANGE_DATA_MODES.LAST_VALUE }), + series, + timeRange, + ], + '10m', + ], + ])('should return %s', (_, input, expected) => { + if (expected === undefined) { + expect(getWindow(...input)).toBeUndefined(); + } + expect(getWindow(...input)).toEqual(expected); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 5c76707706af5..9ae5cb3108e52 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -18,6 +18,7 @@ import { getFilterRatioFormula } from './filter_ratio_formula'; import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; +import { buildCounterRateFormula } from './counter_rate_formula'; const shouldCalculateWindow = (timeRangeMode?: string) => { return timeRangeMode === TIME_RANGE_DATA_MODES.LAST_VALUE; @@ -125,7 +126,7 @@ export const getFormulaEquivalent = ( ); } case 'positive_rate': { - return `${aggFormula}(max(${currentMetric.field}${addTimeRangeToFormula(window)}))`; + return buildCounterRateFormula(currentMetric, currentMetric.field!); } case 'filter_ratio': { return getFilterRatioFormula(currentMetric, window); From 2c9662c1c548751d256fd27ad5d4dc5c28e9c4be Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 14:10:18 +0300 Subject: [PATCH 085/129] Added tests for convertMetricAggregationToColumn --- .../lib/convert/parent_pipeline.test.ts | 182 +++++++++++++++++- .../lib/convert/parent_pipeline.ts | 17 +- .../lib/convert/percentile_rank.ts | 4 +- 3 files changed, 189 insertions(+), 14 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index 5452163029de7..c832ff79b33fe 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -9,9 +9,15 @@ import { createSeries } from '../__mocks__'; import { MetricType } from '../../../../common/types'; import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; -import { convertMetricAggregationColumnWithoutSpecialParams } from './parent_pipeline'; +import { + convertMetricAggregationColumnWithoutSpecialParams, + convertMetricAggregationToColumn, + MetricAggregationColumn, +} from './parent_pipeline'; import { SupportedMetric, SUPPORTED_METRICS } from '../metrics'; import { ColumnWithMeta } from './types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { METRIC_TYPES } from '@kbn/data-plugin/public'; describe('convertMetricAggregationColumnWithoutSpecialParams', () => { const dataView = stubLogstashDataView; @@ -137,3 +143,177 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { ).toEqual(expect.objectContaining(expected)); }); }); + +describe('convertMetricAggregationToColumn', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + test('should return null for not supported metric aggregation', () => { + expect( + convertMetricAggregationToColumn(SUPPORTED_METRICS.math, { + series, + dataView, + metric: { type: TSVB_METRIC_TYPES.MATH, id: 'some-id', field: dataView.fields[0].name }, + }) + ).toBeNull(); + }); + + test('should return null for supported metric aggregation with empty field if it is required', () => { + expect( + convertMetricAggregationToColumn(SUPPORTED_METRICS.avg, { + series, + dataView, + metric: { type: METRIC_TYPES.AVG, id: 'some-id' }, + }) + ).toBeNull(); + }); + + test('should return column for supported metric aggregation with empty field if it is not required', () => { + expect( + convertMetricAggregationToColumn(SUPPORTED_METRICS.count, { + series, + dataView, + metric: { type: METRIC_TYPES.COUNT, id: 'some-id' }, + }) + ).toEqual( + expect.objectContaining({ + meta: { metricId: 'some-id' }, + operationType: 'count', + params: {}, + }) + ); + }); + + const field = dataView.fields[0].name; + const id = 'some-id'; + + test.each< + [ + string, + Parameters, + Partial | null + ] + >([ + [ + 'null for percentile if metaValue is empty', + [ + SUPPORTED_METRICS.percentile, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, + ], + null, + ], + [ + 'percentile column for percentile if metaValue is set', + [ + SUPPORTED_METRICS.percentile, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, + { metaValue: 50 }, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'percentile', + params: { format: { id: 'bytes' }, percentile: 50 }, + }, + ], + [ + 'percentile column for percentile if metaValue is set and window is passed', + [ + SUPPORTED_METRICS.percentile, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, + { metaValue: 50, window: '10' }, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'percentile', + params: { format: { id: 'bytes' }, percentile: 50 }, + window: '10', + }, + ], + [ + 'null for percentile rank if metaValue is empty', + [ + SUPPORTED_METRICS.percentile_rank, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE_RANK }, dataView }, + ], + null, + ], + [ + 'percentile rank column for percentile rank if metaValue is set', + [ + SUPPORTED_METRICS.percentile_rank, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE_RANK }, dataView }, + { metaValue: 50 }, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'percentile_rank', + params: { format: { id: 'bytes' }, value: 50 }, + }, + ], + [ + 'percentile rank column for percentile rank if metaValue is set and window is passed', + [ + SUPPORTED_METRICS.percentile_rank, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE_RANK }, dataView }, + { metaValue: 50, window: '10' }, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'percentile_rank', + params: { format: { id: 'bytes' }, value: 50 }, + window: '10', + }, + ], + [ + 'null for counter rate if field in metric is empty', + [ + SUPPORTED_METRICS.positive_rate, + { series, metric: { id, type: TSVB_METRIC_TYPES.POSITIVE_RATE }, dataView }, + ], + null, + ], + [ + 'formula column for counter rate', + [ + SUPPORTED_METRICS.positive_rate, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.POSITIVE_RATE }, dataView }, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { format: { id: 'bytes' }, formula: 'pick_max(differences(max(bytes)), 0)' }, + }, + ], + [ + 'null for last value (unsupported)', + [ + SUPPORTED_METRICS.top_hit, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.TOP_HIT }, dataView }, + ], + null, + ], + [ + 'column for other supported metrics', + [ + SUPPORTED_METRICS.count, + { series, metric: { id, field, type: METRIC_TYPES.COUNT }, dataView }, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'count', + params: {}, + sourceField: 'document', + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertMetricAggregationToColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertMetricAggregationToColumn(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertMetricAggregationToColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index f4ab97919ac89..4dad18d36ce9d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -7,7 +7,6 @@ */ import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import type { DataView } from '@kbn/data-views-plugin/common'; import { Operations } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { AvgColumn, @@ -28,7 +27,7 @@ import { FormulaColumn, } from './types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; -import { Metric, Series } from '../../../../common/types'; +import { Metric } from '../../../../common/types'; import { getFilterRatioFormula, getFormulaFromMetric, @@ -74,7 +73,7 @@ type MetricAggregationColumnWithoutSpecialParams = | MinColumn | SumColumn; -type MetricAggregationColumn = +export type MetricAggregationColumn = | MetricAggregationColumnWithoutSpecialParams | MetricAggregationColumnWithSpecialParams; @@ -139,9 +138,7 @@ export const convertMetricAggregationColumnWithoutSpecialParams = ( export const convertMetricAggregationToColumn = ( aggregation: SupportedMetric, - series: Series, - metric: Metric, - dataView: DataView, + { series, metric, dataView }: CommonColumnConverterArgs, { metaValue, window }: { metaValue?: number; window?: string } = {} ): MetricAggregationColumn | null => { if (!isSupportedAggregation(aggregation.name)) { @@ -149,7 +146,7 @@ export const convertMetricAggregationToColumn = ( } const field = dataView.getFieldByName(metric.field ?? 'document'); - if (!field) { + if (!field && aggregation.isFieldRequired) { return null; } @@ -158,7 +155,7 @@ export const convertMetricAggregationToColumn = ( } if (aggregation.name === Operations.PERCENTILE_RANK) { - return convertToPercentileRankColumn(metaValue?.toString() ?? '', series, metric, dataView, { + return convertToPercentileRankColumn(metaValue?.toString(), series, metric, dataView, { window, }); } @@ -202,9 +199,7 @@ export const computeParentPipelineColumns = ( const metricAggregationColumn = convertMetricAggregationToColumn( pipelineAgg, - series, - subFunctionMetric, - dataView, + { series, metric: subFunctionMetric, dataView }, { metaValue, window } ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index 9cb8c097b0a0a..e60c450d61163 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -26,7 +26,7 @@ export const isPercentileRanksColumnWithMeta = ( column.operationType === Operations.PERCENTILE_RANK && Boolean((column as PercentileRanksColumnWithExtendedMeta).meta?.reference); -export const convertToPercentileRankParams = (value: string): PercentileRanksParams | null => +export const convertToPercentileRankParams = (value?: string): PercentileRanksParams | null => value !== undefined && !isNaN(Number(value)) ? { value: Number(value), @@ -34,7 +34,7 @@ export const convertToPercentileRankParams = (value: string): PercentileRanksPar : null; export const convertToPercentileRankColumn = ( - value: string, + value: string | undefined, series: Series, metric: Metric, dataView: DataView, From 7401851e2a1988d5a67f90b224a6207a0b569432 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 15:30:09 +0300 Subject: [PATCH 086/129] Added tests for computeParentPipelineColumns --- .../lib/convert/parent_pipeline.test.ts | 141 +++++++++++++++++- .../lib/convert/parent_pipeline.ts | 6 +- 2 files changed, 141 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index c832ff79b33fe..84df2f196734b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -10,14 +10,17 @@ import { createSeries } from '../__mocks__'; import { MetricType } from '../../../../common/types'; import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; import { + computeParentPipelineColumns, convertMetricAggregationColumnWithoutSpecialParams, convertMetricAggregationToColumn, MetricAggregationColumn, + ParentPipelineAggColumn, } from './parent_pipeline'; import { SupportedMetric, SUPPORTED_METRICS } from '../metrics'; -import { ColumnWithMeta } from './types'; +import { ColumnWithMeta, FormulaColumn } from './types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { Operations } from '@kbn/visualizations-plugin/common'; describe('convertMetricAggregationColumnWithoutSpecialParams', () => { const dataView = stubLogstashDataView; @@ -317,3 +320,139 @@ describe('convertMetricAggregationToColumn', () => { } }); }); + +describe('computeParentPipelineColumns', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const field = dataView.fields[0].name; + const field2 = dataView.fields[2].name; + const id = 'some-id'; + + test.each< + [ + string, + Parameters, + ( + | Partial + | Array | Partial> + | null + ) + ] + >([ + [ + 'null for percentile if metaValue is empty', + [ + Operations.MOVING_AVERAGE, + { series, metric: { id, field, type: METRIC_TYPES.MEDIAN }, dataView }, + { id, field: field2, type: TSVB_METRIC_TYPES.PERCENTILE }, + SUPPORTED_METRICS.avg, + ], + null, + ], + [ + 'formula column if sub metric is filter ratio', + [ + Operations.MOVING_AVERAGE, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, + { id, field: field2, type: TSVB_METRIC_TYPES.FILTER_RATIO }, + SUPPORTED_METRICS.avg, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { format: { id: 'bytes' }, formula: "percentile(count(kql='*') / count(kql='*'))" }, + }, + ], + [ + 'null if sub metric is filter ratio and metric_agg is set and not supported', + [ + Operations.MOVING_AVERAGE, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, + { + id, + field: field2, + type: TSVB_METRIC_TYPES.FILTER_RATIO, + metric_agg: METRIC_TYPES.MEDIAN, + }, + SUPPORTED_METRICS.avg, + ], + null, + ], + [ + 'formula column if sub metric is filter ratio and metric_agg is set', + [ + Operations.MOVING_AVERAGE, + { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, + { id, field, type: TSVB_METRIC_TYPES.FILTER_RATIO, metric_agg: METRIC_TYPES.AVG }, + SUPPORTED_METRICS.avg, + ], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { + format: { id: 'bytes' }, + formula: "percentile(average('bytes',kql='*') / average('bytes',kql='*'))", + }, + }, + ], + [ + 'null if pipeline aggregation is not supported', + [ + Operations.MOVING_AVERAGE, + { series, metric: { id, field, type: METRIC_TYPES.AVG }, dataView }, + { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, + SUPPORTED_METRICS.avg_bucket, + ], + null, + ], + [ + 'metric aggregation column if pipeline aggregation is supported', + [ + Operations.MOVING_AVERAGE, + { series, metric: { id, field, type: METRIC_TYPES.AVG }, dataView }, + { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, + SUPPORTED_METRICS.avg, + ], + [ + { + meta: { metricId: 'some-id' }, + operationType: 'average', + params: { format: { id: 'bytes' } }, + sourceField: 'bytes', + }, + { + meta: { metricId: 'some-id' }, + operationType: 'moving_average', + params: { window: 0 }, + }, + ], + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(computeParentPipelineColumns(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(computeParentPipelineColumns(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(computeParentPipelineColumns(...input)).toEqual(expect.objectContaining(expected)); + } + }); + + test('pipeline aggregation columns with correct references', () => { + const result = computeParentPipelineColumns( + Operations.MOVING_AVERAGE, + { series, metric: { id, field, type: METRIC_TYPES.AVG }, dataView }, + { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, + SUPPORTED_METRICS.avg + ); + expect(result).not.toBeNull(); + + expect(Array.isArray(result)).toBeTruthy(); + + const [metricColumn, parentPipelineColumn] = result as [ + MetricAggregationColumn, + ParentPipelineAggColumn + ]; + expect(parentPipelineColumn.references).toContain(metricColumn.columnId); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 4dad18d36ce9d..9b044d6592143 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -82,7 +82,7 @@ type ParentPipelineAggregation = | typeof Operations.DIFFERENCES | typeof Operations.CUMULATIVE_SUM; -type ParentPipelineAggColumn = MovingAverageColumn | DerivativeColumn | CumulativeSumColumn; +export type ParentPipelineAggColumn = MovingAverageColumn | DerivativeColumn | CumulativeSumColumn; const SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS: MetricAggregationWithoutParams[] = [ Operations.AVERAGE, @@ -293,10 +293,6 @@ export const createParentPipelineAggregationColumn = ( ? convertToMovingAverageParams(metric) : getFormat(series, metric.field, dataView); - if (params === null) { - return null; - } - return { operationType: aggregation, references, From 46084673e03bb7b0a0bef7f8abd4b953db31d4e5 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 15:47:21 +0300 Subject: [PATCH 087/129] Added tests for convertParentPipelineAggToColumns --- .../lib/convert/parent_pipeline.test.ts | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index 84df2f196734b..d01e6a60c9f1e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -13,6 +13,7 @@ import { computeParentPipelineColumns, convertMetricAggregationColumnWithoutSpecialParams, convertMetricAggregationToColumn, + convertParentPipelineAggToColumns, MetricAggregationColumn, ParentPipelineAggColumn, } from './parent_pipeline'; @@ -456,3 +457,96 @@ describe('computeParentPipelineColumns', () => { expect(parentPipelineColumn.references).toContain(metricColumn.columnId); }); }); + +describe('convertParentPipelineAggToColumns', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const field = dataView.fields[0].name; + const id = 'some-id'; + const id1 = 'some-id-1'; + const id2 = 'some-id-2'; + + test.each< + [ + string, + Parameters, + ( + | Partial + | Array | Partial> + | null + ) + ] + >([ + [ + 'null for metric which is not moving_average or derivative', + [{ series, metrics: [{ id, field, type: TSVB_METRIC_TYPES.POSITIVE_ONLY }], dataView }], + null, + ], + [ + 'column for moving_average', + [ + { + series, + metrics: [ + { id, field, type: METRIC_TYPES.MAX }, + { id: id1, field: `${id}[75]`, type: METRIC_TYPES.AVG }, + { id: id2, field: `${id1}[50]`, type: TSVB_METRIC_TYPES.MOVING_AVERAGE }, + ], + dataView, + }, + ], + { + meta: { metricId: 'some-id-2' }, + operationType: 'formula', + params: { formula: 'moving_average(average(max(bytes)))' }, + }, + ], + [ + 'column for derivative', + [ + { + series, + metrics: [ + { id, field, type: METRIC_TYPES.MAX }, + { id: id1, field: `${id}[75]`, type: METRIC_TYPES.AVG }, + { id: id2, field: `${id1}[50]`, type: METRIC_TYPES.DERIVATIVE }, + ], + dataView, + }, + ], + { + meta: { metricId: 'some-id-2' }, + operationType: 'formula', + params: { formula: 'differences(average(max(bytes)))' }, + }, + ], + [ + 'null for static sub metric (unsupported)', + [ + { + series, + metrics: [ + { id, field, type: METRIC_TYPES.MAX }, + { id: id1, field: `${id}[75]`, type: TSVB_METRIC_TYPES.STATIC }, + { id: id2, field: `${id1}[50]`, type: METRIC_TYPES.DERIVATIVE }, + ], + dataView, + }, + ], + null, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertParentPipelineAggToColumns(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertParentPipelineAggToColumns(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertParentPipelineAggToColumns(...input)).toEqual( + expect.objectContaining(expected) + ); + } + }); +}); From 588d9838fe50264a41077ef4cc76c2c1a6be99a8 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 29 Aug 2022 15:48:07 +0300 Subject: [PATCH 088/129] Add tests for getParentPipelineSeriesFormula --- .../metrics/parent_pipeline_formula.test.ts | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.test.ts new file mode 100644 index 0000000000000..5949a60fa76a6 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.test.ts @@ -0,0 +1,180 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import type { Metric, MetricType } from '../../../../common/types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; +import { SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; + +describe('getParentPipelineSeriesFormula', () => { + const metrics: Metric[] = [ + { + id: 'test-1', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: 'test-1', + }, + ]; + + const metricsWithNotSupportedSubFunction: Metric[] = [ + { + id: 'test-2', + type: METRIC_TYPES.MEDIAN, + field: 'test-field-1', + }, + { + id: 'test-1', + type: METRIC_TYPES.DERIVATIVE, + field: 'test-2', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: 'test-1', + }, + ]; + + const metricsWithSubFunction: Metric[] = [ + { + id: 'test-2', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'test-1', + type: METRIC_TYPES.DERIVATIVE, + field: 'test-2', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: 'test-1', + }, + ]; + + const metricsWithPercentileSubFunction: Metric[] = [ + { + id: 'test-2', + type: TSVB_METRIC_TYPES.PERCENTILE, + field: 'test-field-1', + }, + { + id: 'test-1', + type: METRIC_TYPES.DERIVATIVE, + field: 'test-2[50]', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: 'test-1', + }, + ]; + + const metricsWithPercentileRankSubFunction: Metric[] = [ + { + id: 'test-2', + type: TSVB_METRIC_TYPES.PERCENTILE_RANK, + field: 'test-field-1', + }, + { + id: 'test-1', + type: METRIC_TYPES.DERIVATIVE, + field: 'test-2[5]', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: 'test-1', + }, + ]; + + test.each< + [ + string, + [Metric[], Metric, SupportedMetric, MetricType, { metaValue?: number; window?: string }], + string | null + ] + >([ + [ + 'null if metric is not supported', + [ + metrics, + metrics[0], + SUPPORTED_METRICS[metrics[0].type]!, + TSVB_METRIC_TYPES.SUM_OF_SQUARES_BUCKET, + {}, + ], + null, + ], + [ + 'null if metric have not supported additional sub function', + [ + metricsWithNotSupportedSubFunction, + metricsWithNotSupportedSubFunction[1], + SUPPORTED_METRICS[metricsWithNotSupportedSubFunction[1].type]!, + TSVB_METRIC_TYPES.MOVING_AVERAGE, + {}, + ], + null, + ], + [ + 'correct formula if metric is supported', + [ + metrics, + metrics[0], + SUPPORTED_METRICS[metrics[0].type]!, + TSVB_METRIC_TYPES.MOVING_AVERAGE, + {}, + ], + 'moving_average(average(test-field-1))', + ], + [ + 'correct formula if metric have additional sub function', + [ + metricsWithSubFunction, + metricsWithSubFunction[1], + SUPPORTED_METRICS[metricsWithSubFunction[1].type]!, + TSVB_METRIC_TYPES.MOVING_AVERAGE, + {}, + ], + 'moving_average(differences(average(test-field-1)))', + ], + [ + 'correct formula if metric have percentile additional sub function', + [ + metricsWithPercentileSubFunction, + metricsWithPercentileSubFunction[1], + SUPPORTED_METRICS[metricsWithPercentileSubFunction[1].type]!, + TSVB_METRIC_TYPES.MOVING_AVERAGE, + {}, + ], + 'moving_average(differences(percentile(test-field-1, percentile=50)))', + ], + [ + 'correct formula if metric have percentile rank additional sub function', + [ + metricsWithPercentileRankSubFunction, + metricsWithPercentileRankSubFunction[1], + SUPPORTED_METRICS[metricsWithPercentileRankSubFunction[1].type]!, + TSVB_METRIC_TYPES.MOVING_AVERAGE, + {}, + ], + 'moving_average(differences(percentile_rank(test-field-1, value=5)))', + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(getParentPipelineSeriesFormula(...input)).toBeNull(); + } + expect(getParentPipelineSeriesFormula(...input)).toEqual(expected); + }); +}); From 538bb05102df406c04cdb3f222ece06d8c669fad Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 16:02:41 +0300 Subject: [PATCH 089/129] Added tests for createParentPipelineAggregationColumn --- .../lib/convert/parent_pipeline.test.ts | 114 +++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index d01e6a60c9f1e..b198c2920dcf1 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -7,13 +7,14 @@ */ import { createSeries } from '../__mocks__'; -import { MetricType } from '../../../../common/types'; +import { Metric, MetricType } from '../../../../common/types'; import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; import { computeParentPipelineColumns, convertMetricAggregationColumnWithoutSpecialParams, convertMetricAggregationToColumn, convertParentPipelineAggToColumns, + createParentPipelineAggregationColumn, MetricAggregationColumn, ParentPipelineAggColumn, } from './parent_pipeline'; @@ -550,3 +551,114 @@ describe('convertParentPipelineAggToColumns', () => { } }); }); + +describe('createParentPipelineAggregationColumn', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + const movingAvgMetric: Metric = { + id: 'some-id-0', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: dataView.fields[0].name, + }; + + const cumulativeSumMetric: Metric = { + id: 'some-id-0', + type: METRIC_TYPES.CUMULATIVE_SUM, + field: dataView.fields[0].name, + }; + + const derivativeMetric: Metric = { + id: 'some-id-0', + type: METRIC_TYPES.DERIVATIVE, + field: dataView.fields[0].name, + }; + + test.each< + [ + string, + Parameters, + Partial + ] + >([ + [ + 'moving average column', + [ + Operations.MOVING_AVERAGE, + { + series, + metric: movingAvgMetric, + dataView, + }, + ], + { + meta: { metricId: 'some-id-0' }, + operationType: 'moving_average', + params: { window: 0 }, + }, + ], + [ + 'moving average column with window', + [ + Operations.MOVING_AVERAGE, + { + series, + metric: { + ...movingAvgMetric, + window: 10, + }, + dataView, + }, + ], + { + meta: { metricId: 'some-id-0' }, + operationType: 'moving_average', + params: { window: 10 }, + }, + ], + [ + 'cumulative sum column', + [ + Operations.CUMULATIVE_SUM, + { + series, + metric: cumulativeSumMetric, + dataView, + }, + ], + { + meta: { metricId: 'some-id-0' }, + operationType: 'cumulative_sum', + params: { format: { id: 'bytes' } }, + }, + ], + [ + 'derivative column', + [ + Operations.DIFFERENCES, + { + series, + metric: derivativeMetric, + dataView, + }, + ], + { + meta: { metricId: 'some-id-0' }, + operationType: 'differences', + params: { format: { id: 'bytes' } }, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(createParentPipelineAggregationColumn(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(createParentPipelineAggregationColumn(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(createParentPipelineAggregationColumn(...input)).toEqual( + expect.objectContaining(expected) + ); + } + }); +}); From 28022a618dc0526be487a5e6e9d1145d810f7e6e Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 16:17:06 +0300 Subject: [PATCH 090/129] Added tests for isPercentileRanksColumnWithMeta --- .../lib/convert/percentile_rank.test.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts new file mode 100644 index 0000000000000..2a9d9c73e52bc --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -0,0 +1,38 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Operations } from '@kbn/visualizations-plugin/common'; +import { isPercentileRanksColumnWithMeta } from './percentile_rank'; +import { PercentileRanksColumn, PercentileRanksColumnWithExtendedMeta } from './types'; + +describe('isPercentileRanksColumnWithMeta', () => { + const percentileRankColumnWithoutMeta = { + columnId: 'col', + sourceField: 'some-field', + operationType: Operations.PERCENTILE_RANK, + isBucketed: false, + isSplit: false, + dataType: 'number', + params: { + value: 50, + }, + meta: { metricId: 'someId' }, + } as PercentileRanksColumn; + + const percentileRankColumn: PercentileRanksColumnWithExtendedMeta = { + ...percentileRankColumnWithoutMeta, + meta: { ...percentileRankColumnWithoutMeta.meta, reference: 'some-ref.0' }, + }; + + test.each<[string, Parameters, boolean]>([ + ["false if meta doesn't contain reference", [percentileRankColumnWithoutMeta], false], + ['true if meta contains reference', [percentileRankColumn], true], + ])('should return %s', (_, input, expected) => { + expect(isPercentileRanksColumnWithMeta(...input)).toBe(expected); + }); +}); From 615eb74bf716e3b8d9c37cc8930a68931de16ee8 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 16:21:52 +0300 Subject: [PATCH 091/129] Added tests for convertToPercentileRankParams --- .../lib/convert/percentile_rank.test.ts | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts index 2a9d9c73e52bc..8c12a8f9f2884 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { Operations } from '@kbn/visualizations-plugin/common'; -import { isPercentileRanksColumnWithMeta } from './percentile_rank'; +import { Operations, PercentileRanksParams } from '@kbn/visualizations-plugin/common'; +import { convertToPercentileRankParams, isPercentileRanksColumnWithMeta } from './percentile_rank'; import { PercentileRanksColumn, PercentileRanksColumnWithExtendedMeta } from './types'; describe('isPercentileRanksColumnWithMeta', () => { @@ -36,3 +36,24 @@ describe('isPercentileRanksColumnWithMeta', () => { expect(isPercentileRanksColumnWithMeta(...input)).toBe(expected); }); }); + +describe('convertToPercentileRankParams', () => { + test.each< + [string, Parameters, PercentileRanksParams | null] + >([ + ['null if value is undefined', [undefined], null], + ['null if value is NaN', ['some-nan-value'], null], + ['percentile ranks params if value is present and valid', ['100'], { value: 100 }], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToPercentileRankParams(...input)).toBeNull(); + } + if (Array.isArray(expected)) { + expect(convertToPercentileRankParams(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertToPercentileRankParams(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From 73352023f61c39189b1f817b9c642a52b71955a1 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 29 Aug 2022 16:22:49 +0300 Subject: [PATCH 092/129] Update and add tests for getSiblingPipelineSeriesFormula --- .../lib/metrics/parent_pipeline_formula.ts | 4 + .../metrics/sibling_pipeline_formula.test.ts | 168 ++++++++++-------- 2 files changed, 101 insertions(+), 71 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index fe3706570f11d..cde9104e7e9c8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -22,6 +22,10 @@ export const getParentPipelineSeriesFormula = ( if (!aggregationMap) { return null; } + if (subFunctionMetric.type === 'static') { + return null; + } + const aggFormula = getFormulaFromMetric(aggregationMap); const pipelineFormula = getFormulaFromMetric(pipelineAgg); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts index c251f72c84a9f..15c1df306c05a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts @@ -7,82 +7,108 @@ */ import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import type { Metric } from '../../../../common/types'; +import type { Metric, MetricType } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; describe('getSiblingPipelineSeriesFormula', () => { - test('should return correct formula for sibling pipeline agg on positive only', () => { - const metrics = [ - { - field: 'day_of_week_i', - id: '123456', - type: 'max', - }, - { - id: '891011', - type: 'positive_only', - field: '123456', - }, - ] as Metric[]; - const formula = getSiblingPipelineSeriesFormula( - TSVB_METRIC_TYPES.POSITIVE_ONLY, - metrics[1], - metrics - ); - expect(formula).toStrictEqual('pick_max(max(day_of_week_i), 0)'); - }); + const metrics: Metric[] = [ + { + id: 'test-1', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'some-random-value', + type: METRIC_TYPES.AVG_BUCKET, + field: 'test-1', + }, + ]; - test('should return correct config for sibling pipeline agg on percentile ranks', () => { - const metrics = [ - { - field: 'AvgTicketPrice', - id: '04558549-f19f-4a87-9923-27df8b81af3e', - values: ['400', '500', '700'], - colors: ['rgba(211,96,134,1)', 'rgba(155,33,230,1)', '#68BC00'], - type: 'percentile_rank', - }, - { - field: '04558549-f19f-4a87-9923-27df8b81af3e[400.0]', - id: '764f4110-7db9-11ec-9fdf-91a8881dd06b', - type: 'avg_bucket', - }, - ] as Metric[]; - const formula = getSiblingPipelineSeriesFormula(METRIC_TYPES.AVG_BUCKET, metrics[1], metrics); - expect(formula).toStrictEqual('overall_average(percentile_rank(AvgTicketPrice, value=400))'); - }); + const positiveOnlyMetrics: Metric[] = [ + { + id: 'test-1', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.POSITIVE_ONLY, + field: 'test-1', + }, + ]; + + const metricsWithNotSupportedSubFunction: Metric[] = [ + { + id: 'test-2', + type: METRIC_TYPES.MEDIAN, + field: 'test-field-1', + }, + { + id: 'test-1', + type: METRIC_TYPES.SUM_BUCKET, + field: 'test-2', + }, + { + id: 'some-random-value', + type: METRIC_TYPES.AVG_BUCKET, + field: 'test-1', + }, + ]; + + const metricsWithSubFunction: Metric[] = [ + { + id: 'test-2', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'test-1', + type: METRIC_TYPES.SUM_BUCKET, + field: 'test-2', + }, + { + id: 'some-random-value', + type: METRIC_TYPES.AVG_BUCKET, + field: 'test-1', + }, + ]; - test('should return correct config for sibling pipeline agg on percentile', () => { - const metrics = [ - { - field: 'AvgTicketPrice', - id: '04558549-f19f-4a87-9923-27df8b81af3e', - percentiles: [ - { - color: '#68BC00', - id: 'aef159f0-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - shade: 0.2, - value: 50, - }, - { - color: 'rgba(0,63,188,1)', - id: 'b0e0a6d0-7db8-11ec-9d0c-e57521cec076', - mode: 'line', - percentile: '', - shade: 0.2, - value: '70', - }, - ], - type: 'percentile', - }, - { - field: '04558549-f19f-4a87-9923-27df8b81af3e[70.0]', - id: '764f4110-7db9-11ec-9fdf-91a8881dd06b', - type: 'avg_bucket', - }, - ] as Metric[]; - const formula = getSiblingPipelineSeriesFormula(METRIC_TYPES.AVG_BUCKET, metrics[1], metrics); - expect(formula).toStrictEqual('overall_average(percentile(AvgTicketPrice, percentile=70))'); + test.each<[string, [MetricType, Metric, Metric[], string | undefined], string | null]>([ + [ + 'null if metric is not supported', + [TSVB_METRIC_TYPES.SUM_OF_SQUARES_BUCKET, metrics[1], metrics, undefined], + null, + ], + [ + 'null if metric have not supported additional sub function', + [ + METRIC_TYPES.AVG_BUCKET, + metricsWithNotSupportedSubFunction[2], + metricsWithNotSupportedSubFunction, + undefined, + ], + null, + ], + [ + 'correct formula if metric is supported', + [METRIC_TYPES.AVG_BUCKET, metrics[1], metrics, undefined], + 'overall_average(average(test-field-1))', + ], + [ + 'correct formula if metric is positive only', + [TSVB_METRIC_TYPES.POSITIVE_ONLY, positiveOnlyMetrics[1], positiveOnlyMetrics, undefined], + 'pick_max(average(test-field-1), 0)', + ], + [ + 'correct formula if metric have additional sub function', + [METRIC_TYPES.AVG_BUCKET, metricsWithSubFunction[2], metricsWithSubFunction, undefined], + 'overall_average(overall_sum(average(test-field-1)))', + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(getSiblingPipelineSeriesFormula(...input)).toBeNull(); + } + expect(getSiblingPipelineSeriesFormula(...input)).toEqual(expected); }); }); From 70504fd299a29d63372d6246cb772df004b960d1 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 16:24:52 +0300 Subject: [PATCH 093/129] Fixed tests. --- .../lib/convert/cumulative_sum.test.ts | 3 +-- .../lib/convert/date_histogram.test.ts | 6 ++---- .../convert_to_lens/lib/convert/filter_ratio.test.ts | 3 +-- .../convert_to_lens/lib/convert/filters.test.ts | 6 ++---- .../convert_to_lens/lib/convert/formula.test.ts | 9 +++------ .../convert_to_lens/lib/convert/last_value.test.ts | 3 +-- .../lib/convert/parent_pipeline.test.ts | 12 ++++-------- .../lib/convert/percentile_rank.test.ts | 3 +-- 8 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts index fc724dcd69b1f..9d37f02da161d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts @@ -208,8 +208,7 @@ describe('convertToCumulativeSumColumns', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertToCumulativeSumColumns(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertToCumulativeSumColumns(...input)).toEqual( expected.map(expect.objectContaining) ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.ts index 1c90018a715ab..f2220b58cdb6b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.test.ts @@ -53,8 +53,7 @@ describe('convertToDateHistogramParams', () => { ])('should return date histogram params %s', (_, input, expected) => { if (expected === null) { expect(convertToDateHistogramParams(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertToDateHistogramParams(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(convertToDateHistogramParams(...input)).toEqual(expect.objectContaining(expected)); @@ -121,8 +120,7 @@ describe('convertToDateHistogramColumn', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertToDateHistogramColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertToDateHistogramColumn(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(convertToDateHistogramColumn(...input)).toEqual(expect.objectContaining(expected)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts index 40014bef0b1f5..febeaed6041f0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts @@ -65,8 +65,7 @@ describe('convertFilterRatioToFormulaColumn', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertFilterRatioToFormulaColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertFilterRatioToFormulaColumn(...input)).toEqual( expected.map(expect.objectContaining) ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts index d01e9fd88a345..b98c977188ba8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filters.test.ts @@ -62,8 +62,7 @@ describe('convertToFiltersParams', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertToFiltersParams(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertToFiltersParams(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(convertToFiltersParams(...input)).toEqual(expect.objectContaining(expected)); @@ -120,8 +119,7 @@ describe('convertToFiltersColumn', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertToFiltersColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertToFiltersColumn(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(convertToFiltersColumn(...input)).toEqual(expect.objectContaining(expected)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts index 58620606e5b4e..6324d891f3c80 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts @@ -117,8 +117,7 @@ describe('createFormulaColumn', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(createFormulaColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(createFormulaColumn(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(createFormulaColumn(...input)).toEqual(expect.objectContaining(expected)); @@ -301,8 +300,7 @@ describe('convertMathToFormulaColumn', () => { )('should return %s', (_, input, expected) => { if (expected === null) { expect(convertMathToFormulaColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertMathToFormulaColumn(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(convertMathToFormulaColumn(...input)).toEqual(expect.objectContaining(expected)); @@ -376,8 +374,7 @@ describe('convertOtherAggsToFormulaColumn', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertOtherAggsToFormulaColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertOtherAggsToFormulaColumn(...input)).toEqual( expected.map(expect.objectContaining) ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts index 59de79679f9db..665cb9ff3d58b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts @@ -93,8 +93,7 @@ describe('convertToLastValueColumn', () => { )('should return %s', (_, input, expected) => { if (expected === null) { expect(convertToLastValueColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertToLastValueColumn(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(convertToLastValueColumn(...input)).toEqual(expect.objectContaining(expected)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index b198c2920dcf1..2b31555a8676e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -312,8 +312,7 @@ describe('convertMetricAggregationToColumn', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertMetricAggregationToColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertMetricAggregationToColumn(...input)).toEqual( expected.map(expect.objectContaining) ); @@ -432,8 +431,7 @@ describe('computeParentPipelineColumns', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(computeParentPipelineColumns(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(computeParentPipelineColumns(...input)).toEqual(expected.map(expect.objectContaining)); } else { expect(computeParentPipelineColumns(...input)).toEqual(expect.objectContaining(expected)); @@ -539,8 +537,7 @@ describe('convertParentPipelineAggToColumns', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertParentPipelineAggToColumns(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertParentPipelineAggToColumns(...input)).toEqual( expected.map(expect.objectContaining) ); @@ -650,8 +647,7 @@ describe('createParentPipelineAggregationColumn', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(createParentPipelineAggregationColumn(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(createParentPipelineAggregationColumn(...input)).toEqual( expected.map(expect.objectContaining) ); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts index 8c12a8f9f2884..73740b028f849 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -47,8 +47,7 @@ describe('convertToPercentileRankParams', () => { ])('should return %s', (_, input, expected) => { if (expected === null) { expect(convertToPercentileRankParams(...input)).toBeNull(); - } - if (Array.isArray(expected)) { + } else if (Array.isArray(expected)) { expect(convertToPercentileRankParams(...input)).toEqual( expected.map(expect.objectContaining) ); From fedee6d985eedc7c856d182e4bb295cfc2988449 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 16:37:58 +0300 Subject: [PATCH 094/129] Added tests for convertToPercentileRankColumn. --- .../lib/convert/percentile_rank.test.ts | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts index 73740b028f849..f30675bd16a71 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -6,9 +6,21 @@ * Side Public License, v 1. */ +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; import { Operations, PercentileRanksParams } from '@kbn/visualizations-plugin/common'; -import { convertToPercentileRankParams, isPercentileRanksColumnWithMeta } from './percentile_rank'; -import { PercentileRanksColumn, PercentileRanksColumnWithExtendedMeta } from './types'; +import { createSeries } from '../__mocks__'; +import { Metric } from '../../../../common/types'; +import { + convertToPercentileRankColumn, + convertToPercentileRankParams, + isPercentileRanksColumnWithMeta, +} from './percentile_rank'; +import { + PercentileRanksColumn, + PercentileRanksColumnWithCommonMeta, + PercentileRanksColumnWithExtendedMeta, +} from './types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; describe('isPercentileRanksColumnWithMeta', () => { const percentileRankColumnWithoutMeta = { @@ -56,3 +68,74 @@ describe('convertToPercentileRankParams', () => { } }); }); + +describe('convertToPercentileRankColumn', () => { + const series = createSeries(); + const dataView = stubLogstashDataView; + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.PERCENTILE_RANK, + }; + test.each< + [ + string, + Parameters, + ( + | Partial + | Partial + | null + ) + ] + >([ + ['null if value is undefined', [undefined, series, metric, dataView], null], + ['null if value is NaN', ['some-nan-value', series, metric, dataView], null], + ['null if field is not present', ['50', series, metric, dataView], null], + [ + 'precentile rank column', + ['50', series, { ...metric, field: dataView.fields[0].name }, dataView], + { + meta: { metricId: 'some-id' }, + operationType: 'percentile_rank', + params: { format: { id: 'bytes' }, value: 50 }, + sourceField: 'bytes', + } as Partial, + ], + [ + 'precentile rank column with reference in meta', + ['50', series, { ...metric, field: dataView.fields[0].name }, dataView, { index: 0 }], + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile_rank', + params: { format: { id: 'bytes' }, value: 50 }, + sourceField: 'bytes', + } as Partial, + ], + [ + 'precentile rank column with reference in meta and window', + [ + '50', + series, + { ...metric, field: dataView.fields[0].name }, + dataView, + { index: 0, window: '10' }, + ], + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile_rank', + params: { format: { id: 'bytes' }, value: 50 }, + sourceField: 'bytes', + window: '10', + } as Partial, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToPercentileRankColumn(...input)).toBeNull(); + } else if (Array.isArray(expected)) { + expect(convertToPercentileRankColumn(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertToPercentileRankColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From 1fd32b8f24b39e5e9b05a5949fe6b6fbc0724a7b Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 16:51:19 +0300 Subject: [PATCH 095/129] Added tests for convertToPercentileRankColumns. --- .../lib/convert/percentile_rank.test.ts | 67 +++++++++++++++++++ .../common/convert_to_lens/types/params.ts | 2 +- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts index f30675bd16a71..169847d3c9d17 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -12,6 +12,7 @@ import { createSeries } from '../__mocks__'; import { Metric } from '../../../../common/types'; import { convertToPercentileRankColumn, + convertToPercentileRankColumns, convertToPercentileRankParams, isPercentileRanksColumnWithMeta, } from './percentile_rank'; @@ -139,3 +140,69 @@ describe('convertToPercentileRankColumn', () => { } }); }); + +describe('convertToPercentileRankColumns', () => { + const series = createSeries(); + const dataView = stubLogstashDataView; + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.PERCENTILE_RANK, + }; + test.each< + [ + string, + Parameters, + Array | null> | null + ] + >([ + ['null if values arr is empty', [{ series, metric, dataView }], null], + [ + 'array with null if values arr contains empty value', + [{ series, metric: { ...metric, values: [undefined as unknown as string] }, dataView }], + [null], + ], + [ + 'array with null if values arr contains NaN value', + [{ series, metric: { ...metric, values: ['unvalid value'] }, dataView }], + [null], + ], + [ + 'percentile rank columns', + [{ series, metric: { ...metric, field: dataView.fields[0].name, values: ['75'] }, dataView }], + [ + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile_rank', + params: { format: { id: 'bytes' }, value: 75 }, + sourceField: 'bytes', + }, + ], + ], + [ + 'percentile rank columns with window', + [ + { series, metric: { ...metric, field: dataView.fields[0].name, values: ['75'] }, dataView }, + '50', + ], + [ + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile_rank', + params: { format: { id: 'bytes' }, value: 75 }, + sourceField: 'bytes', + window: '50', + }, + ], + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToPercentileRankColumns(...input)).toBeNull(); + } else if (Array.isArray(expected)) { + expect(convertToPercentileRankColumns(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertToPercentileRankColumns(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); diff --git a/src/plugins/visualizations/common/convert_to_lens/types/params.ts b/src/plugins/visualizations/common/convert_to_lens/types/params.ts index 05375a99619d6..6fc49d30fe02e 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/params.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/params.ts @@ -74,7 +74,7 @@ export interface PercentileParams extends FormatParams { percentile: number; } -export interface PercentileRanksParams { +export interface PercentileRanksParams extends FormatParams { value: number; } From a99a96c3a54b8c791c4c490215683df728233e25 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 17:12:05 +0300 Subject: [PATCH 096/129] Added tests for percentile. --- .../lib/convert/percentile.test.ts | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts new file mode 100644 index 0000000000000..0e20210ab7a5a --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts @@ -0,0 +1,231 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { Operations, PercentileParams } from '@kbn/visualizations-plugin/common'; +import { createSeries } from '../__mocks__'; +import { Metric } from '../../../../common/types'; +import { + convertToPercentileColumn, + convertToPercentileColumns, + convertToPercentileParams, + isPercentileColumnWithMeta, +} from './percentile'; +import { + PercentileColumn, + PercentileColumnWithCommonMeta, + PercentileColumnWithExtendedMeta, +} from './types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; + +describe('isPercentileColumnWithMeta', () => { + const percentileColumnWithoutMeta = { + columnId: 'col', + sourceField: 'some-field', + operationType: Operations.PERCENTILE, + isBucketed: false, + isSplit: false, + dataType: 'number', + params: { + percentile: 50, + }, + meta: { metricId: 'someId' }, + } as PercentileColumn; + + const percentileRankColumn: PercentileColumnWithExtendedMeta = { + ...percentileColumnWithoutMeta, + meta: { ...percentileColumnWithoutMeta.meta, reference: 'some-ref.0' }, + }; + + test.each<[string, Parameters, boolean]>([ + ["false if meta doesn't contain reference", [percentileColumnWithoutMeta], false], + ['true if meta contains reference', [percentileRankColumn], true], + ])('should return %s', (_, input, expected) => { + expect(isPercentileColumnWithMeta(...input)).toBe(expected); + }); +}); + +describe('convertToPercentileParams', () => { + test.each<[string, Parameters, PercentileParams | null]>([ + ['null if value is undefined', [undefined], null], + ['null if value is NaN', ['some-nan-value'], null], + ['percentile params if value is present and valid', ['100'], { percentile: 100 }], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToPercentileParams(...input)).toBeNull(); + } else if (Array.isArray(expected)) { + expect(convertToPercentileParams(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToPercentileParams(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); + +describe('convertToPercentileColumn', () => { + const series = createSeries(); + const dataView = stubLogstashDataView; + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.PERCENTILE, + }; + test.each< + [ + string, + Parameters, + Partial | Partial | null + ] + >([ + ['null if value is undefined', [undefined, { series, metric, dataView }], null], + ['null if value is NaN', ['some-nan-value', { series, metric, dataView }], null], + ['null if field is not present', ['50', { series, metric, dataView }], null], + [ + 'precentile column', + ['50', { series, metric: { ...metric, field: dataView.fields[0].name }, dataView }], + { + meta: { metricId: 'some-id' }, + operationType: 'percentile', + params: { format: { id: 'bytes' }, percentile: 50 }, + sourceField: 'bytes', + } as Partial, + ], + [ + 'precentile column with reference in meta', + [ + '50', + { series, metric: { ...metric, field: dataView.fields[0].name }, dataView }, + { index: 0 }, + ], + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile', + params: { format: { id: 'bytes' }, percentile: 50 }, + sourceField: 'bytes', + } as Partial, + ], + [ + 'precentile column with reference in meta and window', + [ + '50', + { series, metric: { ...metric, field: dataView.fields[0].name }, dataView }, + { index: 0, window: '10' }, + ], + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile', + params: { format: { id: 'bytes' }, percentile: 50 }, + sourceField: 'bytes', + window: '10', + } as Partial, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToPercentileColumn(...input)).toBeNull(); + } else if (Array.isArray(expected)) { + expect(convertToPercentileColumn(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToPercentileColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); + +describe('convertToPercentileColumns', () => { + const series = createSeries(); + const dataView = stubLogstashDataView; + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.PERCENTILE, + }; + test.each< + [ + string, + Parameters, + Array | null> | null + ] + >([ + ['null if values arr is empty', [{ series, metric, dataView }], null], + [ + 'array with null if values arr contains empty value', + [ + { + series, + metric: { ...metric, percentiles: [{ id: 'some-id', mode: 'line', value: undefined }] }, + dataView, + }, + ], + [null], + ], + [ + 'array with null if values arr contains NaN value', + [ + { + series, + metric: { + ...metric, + percentiles: [{ id: 'some-id', mode: 'line', value: 'invalid value' }], + }, + dataView, + }, + ], + [null], + ], + [ + 'percentile columns', + [ + { + series, + metric: { + ...metric, + field: dataView.fields[0].name, + percentiles: [{ id: 'some-id', mode: 'line', value: '75' }], + }, + dataView, + }, + ], + [ + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile', + params: { format: { id: 'bytes' }, percentile: 75 }, + sourceField: 'bytes', + }, + ], + ], + [ + 'percentile columns with window', + [ + { + series, + metric: { + ...metric, + field: dataView.fields[0].name, + percentiles: [{ id: 'some-id', mode: 'line', value: '75' }], + }, + dataView, + }, + '50', + ], + [ + { + meta: { metricId: 'some-id', reference: 'some-id.0' }, + operationType: 'percentile', + params: { format: { id: 'bytes' }, percentile: 75 }, + sourceField: 'bytes', + window: '50', + }, + ], + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToPercentileColumns(...input)).toBeNull(); + } else if (Array.isArray(expected)) { + expect(convertToPercentileColumns(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(convertToPercentileColumns(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From 3a850e153a8eb31106e53a2332705c8856168315 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 17:27:21 +0300 Subject: [PATCH 097/129] Added tests for static_value. --- .../lib/convert/static_value.test.ts | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts new file mode 100644 index 0000000000000..f29ef3b3f0083 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts @@ -0,0 +1,76 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { StaticValueParams } from '@kbn/visualizations-plugin/common'; +import { createSeries } from '../__mocks__'; +import { Metric } from '../../../../common/types'; +import { StaticValueColumn } from './types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { convertToStaticValueColumn, convertToStaticValueParams } from './static_value'; + +describe('convertToStaticValueParams', () => { + test.each<[string, Parameters, StaticValueParams]>([ + [ + 'param with undefined value', + [{ id: 'some-id', type: TSVB_METRIC_TYPES.STATIC }], + { value: undefined }, + ], + [ + 'param with specified value', + [{ id: 'some-id', type: TSVB_METRIC_TYPES.STATIC, value: 'some value' }], + { value: 'some value' }, + ], + ])('should return %s', (_, input, expected) => { + expect(convertToStaticValueParams(...input)).toEqual(expect.objectContaining(expected)); + }); +}); + +describe('convertToStaticValueColumn', () => { + const series = createSeries(); + const dataView = stubLogstashDataView; + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.STATIC, + }; + + test.each< + [string, Parameters, Partial | null] + >([ + [ + 'null if visibleSeriesCount is equal to 1', + [{ series, metrics: [metric], dataView }, { visibleSeriesCount: 1 }], + null, + ], + [ + 'static value column', + [{ series, metrics: [{ ...metric, value: 'some value' }], dataView }], + { + meta: { metricId: 'some-id' }, + operationType: 'static_value', + params: { value: 'some value' }, + }, + ], + [ + 'static value column with window', + [{ series, metrics: [{ ...metric, value: 'some value' }], dataView }, { window: '100' }], + { + meta: { metricId: 'some-id' }, + operationType: 'static_value', + params: { value: 'some value' }, + window: '100', + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToStaticValueColumn(...input)).toBeNull(); + } else { + expect(convertToStaticValueColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From eb9fabffd00b8afeaa6a83b4b45b6e903b3d60f8 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 29 Aug 2022 17:29:03 +0300 Subject: [PATCH 098/129] Add tests for isValidMetrics --- .../lib/metrics/validate_metrics.test.ts | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.test.ts new file mode 100644 index 0000000000000..6164971b73f80 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/validate_metrics.test.ts @@ -0,0 +1,107 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import type { Metric } from '../../../../common/types'; +import { PANEL_TYPES, TSVB_METRIC_TYPES, TIME_RANGE_DATA_MODES } from '../../../../common/enums'; +import { isValidMetrics } from './validate_metrics'; + +describe('isValidMetrics', () => { + const supportedMetrics: Metric[] = [ + { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + field: 'test-1', + }, + { + id: 'some-random-value', + type: METRIC_TYPES.VALUE_COUNT, + field: 'test-2', + }, + ]; + + const notSupportedMetrics: Metric[] = [ + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.SUM_OF_SQUARES, + field: 'test-1', + }, + ]; + + const notSupportedMetricsForTopN: Metric[] = [ + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.MOVING_AVERAGE, + field: 'test-1', + }, + ]; + + const metricsWithoutField: Metric[] = [ + { + id: 'some-random-value', + type: METRIC_TYPES.AVG, + }, + ]; + + const filterRatioWithNotSupportedMetricAgg: Metric[] = [ + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.FILTER_RATIO, + metric_agg: TSVB_METRIC_TYPES.SUM_OF_SQUARES, + field: 'test-1', + }, + ]; + + const filterRatioWithoutField: Metric[] = [ + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.FILTER_RATIO, + metric_agg: METRIC_TYPES.AVG, + }, + ]; + + test.each<[string, [Metric[], PANEL_TYPES, string | undefined], boolean]>([ + [ + 'false if at least one metric type is not supported', + [notSupportedMetrics, PANEL_TYPES.TIMESERIES, undefined], + false, + ], + [ + 'false if at least one metric type is not supported for provided panel type', + [notSupportedMetricsForTopN, PANEL_TYPES.TOP_N, undefined], + false, + ], + [ + 'false if at least one metric type is not supported for provided time range mode', + [notSupportedMetricsForTopN, PANEL_TYPES.TIMESERIES, TIME_RANGE_DATA_MODES.LAST_VALUE], + false, + ], + [ + 'false if at least one metric which require field provided without field name', + [metricsWithoutField, PANEL_TYPES.TIMESERIES, undefined], + false, + ], + [ + 'false if at least one filter ratio has not supported metric agg', + [filterRatioWithNotSupportedMetricAgg, PANEL_TYPES.TIMESERIES, undefined], + false, + ], + [ + 'false if at least one filter ratio has not field for metric agg', + [filterRatioWithoutField, PANEL_TYPES.TIMESERIES, undefined], + false, + ], + [ + 'true if all metric is supported', + [supportedMetrics, PANEL_TYPES.TIMESERIES, undefined], + true, + ], + ])('should return %s', (_, input, expected) => { + expect(isValidMetrics(...input)).toBe(expected); + }); +}); From 55e57949b4829b5003efec1c01f83a5863a2d334 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 17:51:39 +0300 Subject: [PATCH 099/129] Added std_deviation tests. --- .../lib/convert/std_deviation.test.ts | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.ts new file mode 100644 index 0000000000000..2b43372ce7d5d --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { createSeries } from '../__mocks__'; +import { Metric } from '../../../../common/types'; +import { + AvgColumn, + CardinalityColumn, + CountColumn, + CounterRateColumn, + FormulaColumn, + MaxColumn, + MinColumn, + StandardDeviationColumn, + SumColumn, +} from './types'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { convertToStandartDeviationColumn } from './std_deviation'; + +describe('convertToStandartDeviationColumn', () => { + const series = createSeries(); + const dataView = stubLogstashDataView; + const metric: Metric = { + id: 'some-id', + type: TSVB_METRIC_TYPES.STD_DEVIATION, + }; + const field = dataView.fields[0].name; + + test.each< + [ + string, + Parameters, + Array | null> | null + ] + >([ + ['null if field is not provided', [{ series, metrics: [metric], dataView }], null], + [ + 'std deviation columns if mode = upper', + [{ series, metrics: [{ ...metric, mode: 'upper', field }], dataView }], + [ + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { + format: { id: 'bytes' }, + formula: 'average(bytes) + 1.5 * standard_deviation(bytes)', + }, + }, + ], + ], + [ + 'std deviation columns if mode = lower', + [{ series, metrics: [{ ...metric, mode: 'lower', field }], dataView }], + [ + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { + format: { id: 'bytes' }, + formula: 'average(bytes) - 1.5 * standard_deviation(bytes)', + }, + }, + ], + ], + [ + 'std deviation columns if mode = band', + [{ series, metrics: [{ ...metric, mode: 'band', field }], dataView }], + [ + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { + format: { id: 'bytes' }, + formula: 'average(bytes) + 1.5 * standard_deviation(bytes)', + }, + }, + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { + format: { id: 'bytes' }, + formula: 'average(bytes) - 1.5 * standard_deviation(bytes)', + }, + }, + ], + ], + [ + 'std deviation columns', + [ + { + series, + metrics: [{ ...metric, mode: undefined, field }], + dataView, + }, + ], + [ + { + meta: { metricId: 'some-id' }, + operationType: 'standard_deviation', + params: { format: { id: 'bytes' } }, + }, + ], + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToStandartDeviationColumn(...input)).toBeNull(); + } else if (Array.isArray(expected)) { + expect(convertToStandartDeviationColumn(...input)).toEqual( + expected.map(expect.objectContaining) + ); + } else { + expect(convertToStandartDeviationColumn(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From eb6e24583548a07438d81024b4ae707a0954283f Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 29 Aug 2022 18:58:10 +0300 Subject: [PATCH 100/129] Added tests for terms. --- .../convert_to_lens/lib/convert/terms.test.ts | 294 ++++++++++++++++++ .../convert_to_lens/lib/convert/terms.ts | 4 +- .../lib/series/buckets_columns.ts | 12 +- 3 files changed, 307 insertions(+), 3 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts new file mode 100644 index 0000000000000..e4436ecc19945 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts @@ -0,0 +1,294 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { + Operations, + TermsColumn, + TermsParams, +} from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { createSeries } from '../__mocks__'; +import { converToTermsColumn, convertToTermsParams } from './terms'; +import { Column } from './types'; + +describe('convertToTermsParams', () => { + const dataView = stubLogstashDataView; + const series = createSeries(); + + const metricId1 = 'metric-id-1'; + const metricId2 = 'metric-id-2'; + const columns: Column[] = [ + { + operationType: Operations.AVERAGE, + sourceField: dataView.fields[0].name, + columnId: 'some-id-0', + dataType: 'number', + params: {}, + meta: { metricId: metricId1 }, + isSplit: false, + isBucketed: true, + }, + { + operationType: Operations.SUM, + sourceField: dataView.fields[0].name, + columnId: 'some-id-1', + dataType: 'number', + params: {}, + meta: { metricId: metricId2 }, + isSplit: false, + isBucketed: true, + }, + ]; + const secondaryFields = ['some-field-1', 'some-field-2']; + const termsInclude = 'term-to-include'; + const termsExclude = 'term-to-exclude'; + const termsDirection = 'asc'; + const termsSize = 15; + + test.each< + [ + string, + Parameters, + Partial & { orderAgg: Partial }> | null + ] + >([ + [ + 'count column orderAgg if not terms_order_by is set', + [series, columns, []], + { + excludeIsRegex: false, + includeIsRegex: false, + orderAgg: { + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'count', + params: {}, + sourceField: 'document', + }, + orderDirection: 'desc', + }, + ], + [ + 'count column orderAgg if terms_order_by is set to _count', + [createSeries({ terms_order_by: '_count' }), columns, []], + { + excludeIsRegex: false, + includeIsRegex: false, + orderAgg: { + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'count', + params: {}, + sourceField: 'document', + }, + orderDirection: 'desc', + }, + ], + [ + 'orderBy alphabetical if terms_order_by is set to _key', + [createSeries({ terms_order_by: '_key' }), columns, []], + { + excludeIsRegex: false, + includeIsRegex: false, + orderBy: { type: 'alphabetical' }, + orderDirection: 'desc', + size: 10, + }, + ], + [ + 'column as orderAgg if terms_order_by is set to metric id', + [createSeries({ terms_order_by: metricId1 }), columns, []], + { + excludeIsRegex: false, + includeIsRegex: false, + orderAgg: { + columnId: 'some-id-0', + }, + orderBy: { columnId: 'some-id-0', type: 'column' }, + orderDirection: 'desc', + }, + ], + [ + 'null if terms_order_by is set not set to valid metric id', + [createSeries({ terms_order_by: 'some-invalid-id' }), columns, []], + null, + ], + [ + 'respect all the args', + [ + createSeries({ + terms_order_by: metricId1, + terms_include: termsInclude, + terms_exclude: termsExclude, + terms_direction: termsDirection, + terms_size: `${termsSize}`, + }), + columns, + secondaryFields, + ], + { + exclude: [termsExclude], + excludeIsRegex: true, + include: [termsInclude], + includeIsRegex: true, + orderAgg: { + columnId: 'some-id-0', + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'average', + params: {}, + sourceField: 'bytes', + }, + orderBy: { columnId: 'some-id-0', type: 'column' }, + orderDirection: termsDirection, + otherBucket: false, + parentFormat: { id: 'terms' }, + secondaryFields, + size: termsSize, + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(convertToTermsParams(...input)).toBeNull(); + } else { + expect(convertToTermsParams(...input)).toEqual( + expect.objectContaining({ + ...expected, + ...(expected.orderAgg ? { orderAgg: expect.objectContaining(expected.orderAgg) } : {}), + }) + ); + } + }); +}); + +describe('converToTermsColumn', () => { + const dataView = stubLogstashDataView; + + const series = createSeries(); + + const metricId1 = 'metric-id-1'; + const metricId2 = 'metric-id-2'; + const columns: Column[] = [ + { + operationType: Operations.AVERAGE, + sourceField: dataView.fields[0].name, + columnId: 'some-id-0', + dataType: 'number', + params: {}, + meta: { metricId: metricId1 }, + isSplit: false, + isBucketed: true, + }, + { + operationType: Operations.SUM, + sourceField: dataView.fields[0].name, + columnId: 'some-id-1', + dataType: 'number', + params: {}, + meta: { metricId: metricId2 }, + isSplit: false, + isBucketed: true, + }, + ]; + + const secondaryFields = ['some-field-1', 'some-field-2']; + const termsInclude = 'term-to-include'; + const termsExclude = 'term-to-exclude'; + const termsDirection = 'asc'; + const termsSize = 15; + + test.each< + [ + string, + Parameters, + Partial< + Omit & { + params: Partial> & { + orderAgg: Partial; + }; + } + > | null + ] + >([ + ['null if base field is not valid', [[''], series, columns, dataView, false], null], + [ + 'null if terms_order_by is invalid', + [ + [dataView.fields[0].name], + createSeries({ terms_order_by: 'some-invalid-id' }), + columns, + dataView, + false, + ], + null, + ], + [ + 'terms colum', + [ + [dataView.fields[0].name, ...secondaryFields], + createSeries({ + terms_order_by: metricId1, + terms_include: termsInclude, + terms_exclude: termsExclude, + terms_direction: termsDirection, + terms_size: `${termsSize}`, + }), + columns, + dataView, + true, + ], + { + isBucketed: true, + isSplit: true, + operationType: 'terms', + params: { + exclude: [termsExclude], + excludeIsRegex: true, + include: [termsInclude], + includeIsRegex: true, + format: { id: 'bytes' }, + orderAgg: { + columnId: 'some-id-0', + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'average', + params: {}, + sourceField: 'bytes', + }, + orderBy: { columnId: 'some-id-0', type: 'column' }, + orderDirection: termsDirection, + otherBucket: false, + parentFormat: { id: 'terms' }, + secondaryFields, + size: termsSize, + }, + sourceField: 'bytes', + }, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(converToTermsColumn(...input)).toBeNull(); + } else { + expect(converToTermsColumn(...input)).toEqual( + expect.objectContaining({ + ...expected, + params: expect.objectContaining({ + ...expected.params, + ...(expected.params?.orderAgg + ? { orderAgg: expect.objectContaining(expected.params.orderAgg) } + : {}), + }), + }) + ); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts index 8b601742a5bd0..580094603ed72 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts @@ -84,7 +84,7 @@ export const convertToTermsParams = ( }; export const converToTermsColumn = ( - termFields: string[], + termFields: [string, ...string[]], series: Series, columns: Column[], dataView: DataView, @@ -99,7 +99,7 @@ export const converToTermsColumn = ( const params = convertToTermsParams(series, columns, secondaryFields); if (!params) { - return params; + return null; } return { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index 932235b99e14a..cbbfdc5483ba0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -64,7 +64,17 @@ export const getBucketsColumns = ( return getValidColumns(dateHistogramColumn); } - const termsColumn = converToTermsColumn(splitFields, series, columns, dataView, isSplit); + if (!splitFields.length) { + return null; + } + + const termsColumn = converToTermsColumn( + splitFields as [string, ...string[]], + series, + columns, + dataView, + isSplit + ); return getValidColumns(termsColumn); } return []; From 69b249998009a8b1acd11ab8b183c749d901c9ca Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 10:47:57 +0300 Subject: [PATCH 101/129] Added tests. --- .../lib/series/buckets_columns.test.ts | 50 +++++++++++++++++++ .../lib/series/buckets_columns.ts | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts new file mode 100644 index 0000000000000..027d5abd0dc84 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts @@ -0,0 +1,50 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { createSeries } from '../__mocks__'; +import { isSplitWithDateHistogram } from './buckets_columns'; + +describe('isSplitWithDateHistogram', () => { + const dataView = stubLogstashDataView; + const series = createSeries({ terms_field: dataView.fields[0].name, split_mode: 'terms' }); + const splitFieldsWithMultipleDateFields = [dataView.fields[0].name, dataView.fields[2].name]; + test.each<[string, Parameters, boolean | null]>([ + [ + 'null if split_mode is terms, terms_field is specified and splitFields contains date field and others', + [series, splitFieldsWithMultipleDateFields, dataView], + null, + ], + [ + 'true if split_mode is terms, terms_field is specified and splitFields contains date field', + [series, [dataView.fields[2].name], dataView], + true, + ], + [ + 'false if no terms field is specified', + [createSeries({ split_mode: 'terms' }), splitFieldsWithMultipleDateFields, dataView], + false, + ], + [ + 'false if split_mode is not terms', + [ + createSeries({ terms_field: dataView.fields[0].name, split_mode: 'some-split-mode' }), + splitFieldsWithMultipleDateFields, + dataView, + ], + false, + ], + ['false if splitFields array is empty', [series, [], dataView], false], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(isSplitWithDateHistogram(...input)).toBeNull(); + } else { + expect(isSplitWithDateHistogram(...input)).toBe(expected); + } + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index cbbfdc5483ba0..967702abbd88a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -22,7 +22,7 @@ export const isSplitWithDateHistogram = ( splitFields: string[], dataView: DataView ) => { - if (series.terms_field && series.split_mode === 'terms' && splitFields) { + if (series.terms_field && series.split_mode === 'terms' && splitFields.length) { for (const f of splitFields) { const fieldType = dataView.getFieldByName(f)?.type; From 99f86e22ba2285b607307afb61ffc8c3e1abaf75 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 30 Aug 2022 11:48:17 +0300 Subject: [PATCH 102/129] Add tests for getLayers in xy configuration --- .../lib/configurations/xy/layers.test.ts | 288 ++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.test.ts new file mode 100644 index 0000000000000..656dc3a8c4290 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/layers.test.ts @@ -0,0 +1,288 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { XYLayerConfig } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import type { Panel } from '../../../../../common/types'; +import { TSVB_METRIC_TYPES } from '../../../../../common/enums'; +import { + Layer, + PercentileColumnWithExtendedMeta, + PercentileRanksColumnWithCommonMeta, +} from '../../convert'; +import { getLayers } from './layers'; +import { createPanel, createSeries } from '../../__mocks__'; + +describe('getLayers', () => { + const dataSourceLayers: Record = [ + { + indexPatternId: 'test', + layerId: 'test-layer-1', + columns: [ + { + operationType: 'count', + columnId: 'column-id-1', + sourceField: 'document', + isBucketed: false, + isSplit: false, + dataType: 'number', + params: {}, + meta: { metricId: 'metric-1' }, + }, + { + columnId: 'column-id-2', + operationType: 'date_histogram', + isBucketed: true, + isSplit: false, + sourceField: 'date-field', + dataType: 'date', + params: { + interval: 'auto', + }, + }, + { + columnId: 'column-id-3', + operationType: 'terms', + isBucketed: true, + isSplit: true, + sourceField: 'string-field', + dataType: 'string', + params: { + size: 5, + orderBy: { type: 'alphabetical' }, + orderDirection: 'desc', + }, + }, + ], + columnOrder: [], + }, + ]; + const dataSourceLayersWithStatic: Record = [ + { + indexPatternId: 'test', + layerId: 'test-layer-1', + columns: [ + { + operationType: 'static_value', + columnId: 'column-id-1', + isBucketed: false, + isSplit: false, + dataType: 'number', + references: [], + params: { + value: '100', + }, + meta: { metricId: 'metric-1' }, + }, + ], + columnOrder: [], + }, + ]; + const dataSourceLayersWithPercentile: Record = [ + { + indexPatternId: 'test', + layerId: 'test-layer-1', + columns: [ + { + operationType: 'percentile', + columnId: 'column-id-1', + sourceField: 'test-field', + isBucketed: false, + isSplit: false, + dataType: 'number', + params: { + percentile: 50, + }, + meta: { metricId: 'metric-1', reference: 'metric-1.0' }, + } as PercentileColumnWithExtendedMeta, + { + operationType: 'percentile', + columnId: 'column-id-2', + sourceField: 'test-field', + isBucketed: false, + isSplit: false, + dataType: 'number', + params: { + percentile: 100, + }, + meta: { metricId: 'metric-1', reference: 'metric-1.1' }, + } as PercentileColumnWithExtendedMeta, + ], + columnOrder: [], + }, + ]; + const dataSourceLayersWithPercentileRank: Record = [ + { + indexPatternId: 'test', + layerId: 'test-layer-1', + columns: [ + { + operationType: 'percentile_rank', + columnId: 'column-id-1', + sourceField: 'test-field', + isBucketed: false, + isSplit: false, + dataType: 'number', + params: { + value: 50, + }, + meta: { metricId: 'metric-1', reference: 'metric-1.0' }, + } as PercentileRanksColumnWithCommonMeta, + { + operationType: 'percentile_rank', + columnId: 'column-id-2', + sourceField: 'test-field', + isBucketed: false, + isSplit: false, + dataType: 'number', + params: { + value: 100, + }, + meta: { metricId: 'metric-1', reference: 'metric-1.1' }, + } as PercentileRanksColumnWithCommonMeta, + ], + columnOrder: [], + }, + ]; + const metrics = [ + { + id: 'metric-1', + type: METRIC_TYPES.COUNT, + }, + ]; + + const staticValueMetric = [ + { + id: 'metric-1', + type: TSVB_METRIC_TYPES.STATIC, + }, + ]; + + const percentileMetrics = [ + { + id: 'metric-1', + type: TSVB_METRIC_TYPES.PERCENTILE, + percentiles: [ + { + id: 'percent-1', + mode: 'line' as const, + color: 'color-1', + }, + { + id: 'percent-2', + mode: 'line' as const, + color: 'color-2', + }, + ], + }, + ]; + + const percentileRankMetrics = [ + { + id: 'metric-1', + type: TSVB_METRIC_TYPES.PERCENTILE_RANK, + colors: ['color-1', 'color-2'], + }, + ]; + + const panel = createPanel({ series: [createSeries({ metrics })] }); + const panelWithStaticValue = createPanel({ + series: [createSeries({ metrics: staticValueMetric })], + }); + const panelWithPercentileMetric = createPanel({ + series: [createSeries({ metrics: percentileMetrics })], + }); + const panelWithPercentileRankMetric = createPanel({ + series: [createSeries({ metrics: percentileRankMetrics })], + }); + + test.each<[string, [Record, Panel], Array>]>([ + [ + 'data layer if columns do not include static column', + [dataSourceLayers, panel], + [ + { + layerType: 'data', + accessors: ['column-id-1'], + xAccessor: 'column-id-2', + splitAccessor: 'column-id-3', + seriesType: 'area', + layerId: 'test-layer-1', + yConfig: [ + { + forAccessor: 'column-id-1', + axisMode: 'right', + color: '#68BC00', + }, + ], + }, + ], + ], + [ + 'reference line layer if columns include static column', + [dataSourceLayersWithStatic, panelWithStaticValue], + [ + { + layerType: 'referenceLine', + accessors: ['column-id-1'], + layerId: 'test-layer-1', + yConfig: [ + { + forAccessor: 'column-id-1', + axisMode: 'right', + color: '#68BC00', + fill: 'below', + }, + ], + }, + ], + ], + [ + 'correct colors if columns include percentile columns', + [dataSourceLayersWithPercentile, panelWithPercentileMetric], + [ + { + yConfig: [ + { + forAccessor: 'column-id-1', + axisMode: 'right', + color: 'color-1', + }, + { + forAccessor: 'column-id-2', + axisMode: 'right', + color: 'color-2', + }, + ], + }, + ], + ], + [ + 'correct colors if columns include percentile rank columns', + [dataSourceLayersWithPercentileRank, panelWithPercentileRankMetric], + [ + { + yConfig: [ + { + forAccessor: 'column-id-1', + axisMode: 'right', + color: 'color-1', + }, + { + forAccessor: 'column-id-2', + axisMode: 'right', + color: 'color-2', + }, + ], + }, + ], + ], + ])('should return %s', (_, input, expected) => { + expect(getLayers(...input)).toEqual(expected.map(expect.objectContaining)); + }); +}); From c65115acc439828fac1020ae2116584307d1f543 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 30 Aug 2022 12:28:41 +0300 Subject: [PATCH 103/129] Rename window to reducedTimeRange --- .../lib/convert/column.test.ts | 6 +-- .../convert_to_lens/lib/convert/column.ts | 10 ++--- .../lib/convert/cumulative_sum.test.ts | 10 ++--- .../lib/convert/cumulative_sum.ts | 6 +-- .../lib/convert/filter_ratio.ts | 4 +- .../convert_to_lens/lib/convert/formula.ts | 24 ++++++---- .../lib/convert/last_value.test.ts | 6 +-- .../convert_to_lens/lib/convert/last_value.ts | 4 +- .../lib/convert/parent_pipeline.test.ts | 8 ++-- .../lib/convert/parent_pipeline.ts | 28 ++++++------ .../lib/convert/percentile.test.ts | 12 ++--- .../convert_to_lens/lib/convert/percentile.ts | 8 ++-- .../lib/convert/percentile_rank.test.ts | 12 ++--- .../lib/convert/percentile_rank.ts | 8 ++-- .../lib/convert/static_value.test.ts | 9 ++-- .../lib/convert/static_value.ts | 7 ++- .../lib/convert/std_deviation.ts | 16 ++++--- .../lib/metrics/filter_ratio_formula.test.ts | 4 +- .../lib/metrics/filter_ratio_formula.ts | 22 ++++++--- .../lib/metrics/metrics_helpers.test.ts | 18 ++++---- .../lib/metrics/metrics_helpers.ts | 45 +++++++++++-------- .../lib/metrics/parent_pipeline_formula.ts | 4 +- .../lib/metrics/sibling_pipeline_formula.ts | 4 +- .../lib/series/metrics_columns.ts | 30 ++++++++----- .../public/convert_to_lens/top_n/index.ts | 6 +-- .../public/convert_to_lens/top_n/new.index.ts | 0 .../public/convert_to_lens/types.ts | 2 +- .../common/convert_to_lens/types/columns.ts | 2 +- .../indexpattern_suggestions.ts | 2 +- 29 files changed, 178 insertions(+), 139 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts index cd99e1a5e5189..cad2fcff9cce6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -106,7 +106,7 @@ describe('createColumn', () => { }; const customLabel = 'some custom'; - const window = 'some-window'; + const reducedTimeRange = '10h'; const filter = { query: 'some-query', language: 'lucene' }; test.each([ @@ -131,12 +131,12 @@ describe('createColumn', () => { }, field, metric: metricWithTimeScale, - extraFields: { window, isBucketed: true, isSplit: true }, + extraFields: { reducedTimeRange, isBucketed: true, isSplit: true }, }, { isBucketed: true, isSplit: true, - window, + reducedTimeRange, label: customLabel, meta: { metricId: metricWithTimeScale.id }, filter, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index d12df89e7122f..f68f86cce6e0e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -25,7 +25,7 @@ type GeneralColumnWithMeta = GenericColumnWithMeta; interface ExtraColumnFields { isBucketed?: boolean; isSplit?: boolean; - window?: string; + reducedTimeRange?: string; } const isSupportedFormat = (format: string) => ['bytes', 'number', 'percent'].includes(format); @@ -75,14 +75,14 @@ export const createColumn = ( series: Series, metric: Metric, field?: DataViewField, - { isBucketed = false, isSplit = false, window }: ExtraColumnFields = {} + { isBucketed = false, isSplit = false, reducedTimeRange }: ExtraColumnFields = {} ): GeneralColumnWithMeta => ({ columnId: uuid(), dataType: (field?.type as DataType) ?? undefined, label: series.label, isBucketed, isSplit, - window, + reducedTimeRange, filter: series.filter, timeScale: getTimeScale(metric), meta: { metricId: metric.id }, @@ -91,8 +91,8 @@ export const createColumn = ( export const convertMetricsToColumns = ( { series, metrics, dataView }: CommonColumnsConverterArgs, convertToFn: ConvertToColumnsFn, - window?: string -) => metrics.flatMap((metric) => convertToFn({ series, metric, dataView }, window)); + reducedTimeRange?: string +) => metrics.flatMap((metric) => convertToFn({ series, metric, dataView }, reducedTimeRange)); export const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { if ((column as ColumnWithMeta).meta) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts index 9d37f02da161d..127d45d18c153 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts @@ -34,13 +34,13 @@ const staticSubAggMetric: Metric = { type: TSVB_METRIC_TYPES.STATIC, }; const metaValue = `50`; -const window = '1h'; +const reducedTimeRange = '1h'; describe('convertToCumulativeSumColumns', () => { test.each< [ string, - [common: CommonColumnsConverterArgs, window?: string], + [common: CommonColumnsConverterArgs, reducedTimeRange?: string], Partial | Array> | null ] >([ @@ -185,7 +185,7 @@ describe('convertToCumulativeSumColumns', () => { }, ], [ - 'formula with time range if submetric is percentile and window is specified', + 'formula with time range if submetric is percentile and reducedTimeRange is specified', [ { series, @@ -195,13 +195,13 @@ describe('convertToCumulativeSumColumns', () => { ], dataView, }, - window, + reducedTimeRange, ], { operationType: 'formula', meta: { metricId: metric.id }, params: { - formula: `cumulative_sum(percentile(${subAggMetric.field}, percentile=${metaValue}, timeRange='${window}'))`, + formula: `cumulative_sum(percentile(${subAggMetric.field}, percentile=${metaValue}, reducedTimeRange='${reducedTimeRange}'))`, }, }, ], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index 1429936039061..8da6730b17c1c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -14,7 +14,7 @@ import { CommonColumnsConverterArgs } from './types'; export const convertToCumulativeSumColumns = ( { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ) => { const metric = metrics[metrics.length - 1]; @@ -35,7 +35,7 @@ export const convertToCumulativeSumColumns = ( const metaValue = Number(meta?.replace(']', '')); formula = getParentPipelineSeriesFormula(metrics, subFunctionMetric, pipelineAgg, metric.type, { metaValue, - window, + reducedTimeRange, }); if (!formula) { return null; @@ -49,7 +49,7 @@ export const convertToCumulativeSumColumns = ( { series, metric, dataView }, subFunctionMetric, pipelineAgg, - { window } + { reducedTimeRange } ); } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts index cdd150e9a9c36..0b4f591d92503 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -12,10 +12,10 @@ import { CommonColumnsConverterArgs, FormulaColumn } from './types'; export const convertFilterRatioToFormulaColumn = ( { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ): FormulaColumn | null => { const metric = metrics[metrics.length - 1]; - const formula = getFilterRatioFormula(metric, window); + const formula = getFilterRatioFormula(metric, reducedTimeRange); if (!formula) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index cd85c0c9e4888..9ade0575054c9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -43,7 +43,7 @@ const convertFormulaScriptForPercentileAggs = ( variables: Exclude, metric: Metric, allAggMetrics: Metric[], - window?: string + reducedTimeRange?: string ) => { variables.forEach((variable) => { const [_, meta] = variable?.field?.split('[') ?? []; @@ -51,7 +51,7 @@ const convertFormulaScriptForPercentileAggs = ( if (!metaValue) { return; } - const script = getFormulaEquivalent(metric, allAggMetrics, { metaValue, window }); + const script = getFormulaEquivalent(metric, allAggMetrics, { metaValue, reducedTimeRange }); if (!script) { return; } @@ -65,9 +65,9 @@ const convertFormulaScriptForAggs = ( variables: Exclude, metric: Metric, allAggMetrics: Metric[], - window?: string + reducedTimeRange?: string ) => { - const script = getFormulaEquivalent(metric, allAggMetrics, { window }); + const script = getFormulaEquivalent(metric, allAggMetrics, { reducedTimeRange }); if (!script) { return null; } @@ -77,7 +77,7 @@ const convertFormulaScriptForAggs = ( export const convertMathToFormulaColumn = ( { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ): FormulaColumn | null => { // find the metric idx that has math expression const metric = metrics.find(({ type }) => type === 'math'); @@ -112,10 +112,16 @@ export const convertMathToFormulaColumn = ( variables, notMathMetric, metrics, - window + reducedTimeRange ); } else { - script = convertFormulaScriptForAggs(script!, variables, notMathMetric, metrics, window); + script = convertFormulaScriptForAggs( + script!, + variables, + notMathMetric, + metrics, + reducedTimeRange + ); } } @@ -134,11 +140,11 @@ export const convertMathToFormulaColumn = ( export const convertOtherAggsToFormulaColumn = ( aggregation: OtherFormulaAggregations, { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ): FormulaColumn | null => { const metric = metrics[metrics.length - 1]; - const formula = getSiblingPipelineSeriesFormula(aggregation, metric, metrics, window); + const formula = getSiblingPipelineSeriesFormula(aggregation, metric, metrics, reducedTimeRange); if (!formula) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts index 665cb9ff3d58b..8efc402f028d9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts @@ -80,13 +80,13 @@ describe('convertToLastValueColumn', () => { }, ], [ - 'last value column with window', - [{ series, metrics: [metric], dataView }, '10'], + 'last value column with reducedTimeRange', + [{ series, metrics: [metric], dataView }, '10m'], { meta: { metricId: 'some-id-0' }, operationType: 'last_value', params: { format: { id: 'bytes' }, showArrayValues: false, sortField: '@timestamp' }, - window: '10', + reducedTimeRange: '10m', }, ], ] diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index 6a954d4e86dd2..e50ab9ff33c68 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -18,7 +18,7 @@ export const convertToLastValueParams = (metric: Metric): LastValueParams => ({ export const convertToLastValueColumn = ( { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ): LastValueColumn | null => { const currentMetric = metrics[metrics.length - 1]; // We can only support top_hit with size 1 @@ -37,7 +37,7 @@ export const convertToLastValueColumn = ( return { operationType: 'last_value', sourceField: field.name ?? 'document', - ...createColumn(series, currentMetric, undefined, { window }), + ...createColumn(series, currentMetric, undefined, { reducedTimeRange }), params: { ...convertToLastValueParams(currentMetric), ...getFormat(series, currentMetric.field, dataView), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index 2b31555a8676e..fcd569ef59c5e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -224,13 +224,13 @@ describe('convertMetricAggregationToColumn', () => { [ SUPPORTED_METRICS.percentile, { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, - { metaValue: 50, window: '10' }, + { metaValue: 50, window: '10m' }, ], { meta: { metricId: 'some-id' }, operationType: 'percentile', params: { format: { id: 'bytes' }, percentile: 50 }, - window: '10', + reducedTimeRange: '10m', }, ], [ @@ -259,13 +259,13 @@ describe('convertMetricAggregationToColumn', () => { [ SUPPORTED_METRICS.percentile_rank, { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE_RANK }, dataView }, - { metaValue: 50, window: '10' }, + { metaValue: 50, window: '10m' }, ], { meta: { metricId: 'some-id' }, operationType: 'percentile_rank', params: { format: { id: 'bytes' }, value: 50 }, - window: '10', + reducedTimeRange: '10m', }, ], [ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 9b044d6592143..687bcb128b330 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -115,7 +115,7 @@ const isSupportedAggregationWithoutParams = ( export const convertMetricAggregationColumnWithoutSpecialParams = ( aggregation: SupportedMetric, { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ): MetricAggregationColumnWithoutSpecialParams | null => { if (!isSupportedAggregationWithoutParams(aggregation.name)) { return null; @@ -131,7 +131,7 @@ export const convertMetricAggregationColumnWithoutSpecialParams = ( return { operationType: aggregation.name, sourceField, - ...createColumn(series, metric, field, { window }), + ...createColumn(series, metric, field, { reducedTimeRange }), params: { ...getFormat(series, field?.name, dataView) }, } as MetricAggregationColumnWithoutSpecialParams; }; @@ -139,7 +139,7 @@ export const convertMetricAggregationColumnWithoutSpecialParams = ( export const convertMetricAggregationToColumn = ( aggregation: SupportedMetric, { series, metric, dataView }: CommonColumnConverterArgs, - { metaValue, window }: { metaValue?: number; window?: string } = {} + { metaValue, reducedTimeRange }: { metaValue?: number; reducedTimeRange?: string } = {} ): MetricAggregationColumn | null => { if (!isSupportedAggregation(aggregation.name)) { return null; @@ -151,12 +151,12 @@ export const convertMetricAggregationToColumn = ( } if (aggregation.name === Operations.PERCENTILE) { - return convertToPercentileColumn(metaValue, { series, metric, dataView }, { window }); + return convertToPercentileColumn(metaValue, { series, metric, dataView }, { reducedTimeRange }); } if (aggregation.name === Operations.PERCENTILE_RANK) { return convertToPercentileRankColumn(metaValue?.toString(), series, metric, dataView, { - window, + reducedTimeRange, }); } if (aggregation.name === Operations.COUNTER_RATE) { @@ -170,7 +170,7 @@ export const convertMetricAggregationToColumn = ( return convertMetricAggregationColumnWithoutSpecialParams( aggregation, { series, metrics: [metric], dataView }, - window + reducedTimeRange ); }; @@ -179,7 +179,7 @@ export const computeParentPipelineColumns = ( { series, metric, dataView }: CommonColumnConverterArgs, subFunctionMetric: Metric, pipelineAgg: SupportedMetric, - { metaValue, window }: { metaValue?: number; window?: string } = {} + { metaValue, reducedTimeRange }: { metaValue?: number; reducedTimeRange?: string } = {} ) => { const agg = SUPPORTED_METRICS[metric.type]; if (!agg) { @@ -189,7 +189,7 @@ export const computeParentPipelineColumns = ( const aggFormula = getFormulaFromMetric(agg); if (subFunctionMetric.type === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric, window); + const script = getFilterRatioFormula(subFunctionMetric, reducedTimeRange); if (!script) { return null; } @@ -200,7 +200,7 @@ export const computeParentPipelineColumns = ( const metricAggregationColumn = convertMetricAggregationToColumn( pipelineAgg, { series, metric: subFunctionMetric, dataView }, - { metaValue, window } + { metaValue, reducedTimeRange } ); if (!metricAggregationColumn) { @@ -219,7 +219,7 @@ const convertMovingAvgOrDerivativeToColumns = ( aggregation: typeof METRIC_TYPES.DERIVATIVE | typeof TSVB_METRIC_TYPES.MOVING_AVERAGE, metric: Metric, { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ) => { // percentile value is derived from the field Id. It has the format xxx-xxx-xxx-xxx[percentile] const [fieldId, meta] = metric?.field?.split('[') ?? []; @@ -243,7 +243,7 @@ const convertMovingAvgOrDerivativeToColumns = ( subFunctionMetric, pipelineAgg, metric.type, - { metaValue, window } + { metaValue, reducedTimeRange } ); if (!formula) { return null; @@ -261,14 +261,14 @@ const convertMovingAvgOrDerivativeToColumns = ( { series, metric, dataView }, subFunctionMetric, pipelineAgg, - { metaValue, window } + { metaValue, reducedTimeRange } ); } }; export const convertParentPipelineAggToColumns = ( { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ) => { const currentMetric = metrics[metrics.length - 1]; @@ -277,7 +277,7 @@ export const convertParentPipelineAggToColumns = ( currentMetric.type, currentMetric, { series, metrics, dataView }, - window + reducedTimeRange ); } return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts index 0e20210ab7a5a..f6058556ffe27 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts @@ -108,18 +108,18 @@ describe('convertToPercentileColumn', () => { } as Partial, ], [ - 'precentile column with reference in meta and window', + 'precentile column with reference in meta and reducedTimeRange', [ '50', { series, metric: { ...metric, field: dataView.fields[0].name }, dataView }, - { index: 0, window: '10' }, + { index: 0, reducedTimeRange: '10m' }, ], { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile', params: { format: { id: 'bytes' }, percentile: 50 }, sourceField: 'bytes', - window: '10', + reducedTimeRange: '10m', } as Partial, ], ])('should return %s', (_, input, expected) => { @@ -196,7 +196,7 @@ describe('convertToPercentileColumns', () => { ], ], [ - 'percentile columns with window', + 'percentile columns with reducedTimeRange', [ { series, @@ -207,7 +207,7 @@ describe('convertToPercentileColumns', () => { }, dataView, }, - '50', + '50m', ], [ { @@ -215,7 +215,7 @@ describe('convertToPercentileColumns', () => { operationType: 'percentile', params: { format: { id: 'bytes' }, percentile: 75 }, sourceField: 'bytes', - window: '50', + reducedTimeRange: '50m', }, ], ], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 1157afb7e794f..676a5c6907d64 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -32,7 +32,7 @@ export const convertToPercentileParams = (value?: string | number): PercentilePa export const convertToPercentileColumn = ( percentile: Percentile['value'], { series, metric, dataView }: CommonColumnConverterArgs, - { index, window }: { index?: number; window?: string } = {} + { index, reducedTimeRange }: { index?: number; reducedTimeRange?: string } = {} ): PercentileColumn | null => { const params = convertToPercentileParams(percentile); if (!params) { @@ -43,7 +43,7 @@ export const convertToPercentileColumn = ( if (!field) { return null; } - const commonColumnParams = createColumn(series, metric, field, { window }); + const commonColumnParams = createColumn(series, metric, field, { reducedTimeRange }); return { operationType: 'percentile', sourceField: field.name, @@ -61,7 +61,7 @@ export const convertToPercentileColumn = ( export const convertToPercentileColumns = ( columnConverterArgs: CommonColumnConverterArgs, - window?: string + reducedTimeRange?: string ): Array | null => { const { percentiles } = columnConverterArgs.metric; @@ -70,6 +70,6 @@ export const convertToPercentileColumns = ( } return percentiles.map((p, index) => - convertToPercentileColumn(p.value, columnConverterArgs, { index, window }) + convertToPercentileColumn(p.value, columnConverterArgs, { index, reducedTimeRange }) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts index 169847d3c9d17..5a70c86303fbc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -112,20 +112,20 @@ describe('convertToPercentileRankColumn', () => { } as Partial, ], [ - 'precentile rank column with reference in meta and window', + 'precentile rank column with reference in meta and reducedTimeRange', [ '50', series, { ...metric, field: dataView.fields[0].name }, dataView, - { index: 0, window: '10' }, + { index: 0, reducedTimeRange: '10m' }, ], { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile_rank', params: { format: { id: 'bytes' }, value: 50 }, sourceField: 'bytes', - window: '10', + reducedTimeRange: '10m', } as Partial, ], ])('should return %s', (_, input, expected) => { @@ -179,10 +179,10 @@ describe('convertToPercentileRankColumns', () => { ], ], [ - 'percentile rank columns with window', + 'percentile rank columns with reducedTimeRange', [ { series, metric: { ...metric, field: dataView.fields[0].name, values: ['75'] }, dataView }, - '50', + '50m', ], [ { @@ -190,7 +190,7 @@ describe('convertToPercentileRankColumns', () => { operationType: 'percentile_rank', params: { format: { id: 'bytes' }, value: 75 }, sourceField: 'bytes', - window: '50', + reducedTimeRange: '50m', }, ], ], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index e60c450d61163..d0a838d8f0fd5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -38,7 +38,7 @@ export const convertToPercentileRankColumn = ( series: Series, metric: Metric, dataView: DataView, - { index, window }: { index?: number; window?: string } = {} + { index, reducedTimeRange }: { index?: number; reducedTimeRange?: string } = {} ): PercentileRanksColumn | null => { const params = convertToPercentileRankParams(value); if (!params) { @@ -50,7 +50,7 @@ export const convertToPercentileRankColumn = ( return null; } - const commonColumnParams = createColumn(series, metric, field, { window }); + const commonColumnParams = createColumn(series, metric, field, { reducedTimeRange }); return { operationType: 'percentile_rank', sourceField: field.name, @@ -68,7 +68,7 @@ export const convertToPercentileRankColumn = ( export const convertToPercentileRankColumns = ( { series, metric, dataView }: CommonColumnConverterArgs, - window?: string + reducedTimeRange?: string ): Array | null => { const { values } = metric; @@ -77,6 +77,6 @@ export const convertToPercentileRankColumns = ( } return values.map((p, index) => - convertToPercentileRankColumn(p, series, metric, dataView, { index, window }) + convertToPercentileRankColumn(p, series, metric, dataView, { index, reducedTimeRange }) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts index f29ef3b3f0083..907fe458c6a64 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts @@ -57,13 +57,16 @@ describe('convertToStaticValueColumn', () => { }, ], [ - 'static value column with window', - [{ series, metrics: [{ ...metric, value: 'some value' }], dataView }, { window: '100' }], + 'static value column with reducedTimeRange', + [ + { series, metrics: [{ ...metric, value: 'some value' }], dataView }, + { reducedTimeRange: '10h' }, + ], { meta: { metricId: 'some-id' }, operationType: 'static_value', params: { value: 'some value' }, - window: '100', + reducedTimeRange: '10h', }, ], ])('should return %s', (_, input, expected) => { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index 912736e14e780..649198e549687 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -17,7 +17,10 @@ export const convertToStaticValueParams = ({ value }: Metric): StaticValueParams export const convertToStaticValueColumn = ( { series, metrics, dataView }: CommonColumnsConverterArgs, - { visibleSeriesCount = 0, window }: { visibleSeriesCount?: number; window?: string } = {} + { + visibleSeriesCount = 0, + reducedTimeRange, + }: { visibleSeriesCount?: number; reducedTimeRange?: string } = {} ): StaticValueColumn | null => { // Lens support reference lines only when at least one layer data exists if (visibleSeriesCount === 1) { @@ -27,7 +30,7 @@ export const convertToStaticValueColumn = ( return { operationType: 'static_value', references: [], - ...createColumn(series, currentMetric, undefined, { window }), + ...createColumn(series, currentMetric, undefined, { reducedTimeRange }), params: { ...convertToStaticValueParams(currentMetric), ...getFormat(series, currentMetric.field, dataView), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts index 2ebe75d3e81f5..73e1b614869b2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts @@ -15,16 +15,16 @@ import { CommonColumnConverterArgs, CommonColumnsConverterArgs } from './types'; const createStandartDeviationFormulaColumn = ( { series, metric, dataView }: CommonColumnConverterArgs, metrics: Metric[], - window?: string + reducedTimeRange?: string ) => { - const script = getFormulaEquivalent(metric, metrics, { window }); + const script = getFormulaEquivalent(metric, metrics, { reducedTimeRange }); if (!script) return null; return createFormulaColumn(script, { series, metric, dataView }); }; export const convertToStandartDeviationColumn = ( { series, metrics, dataView }: CommonColumnsConverterArgs, - window?: string + reducedTimeRange?: string ) => { const metric = metrics[metrics.length - 1]; @@ -37,7 +37,7 @@ export const convertToStandartDeviationColumn = ( if (metric.mode === 'upper' || metric.mode === 'lower') { columns.push( - createStandartDeviationFormulaColumn({ series, metric, dataView }, metrics, window) + createStandartDeviationFormulaColumn({ series, metric, dataView }, metrics, reducedTimeRange) ); } else if (metric.mode === 'band') { [ @@ -45,7 +45,11 @@ export const convertToStandartDeviationColumn = ( { ...metric, mode: 'lower' }, ].forEach((m) => { columns.push( - createStandartDeviationFormulaColumn({ series, metric: m, dataView }, metrics, window) + createStandartDeviationFormulaColumn( + { series, metric: m, dataView }, + metrics, + reducedTimeRange + ) ); }); } else { @@ -53,7 +57,7 @@ export const convertToStandartDeviationColumn = ( convertMetricAggregationColumnWithoutSpecialParams( SUPPORTED_METRICS.std_deviation, { series, metrics: [metric], dataView }, - window + reducedTimeRange ) ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts index 4ad05ea94d15b..a18de5cdeba13 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts @@ -45,9 +45,9 @@ describe('getFilterRatioFormula', () => { "average('test-1',kql='*') / average('test-1',kql='*')", ], [ - 'filter ratio formula if window is provided', + 'filter ratio formula if reducedTimeRange is provided', [metricWithMetricAgg, '1h'], - "average('test-1',kql='*', timeRange='1h') / average('test-1',kql='*', timeRange='1h')", + "average('test-1',kql='*', reducedTimeRange='1h') / average('test-1',kql='*', reducedTimeRange='1h')", ], ])('should return %s', (_, input, expected) => { if (expected === null) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index d6613c6182eff..ef16ee9ee2ace 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -15,15 +15,19 @@ const escapeQuotes = (str: string) => { return str?.replace(/'/g, "\\'"); }; -const constructFilterRationFormula = (operation: string, metric?: Query, window?: string) => { +const constructFilterRationFormula = ( + operation: string, + metric?: Query, + reducedTimeRange?: string +) => { return `${operation}${metric?.language === 'lucene' ? 'lucene' : 'kql'}='${ metric?.query && typeof metric?.query === 'string' ? escapeQuotes(metric?.query) : metric?.query ?? '*' - }'${addTimeRangeToFormula(window)})`; + }'${addTimeRangeToFormula(reducedTimeRange)})`; }; -export const getFilterRatioFormula = (currentMetric: Metric, window?: string) => { +export const getFilterRatioFormula = (currentMetric: Metric, reducedTimeRange?: string) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; let aggregation: SupportedMetric | null | undefined = SUPPORTED_METRICS.count; @@ -41,17 +45,21 @@ export const getFilterRatioFormula = (currentMetric: Metric, window?: string) => const numeratorFormula = `max(${constructFilterRationFormula( `differences(max('${field}',`, numerator, - window + reducedTimeRange )})`; const denominatorFormula = `max(${constructFilterRationFormula( `differences(max('${field}',`, denominator, - window + reducedTimeRange )})`; return `${numeratorFormula}) / ${denominatorFormula})`; } else { - const numeratorFormula = constructFilterRationFormula(operation, numerator, window); - const denominatorFormula = constructFilterRationFormula(operation, denominator, window); + const numeratorFormula = constructFilterRationFormula(operation, numerator, reducedTimeRange); + const denominatorFormula = constructFilterRationFormula( + operation, + denominator, + reducedTimeRange + ); return `${numeratorFormula} / ${denominatorFormula}`; } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts index fb3133634090a..994e1f77c37a0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts @@ -18,7 +18,7 @@ import { TimeRange } from '@kbn/data-plugin/common'; import { METRIC_TYPES } from '@kbn/data-plugin/public'; import type { Metric, Series, Panel } from '../../../../common/types'; import { TIME_RANGE_DATA_MODES, TSVB_METRIC_TYPES } from '../../../../common/enums'; -import { getFormulaEquivalent, getWindow } from './metrics_helpers'; +import { getFormulaEquivalent, getReducedTimeRange } from './metrics_helpers'; import { createPanel, createSeries } from '../__mocks__'; jest.mock('../../../services', () => ({ @@ -109,7 +109,9 @@ describe('getFormulaEquivalent', () => { field: 'test-1', }; - test.each<[string, [Metric, Metric[], { metaValue?: number; window?: string }], string | null]>([ + test.each< + [string, [Metric, Metric[], { metaValue?: number; reducedTimeRange?: string }], string | null] + >([ ['null if metric is not supported', [notSupportedMetric, [notSupportedMetric], {}], null], [ 'correct formula if metric is sibling pipeline agg', @@ -154,9 +156,9 @@ describe('getFormulaEquivalent', () => { 'average(test-1)', ], [ - 'correct formula if metric is supported and window is provided', - [supportedMetric, [supportedMetric], { window: '1h' }], - "average(test-1, timeRange='1h')", + 'correct formula if metric is supported and reducedTimeRange is provided', + [supportedMetric, [supportedMetric], { reducedTimeRange: '1h' }], + "average(test-1, reducedTimeRange='1h')", ], ])('should return %s', (_, input, expected) => { if (expected === null) { @@ -166,7 +168,7 @@ describe('getFormulaEquivalent', () => { }); }); -describe('getWindow', () => { +describe('getReducedTimeRange', () => { const timeRange: TimeRange = { from: '2022-02-04', to: '2022-02-05', @@ -234,8 +236,8 @@ describe('getWindow', () => { ], ])('should return %s', (_, input, expected) => { if (expected === undefined) { - expect(getWindow(...input)).toBeUndefined(); + expect(getReducedTimeRange(...input)).toBeUndefined(); } - expect(getWindow(...input)).toEqual(expected); + expect(getReducedTimeRange(...input)).toEqual(expected); }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 9ae5cb3108e52..7f5e036ef89d3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -20,20 +20,20 @@ import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; import { buildCounterRateFormula } from './counter_rate_formula'; -const shouldCalculateWindow = (timeRangeMode?: string) => { +const shouldCalculateReducedTimeRange = (timeRangeMode?: string) => { return timeRangeMode === TIME_RANGE_DATA_MODES.LAST_VALUE; }; -export const getWindow = (model: Panel, series: Series, timeRange?: TimeRange) => { +export const getReducedTimeRange = (model: Panel, series: Series, timeRange?: TimeRange) => { if ( - !shouldCalculateWindow( + !shouldCalculateReducedTimeRange( series.override_index_pattern ? series.time_range_mode : model.time_range_mode ) ) { return undefined; } const interval = series.override_index_pattern ? series.series_interval : model.interval; - let window = interval || '1h'; + let reducedTimeRange = interval || '1h'; if (timeRange && !interval) { const { from, to } = timeRange; @@ -47,10 +47,10 @@ export const getWindow = (model: Panel, series: Series, timeRange?: TimeRange) = return Number.isInteger(value); }) || 'ms'; - window = `${duration.as(unit)}${unit}`; + reducedTimeRange = `${duration.as(unit)}${unit}`; } - return window; + return reducedTimeRange; }; export type TimeScaleValue = `1${TimeScaleUnit}`; @@ -68,14 +68,14 @@ export const getTimeScale = (metric: Metric): TimeScaleUnit | undefined => { return timeScale; }; -export const addTimeRangeToFormula = (window?: string) => { - return window ? `, timeRange='${window}'` : ''; +export const addTimeRangeToFormula = (reducedTimeRange?: string) => { + return reducedTimeRange ? `, reducedTimeRange='${reducedTimeRange}'` : ''; }; export const getFormulaEquivalent = ( currentMetric: Metric, metrics: Metric[], - { metaValue, window }: { metaValue?: number; window?: string } = {} + { metaValue, reducedTimeRange }: { metaValue?: number; reducedTimeRange?: string } = {} ) => { const aggregation = SUPPORTED_METRICS[currentMetric.type]; if (!aggregation) { @@ -90,7 +90,12 @@ export const getFormulaEquivalent = ( case 'min_bucket': case 'sum_bucket': case 'positive_only': { - return getSiblingPipelineSeriesFormula(currentMetric.type, currentMetric, metrics, window); + return getSiblingPipelineSeriesFormula( + currentMetric.type, + currentMetric, + metrics, + reducedTimeRange + ); } case 'count': { return `${aggFormula}()`; @@ -98,12 +103,12 @@ export const getFormulaEquivalent = ( case 'percentile': { return `${aggFormula}(${currentMetric.field}${ metaValue ? `, percentile=${metaValue}` : '' - }${addTimeRangeToFormula(window)})`; + }${addTimeRangeToFormula(reducedTimeRange)})`; } case 'percentile_rank': { return `${aggFormula}(${currentMetric.field}${ metaValue ? `, value=${metaValue}` : '' - }${addTimeRangeToFormula(window)})`; + }${addTimeRangeToFormula(reducedTimeRange)})`; } case 'cumulative_sum': case 'derivative': @@ -122,33 +127,35 @@ export const getFormulaEquivalent = ( subFunctionMetric, pipelineAgg, currentMetric.type, - { metaValue, window } + { metaValue, reducedTimeRange } ); } case 'positive_rate': { return buildCounterRateFormula(currentMetric, currentMetric.field!); } case 'filter_ratio': { - return getFilterRatioFormula(currentMetric, window); + return getFilterRatioFormula(currentMetric, reducedTimeRange); } case 'static': { return `${currentMetric.value}`; } case 'std_deviation': { if (currentMetric.mode === 'lower') { - return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) - ${ + return `average(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)}) - ${ currentMetric.sigma || 1.5 - } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)})`; } if (currentMetric.mode === 'upper') { - return `average(${currentMetric.field}${addTimeRangeToFormula(window)}) + ${ + return `average(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)}) + ${ currentMetric.sigma || 1.5 - } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(window)})`; + } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)})`; } return `${aggFormula}(${currentMetric.field})`; } default: { - return `${aggFormula}(${currentMetric.field ?? ''}${addTimeRangeToFormula(window)})`; + return `${aggFormula}(${currentMetric.field ?? ''}${addTimeRangeToFormula( + reducedTimeRange + )})`; } } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts index cde9104e7e9c8..c74ce9713184a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts @@ -15,7 +15,7 @@ export const getParentPipelineSeriesFormula = ( subFunctionMetric: Metric, pipelineAgg: SupportedMetric, aggregation: MetricType, - { metaValue, window }: { metaValue?: number; window?: string } = {} + { metaValue, reducedTimeRange }: { metaValue?: number; reducedTimeRange?: string } = {} ) => { let formula = ''; const aggregationMap = SUPPORTED_METRICS[aggregation]; @@ -55,7 +55,7 @@ export const getParentPipelineSeriesFormula = ( } else { const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, { metaValue, - window, + reducedTimeRange, }); if (!subFormula) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts index a07cba5a99dca..83730071f7baa 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts @@ -14,7 +14,7 @@ export const getSiblingPipelineSeriesFormula = ( aggregation: MetricType, currentMetric: Metric, metrics: Metric[], - window?: string + reducedTimeRange?: string ) => { const [nestedFieldId, nestedMeta] = currentMetric.field?.split('[') ?? []; const subFunctionMetric = metrics.find((metric) => metric.id === nestedFieldId); @@ -58,7 +58,7 @@ export const getSiblingPipelineSeriesFormula = ( const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, { metaValue: nestedMetaValue, - window, + reducedTimeRange, }); if (!subFormula) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index e0688549db95a..3ac6952b561c4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -32,7 +32,7 @@ export const getMetricsColumns = ( series: Series, dataView: DataView, visibleSeriesCount: number, - window?: string + reducedTimeRange?: string ): Column[] | null => { const { metrics: validMetrics, seriesAgg } = getSeriesAgg( series.metrics as [Metric, ...Metric[]] @@ -59,7 +59,7 @@ export const getMetricsColumns = ( const percentileColumns = convertMetricsToColumns( columnsConverterArgs, convertToPercentileColumns, - window + reducedTimeRange ); return getValidColumns(percentileColumns); } @@ -67,28 +67,34 @@ export const getMetricsColumns = ( const percentileRankColumns = convertMetricsToColumns( columnsConverterArgs, convertToPercentileRankColumns, - window + reducedTimeRange ); return getValidColumns(percentileRankColumns); } case 'math': { - const formulaColumn = convertMathToFormulaColumn(columnsConverterArgs, window); + const formulaColumn = convertMathToFormulaColumn(columnsConverterArgs, reducedTimeRange); return getValidColumns(formulaColumn); } case 'derivative': case 'moving_average': { const movingAverageOrDerivativeColumns = convertParentPipelineAggToColumns( columnsConverterArgs, - window + reducedTimeRange ); return getValidColumns(movingAverageOrDerivativeColumns); } case 'cumulative_sum': { - const cumulativeSumColumns = convertToCumulativeSumColumns(columnsConverterArgs, window); + const cumulativeSumColumns = convertToCumulativeSumColumns( + columnsConverterArgs, + reducedTimeRange + ); return getValidColumns(cumulativeSumColumns); } case 'filter_ratio': { - const formulaColumn = convertFilterRatioToFormulaColumn(columnsConverterArgs, window); + const formulaColumn = convertFilterRatioToFormulaColumn( + columnsConverterArgs, + reducedTimeRange + ); return getValidColumns(formulaColumn); } case 'positive_rate': { @@ -103,30 +109,30 @@ export const getMetricsColumns = ( const formulaColumn = convertOtherAggsToFormulaColumn( aggregation, columnsConverterArgs, - window + reducedTimeRange ); return getValidColumns(formulaColumn); } case 'top_hit': { - const column = convertToLastValueColumn(columnsConverterArgs, window); + const column = convertToLastValueColumn(columnsConverterArgs, reducedTimeRange); return getValidColumns(column); } case 'static': { const column = convertToStaticValueColumn(columnsConverterArgs, { visibleSeriesCount, - window, + reducedTimeRange, }); return getValidColumns(column); } case 'std_deviation': { - const column = convertToStandartDeviationColumn(columnsConverterArgs, window); + const column = convertToStandartDeviationColumn(columnsConverterArgs, reducedTimeRange); return getValidColumns(column); } default: { const column = convertMetricAggregationColumnWithoutSpecialParams( aggregationMap, columnsConverterArgs, - window + reducedTimeRange ); return getValidColumns(column); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts index d992a199dd349..9dc37b5ba8703 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -14,7 +14,7 @@ import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getMetricsColumns, getBucketsColumns } from '../lib/series'; import { getLayers } from '../lib/configurations/xy'; -import { getWindow, isValidMetrics } from '../lib/metrics'; +import { getReducedTimeRange, isValidMetrics } from '../lib/metrics'; import { ConvertTsvbToLensVisualization } from '../types'; import { Layer as ExtendedLayer, excludeMetaFromColumn } from '../lib/convert'; @@ -52,10 +52,10 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR dataViews ); - const window = getWindow(model, series, timeRange); + const reducedTimeRange = getReducedTimeRange(model, series, timeRange); // handle multiple metrics - const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, window); + const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, reducedTimeRange); if (!metricsColumns) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index 0f0dcbf041a38..bdafc6999772d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -23,5 +23,5 @@ export interface Filter { export type ConvertToColumnsFn = ( { series: Series, metric: Metric, dataView: DataView }: CommonColumnConverterArgs, - window?: string + reducedTimeRange?: string ) => Array | null; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts index 4dcfaed3291d4..6817e216e762d 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/columns.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/columns.ts @@ -41,7 +41,7 @@ export interface BaseColumn dataType: DataType; timeScale?: TimeScaleUnit; // ? timeShift?: string; - window?: string; + reducedTimeRange?: string; isStaticValue?: boolean; filter?: FilterQuery; params: Params; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 3bc598a5fdd2b..b7a41b1a3ad1f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -235,7 +235,7 @@ function getIncompleteParams(column: Column) { filter: column.filter, shift: column.timeShift, dataType: column.dataType, - ...(column.window && { window: column.window }), + ...(column.reducedTimeRange && { reducedTimeRange: column.reducedTimeRange }), }; } From f47e4cfb61387567841ebb49bc25f8c9451fbd50 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 12:43:28 +0300 Subject: [PATCH 104/129] Added test for getBucketsColumns --- .../lib/series/buckets_columns.test.ts | 210 +++++++++++++++++- 1 file changed, 208 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts index 027d5abd0dc84..5d7104cfa8fbb 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts @@ -7,8 +7,10 @@ */ import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; -import { createSeries } from '../__mocks__'; -import { isSplitWithDateHistogram } from './buckets_columns'; +import { Operations, TermsParams } from '@kbn/visualizations-plugin/common'; +import { Column } from '../convert'; +import { createPanel, createSeries } from '../__mocks__'; +import { getBucketsColumns, isSplitWithDateHistogram } from './buckets_columns'; describe('isSplitWithDateHistogram', () => { const dataView = stubLogstashDataView; @@ -48,3 +50,207 @@ describe('isSplitWithDateHistogram', () => { } }); }); + +describe('getBucketsColumns', () => { + const dataView = stubLogstashDataView; + const seriesWithoutSplitMode = createSeries({ split_mode: '' }); + const seriesWithFilterSplitMode = createSeries({ + split_mode: 'filter', + filter: { language: 'lucene', query: 'some query' }, + }); + + const seriesWithFiltersSplitMode = createSeries({ + split_mode: 'filters', + split_filters: [ + { id: 'filter1', label: 'filter label', filter: { language: 'lucene', query: 'some query' } }, + ], + }); + + const seriesWithTermsSplitMode = createSeries({ + split_mode: 'terms', + terms_field: [dataView.fields[2].name], + }); + const seriesWithTermsSplitModeAndMultipleTermsFields = createSeries({ + split_mode: 'terms', + terms_field: [dataView.fields[0].name, dataView.fields[2].name], + }); + const seriesWithTermsSplitModeAndEmptySplitFields = createSeries({ + split_mode: 'terms', + terms_field: undefined, + }); + const series = createSeries({ + terms_field: [dataView.fields[0].name, dataView.fields[1].name], + split_mode: 'terms', + }); + + const metricId1 = 'metric-id-1'; + const metricId2 = 'metric-id-2'; + const columns: Column[] = [ + { + operationType: Operations.AVERAGE, + sourceField: dataView.fields[0].name, + columnId: 'some-id-0', + dataType: 'number', + params: {}, + meta: { metricId: metricId1 }, + isSplit: false, + isBucketed: true, + }, + { + operationType: Operations.SUM, + sourceField: dataView.fields[0].name, + columnId: 'some-id-1', + dataType: 'number', + params: {}, + meta: { metricId: metricId2 }, + isSplit: false, + isBucketed: true, + }, + ]; + test.each< + [ + string, + Parameters, + Array & { params: Partial }>> | null + ] + >([ + [ + 'empty array if split_mode is not set', + [ + createPanel({ series: [seriesWithoutSplitMode] }), + seriesWithoutSplitMode, + columns, + dataView, + ], + [], + ], + [ + 'filters column if split_mode is filter', + [ + createPanel({ series: [seriesWithFilterSplitMode] }), + seriesWithFilterSplitMode, + columns, + dataView, + ], + [ + { + dataType: 'string', + isBucketed: true, + isSplit: true, + operationType: 'filters', + params: { filters: [{ input: { language: 'lucene', query: 'some query' }, label: '' }] }, + }, + ], + ], + [ + 'filters column if split_mode is filters', + [ + createPanel({ series: [seriesWithFiltersSplitMode] }), + seriesWithFiltersSplitMode, + columns, + dataView, + ], + [ + { + dataType: 'string', + isBucketed: true, + isSplit: true, + operationType: 'filters', + params: { + filters: [ + { input: { language: 'lucene', query: 'some query' }, label: 'filter label' }, + ], + }, + }, + ], + ], + [ + 'datehistogram column if split_mode is terms and terms_field contains single field which is date', + [ + createPanel({ series: [seriesWithTermsSplitMode] }), + seriesWithTermsSplitMode, + columns, + dataView, + ], + [ + { + dataType: 'date', + isBucketed: true, + isSplit: true, + operationType: 'date_histogram', + params: { dropPartials: false, includeEmptyRows: true, interval: 'auto' }, + sourceField: '@timestamp', + }, + ], + ], + [ + 'null if split_mode is terms and terms_field contains date field and others (unsupported)', + [ + createPanel({ series: [seriesWithTermsSplitModeAndMultipleTermsFields] }), + seriesWithTermsSplitModeAndMultipleTermsFields, + columns, + dataView, + ], + null, + ], + [ + 'null if split_mode is terms and terms_field is empty (unsupported)', + [ + createPanel({ series: [seriesWithTermsSplitModeAndEmptySplitFields] }), + seriesWithTermsSplitModeAndEmptySplitFields, + columns, + dataView, + ], + null, + ], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(getBucketsColumns(...input)).toBeNull(); + } else if (Array.isArray(expected)) { + expect(getBucketsColumns(...input)).toEqual(expected.map(expect.objectContaining)); + } else { + expect(getBucketsColumns(...input)).toEqual(expect.objectContaining(expected)); + } + }); + + test("should return terms column if split_mode is terms and terms_field doesn't contain date field", () => { + const result = getBucketsColumns(createPanel({ series: [series] }), series, columns, dataView); + + expect(Array.isArray(result)).toBeTruthy(); + expect(result?.length).toBe(1); + expect(result?.[0]).toEqual( + expect.objectContaining({ + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'terms', + params: expect.objectContaining({ + excludeIsRegex: false, + format: { id: 'bytes' }, + includeIsRegex: false, + orderAgg: expect.objectContaining({ + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'count', + params: {}, + sourceField: 'document', + }), + orderBy: expect.objectContaining({ type: 'column' }), + orderDirection: 'desc', + otherBucket: false, + parentFormat: { id: 'terms' }, + secondaryFields: ['ssl'], + size: 10, + }), + sourceField: 'bytes', + }) + ); + const params = result?.[0].params as TermsParams; + expect(params.orderAgg).not.toBeNull(); + expect(typeof params.orderAgg === 'object').toBeTruthy(); + expect(params.orderAgg?.columnId).toEqual( + (params.orderBy as { columnId: string; type: 'column' }).columnId + ); + }); +}); From d0417824081c936f19a8013c054ff30555e33c62 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 13:24:13 +0300 Subject: [PATCH 105/129] Fixed tests for parent_pipeline. --- .../convert_to_lens/lib/convert/parent_pipeline.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index fcd569ef59c5e..2db0615d208ce 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -224,7 +224,7 @@ describe('convertMetricAggregationToColumn', () => { [ SUPPORTED_METRICS.percentile, { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, - { metaValue: 50, window: '10m' }, + { metaValue: 50, reducedTimeRange: '10m' }, ], { meta: { metricId: 'some-id' }, @@ -259,7 +259,7 @@ describe('convertMetricAggregationToColumn', () => { [ SUPPORTED_METRICS.percentile_rank, { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE_RANK }, dataView }, - { metaValue: 50, window: '10m' }, + { metaValue: 50, reducedTimeRange: '10m' }, ], { meta: { metricId: 'some-id' }, From 42ab0339d9298ed95761df11015cfbcbaef0ba73 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 13:24:46 +0300 Subject: [PATCH 106/129] Added tests for getValidColumns --- .../lib/series/columns.test.ts | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.test.ts new file mode 100644 index 0000000000000..ea299b00cb3c8 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/columns.test.ts @@ -0,0 +1,51 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { Operations } from '@kbn/visualizations-plugin/common'; +import { Column } from '../convert'; +import { getValidColumns } from './columns'; + +describe('getValidColumns', () => { + const dataView = stubLogstashDataView; + const columns: Column[] = [ + { + operationType: Operations.AVERAGE, + sourceField: dataView.fields[0].name, + columnId: 'some-id-0', + dataType: 'number', + params: {}, + meta: { metricId: 'metric-0' }, + isSplit: false, + isBucketed: true, + }, + { + operationType: Operations.SUM, + sourceField: dataView.fields[0].name, + columnId: 'some-id-1', + dataType: 'number', + params: {}, + meta: { metricId: 'metric-1' }, + isSplit: false, + isBucketed: true, + }, + ]; + test.each<[string, Parameters, Column[] | null]>([ + ['null if array contains null', [[null, ...columns]], null], + ['null if columns is null', [null], null], + ['null if columns is undefined', [undefined], null], + ['columns', [columns], columns], + ['columns if one column is passed', [columns[0]], [columns[0]]], + ])('should return %s', (_, input, expected) => { + if (expected === null) { + expect(getValidColumns(...input)).toBeNull(); + } else { + expect(getValidColumns(...input)).toEqual(expect.objectContaining(expected)); + } + }); +}); From b5f55f2b4c21f41222748038add94d136bbf6c00 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 30 Aug 2022 14:07:41 +0300 Subject: [PATCH 107/129] Added tests for getMetricsColumns --- .../lib/series/metrics_columns.test.ts | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts new file mode 100644 index 0000000000000..9df7e23f67b92 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts @@ -0,0 +1,184 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import { createSeries } from '../__mocks__'; +import { getMetricsColumns } from './metrics_columns'; + +const mockConvertMetricsToColumns = jest.fn(); +const mockConvertMathToFormulaColumn = jest.fn(); +const mockConvertParentPipelineAggToColumns = jest.fn(); +const mockConvertToCumulativeSumColumns = jest.fn(); +const mockConvertFilterRatioToFormulaColumn = jest.fn(); +const mockConvertToCounterRateFormulaColumn = jest.fn(); +const mockConvertOtherAggsToFormulaColumn = jest.fn(); +const mockConvertToLastValueColumn = jest.fn(); +const mockConvertToStaticValueColumn = jest.fn(); +const mockConvertToStandartDeviationColumn = jest.fn(); +const mockConvertMetricAggregationColumnWithoutSpecialParams = jest.fn(); + +jest.mock('../convert', () => ({ + convertMetricsToColumns: jest.fn(() => mockConvertMetricsToColumns()), + convertMathToFormulaColumn: jest.fn(() => mockConvertMathToFormulaColumn()), + convertParentPipelineAggToColumns: jest.fn(() => mockConvertParentPipelineAggToColumns()), + convertToCumulativeSumColumns: jest.fn(() => mockConvertToCumulativeSumColumns()), + convertFilterRatioToFormulaColumn: jest.fn(() => mockConvertFilterRatioToFormulaColumn()), + convertToCounterRateFormulaColumn: jest.fn(() => mockConvertToCounterRateFormulaColumn()), + convertOtherAggsToFormulaColumn: jest.fn(() => mockConvertOtherAggsToFormulaColumn()), + convertToLastValueColumn: jest.fn(() => mockConvertToLastValueColumn()), + convertToStaticValueColumn: jest.fn(() => mockConvertToStaticValueColumn()), + convertToStandartDeviationColumn: jest.fn(() => mockConvertToStandartDeviationColumn()), + convertMetricAggregationColumnWithoutSpecialParams: jest.fn(() => + mockConvertMetricAggregationColumnWithoutSpecialParams() + ), +})); + +describe('getMetricsColumns', () => { + const dataView = stubLogstashDataView; + test.each<[string, Parameters, typeof jest.fn | null]>([ + [ + 'return null if metric type is not supported', + [ + createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.SUM_OF_SQUARES, id: '1' }] }), + dataView, + 1, + ], + null, + ], + [ + 'return null if metric type is series agg and split mode is not "everything"', + [ + createSeries({ + metrics: [ + { type: TSVB_METRIC_TYPES.STD_DEVIATION, id: '1' }, + { type: TSVB_METRIC_TYPES.SERIES_AGG, id: '1' }, + ], + split_mode: 'terms', + }), + dataView, + 1, + ], + null, + ], + [ + 'call convertMetricsToColumns if metric type is percentile', + [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.PERCENTILE, id: '1' }] }), dataView, 1], + mockConvertMetricsToColumns, + ], + [ + 'call convertMetricsToColumns if metric type is percentile rank', + [ + createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.PERCENTILE_RANK, id: '1' }] }), + dataView, + 1, + ], + mockConvertMetricsToColumns, + ], + [ + 'call convertMathToFormulaColumn if metric type is math', + [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.MATH, id: '1' }] }), dataView, 1], + mockConvertMathToFormulaColumn, + ], + [ + 'call convertParentPipelineAggToColumns if metric type is moving average', + [ + createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.MOVING_AVERAGE, id: '1' }] }), + dataView, + 1, + ], + mockConvertParentPipelineAggToColumns, + ], + [ + 'call convertParentPipelineAggToColumns if metric type is derivative', + [createSeries({ metrics: [{ type: METRIC_TYPES.DERIVATIVE, id: '1' }] }), dataView, 1], + mockConvertParentPipelineAggToColumns, + ], + [ + 'call convertToCumulativeSumColumns if metric type is cumulative sum', + [createSeries({ metrics: [{ type: METRIC_TYPES.CUMULATIVE_SUM, id: '1' }] }), dataView, 1], + mockConvertToCumulativeSumColumns, + ], + [ + 'call convertFilterRatioToFormulaColumn if metric type is filter ratio', + [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.FILTER_RATIO, id: '1' }] }), dataView, 1], + mockConvertFilterRatioToFormulaColumn, + ], + [ + 'call convertToCounterRateFormulaColumn if metric type is positive rate', + [ + createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.POSITIVE_RATE, id: '1' }] }), + dataView, + 1, + ], + mockConvertToCounterRateFormulaColumn, + ], + [ + 'call convertOtherAggsToFormulaColumn if metric type is positive only', + [ + createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.POSITIVE_ONLY, id: '1' }] }), + dataView, + 1, + ], + mockConvertOtherAggsToFormulaColumn, + ], + [ + 'call convertOtherAggsToFormulaColumn if metric type is average bucket', + [createSeries({ metrics: [{ type: METRIC_TYPES.AVG_BUCKET, id: '1' }] }), dataView, 1], + mockConvertOtherAggsToFormulaColumn, + ], + [ + 'call convertOtherAggsToFormulaColumn if metric type is max bucket', + [createSeries({ metrics: [{ type: METRIC_TYPES.MAX_BUCKET, id: '1' }] }), dataView, 1], + mockConvertOtherAggsToFormulaColumn, + ], + [ + 'call convertOtherAggsToFormulaColumn if metric type is min bucket', + [createSeries({ metrics: [{ type: METRIC_TYPES.MIN_BUCKET, id: '1' }] }), dataView, 1], + mockConvertOtherAggsToFormulaColumn, + ], + [ + 'call convertOtherAggsToFormulaColumn if metric type is sum only', + [createSeries({ metrics: [{ type: METRIC_TYPES.SUM_BUCKET, id: '1' }] }), dataView, 1], + mockConvertOtherAggsToFormulaColumn, + ], + [ + 'call convertToLastValueColumn if metric type is top hit', + [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.TOP_HIT, id: '1' }] }), dataView, 1], + mockConvertToLastValueColumn, + ], + [ + 'call convertToStaticValueColumn if metric type is static', + [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.STATIC, id: '1' }] }), dataView, 1], + mockConvertToStaticValueColumn, + ], + [ + 'call convertToStandartDeviationColumn if metric type is standart deviation', + [ + createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.STD_DEVIATION, id: '1' }] }), + dataView, + 1, + ], + mockConvertToStandartDeviationColumn, + ], + [ + 'call convertMetricAggregationColumnWithoutSpecialParams if metric type is another supported type', + [createSeries({ metrics: [{ type: METRIC_TYPES.AVG, id: '1' }] }), dataView, 1], + mockConvertMetricAggregationColumnWithoutSpecialParams, + ], + ])('should %s', (_, input, expected) => { + if (expected === null) { + expect(getMetricsColumns(...input)).toBeNull(); + } else { + getMetricsColumns(...input); + expect(expected).toHaveBeenCalledTimes(1); + (expected as jest.Mock).mockClear(); + } + }); +}); From d63061f4ce1503cff9df0561c997368c0e57381d Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 14:34:37 +0300 Subject: [PATCH 108/129] Removed empty new.index.ts of top_n. --- .../timeseries/public/convert_to_lens/top_n/new.index.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/new.index.ts deleted file mode 100644 index e69de29bb2d1d..0000000000000 From 689b52bfd104eeedffa98dd1ab2bde124861ff3f Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 14:52:16 +0300 Subject: [PATCH 109/129] Configuration refactored. --- .../lib/configurations/xy/configuration.ts | 68 +++++++++++++++++++ .../lib/configurations/xy/index.ts | 1 + .../convert_to_lens/timeseries/index.ts | 27 ++------ .../public/convert_to_lens/top_n/index.ts | 31 +-------- 4 files changed, 76 insertions(+), 51 deletions(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts new file mode 100644 index 0000000000000..b28e3767135c4 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts @@ -0,0 +1,68 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Position } from '@elastic/charts'; +import { XYConfiguration, XYLayerConfig } from '@kbn/visualizations-plugin/common'; +import { Panel } from '../../../../../common/types'; +import { getYExtents } from './extents'; + +export const getConfigurationForTimeseries = ( + model: Panel, + layers: XYLayerConfig[] +): XYConfiguration => { + const extents = getYExtents(model); + return { + layers, + fillOpacity: Number(model.series[0].fill) ?? 0.3, + legend: { + isVisible: Boolean(model.show_legend), + showSingleSeries: Boolean(model.show_legend), + position: (model.legend_position as Position) ?? Position.Right, + shouldTruncate: Boolean(model.truncate_legend), + maxLines: model.max_lines_legend ?? 1, + }, + gridlinesVisibilitySettings: { + x: Boolean(model.show_grid), + yLeft: Boolean(model.show_grid), + yRight: Boolean(model.show_grid), + }, + yLeftExtent: extents.yLeftExtent, + yRightExtent: extents.yRightExtent, + }; +}; + +export const getConfigurationForTopN = ( + model: Panel, + layers: XYLayerConfig[] +): XYConfiguration => ({ + layers, + fillOpacity: Number(model.series[0].fill) ?? 0.3, + legend: { + isVisible: Boolean(model.show_legend), + showSingleSeries: Boolean(model.show_legend), + position: (model.legend_position as Position) ?? Position.Right, + shouldTruncate: Boolean(model.truncate_legend), + maxLines: model.max_lines_legend ?? 1, + }, + gridlinesVisibilitySettings: { + x: false, + yLeft: false, + yRight: false, + }, + tickLabelsVisibilitySettings: { + x: true, + yLeft: false, + yRight: false, + }, + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: false, + }, + valueLabels: 'show', +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/index.ts index 7a2586d4c45da..6850e669c6dcc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/index.ts @@ -9,3 +9,4 @@ export * from './layers'; export * from './extents'; export * from './chart_type'; +export * from './configuration'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index cc0b68df24a2a..3f6e59ed1f0d1 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { Position } from '@elastic/charts'; import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import { Panel } from '../../../common/types'; @@ -14,7 +13,10 @@ import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getMetricsColumns, getBucketsColumns } from '../lib/series'; -import { getLayers, getYExtents } from '../lib/configurations/xy'; +import { + getConfigurationForTimeseries as getConfiguration, + getLayers, +} from '../lib/configurations/xy'; import { Layer as ExtendedLayer, convertToDateHistogramColumn, @@ -88,28 +90,9 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model: Panel }; } - const extents = getYExtents(model); - return { type: 'lnsXY', layers: Object.values(excludeMetaFromLayers(extendedLayers)), - configuration: { - layers: getLayers(extendedLayers, model), - fillOpacity: Number(model.series[0].fill) ?? 0.3, - legend: { - isVisible: Boolean(model.show_legend), - showSingleSeries: Boolean(model.show_legend), - position: (model.legend_position as Position) ?? Position.Right, - shouldTruncate: Boolean(model.truncate_legend), - maxLines: model.max_lines_legend ?? 1, - }, - gridlinesVisibilitySettings: { - x: Boolean(model.show_grid), - yLeft: Boolean(model.show_grid), - yRight: Boolean(model.show_grid), - }, - yLeftExtent: extents.yLeftExtent, - yRightExtent: extents.yRightExtent, - }, + configuration: getConfiguration(model, getLayers(extendedLayers, model)), }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts index 9dc37b5ba8703..137f457bad307 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -8,12 +8,11 @@ import uuid from 'uuid'; import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { Position } from '@elastic/charts'; import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; import { getDataSourceInfo } from '../lib/datasource'; import { getMetricsColumns, getBucketsColumns } from '../lib/series'; -import { getLayers } from '../lib/configurations/xy'; +import { getConfigurationForTopN as getConfiguration, getLayers } from '../lib/configurations/xy'; import { getReducedTimeRange, isValidMetrics } from '../lib/metrics'; import { ConvertTsvbToLensVisualization } from '../types'; import { Layer as ExtendedLayer, excludeMetaFromColumn } from '../lib/convert'; @@ -77,32 +76,6 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR return { type: 'lnsXY', layers: Object.values(excludeMetaFromLayers(extendedLayers)), - configuration: { - layers: getLayers(extendedLayers, model), - fill: model.series[0].fill ?? 0.3, - legend: { - isVisible: Boolean(model.show_legend), - showSingleSeries: Boolean(model.show_legend), - position: (model.legend_position as Position) ?? Position.Right, - shouldTruncate: Boolean(model.truncate_legend), - maxLines: model.max_lines_legend ?? 1, - }, - gridlinesVisibilitySettings: { - x: false, - yLeft: false, - yRight: false, - }, - tickLabelsVisibilitySettings: { - x: true, - yLeft: false, - yRight: false, - }, - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: false, - }, - valueLabels: 'show', - }, + configuration: getConfiguration(model, getLayers(extendedLayers, model)), }; }; From 6c7fbbdc402d177ca823f8e1e9fe32806d59df5d Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 30 Aug 2022 15:06:45 +0300 Subject: [PATCH 110/129] Added tests for getConfigurationForTimeseries and getConfigurationForTopN --- .../configurations/xy/configuration.test.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts new file mode 100644 index 0000000000000..ae3f75bf5905d --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts @@ -0,0 +1,65 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createPanel } from '../../__mocks__'; +import { getConfigurationForTopN, getConfigurationForTimeseries } from './configuration'; + +describe('getConfigurationForTimeseries', () => { + test('should return correct configuration for timeseries', () => { + expect(getConfigurationForTimeseries(createPanel(), [])).toEqual({ + layers: [], + fillOpacity: 0.5, + legend: { + isVisible: false, + showSingleSeries: false, + position: 'right', + shouldTruncate: false, + maxLines: 1, + }, + gridlinesVisibilitySettings: { + x: false, + yLeft: false, + yRight: false, + }, + yLeftExtent: { mode: 'full' }, + yRightExtent: { mode: 'full' }, + }); + }); +}); + +describe('getConfigurationForTopN', () => { + test('should return correct configuration for top n', () => { + expect(getConfigurationForTopN(createPanel(), [])).toEqual({ + layers: [], + fillOpacity: 0.5, + legend: { + isVisible: false, + showSingleSeries: false, + position: 'right', + shouldTruncate: false, + maxLines: 1, + }, + gridlinesVisibilitySettings: { + x: false, + yLeft: false, + yRight: false, + }, + tickLabelsVisibilitySettings: { + x: true, + yLeft: false, + yRight: false, + }, + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: false, + }, + valueLabels: 'show', + }); + }); +}); From 0fe7efc944d3676e93dfc680101f72bf362bda1d Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 16:08:56 +0300 Subject: [PATCH 111/129] Added tests for timeseries/index.ts --- .../convert_to_lens/timeseries/index.test.ts | 138 ++++++++++++++++++ .../convert_to_lens/timeseries/index.ts | 2 +- 2 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts new file mode 100644 index 0000000000000..a6460e2917ba9 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.test.ts @@ -0,0 +1,138 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { convertToLens } from '.'; +import { createPanel, createSeries } from '../lib/__mocks__'; + +const mockConvertToDateHistogramColumn = jest.fn(); +const mockGetMetricsColumns = jest.fn(); +const mockGetBucketsColumns = jest.fn(); +const mockGetConfigurationForTimeseries = jest.fn(); +const mockIsValidMetrics = jest.fn(); +const mockGetDatasourceValue = jest + .fn() + .mockImplementation(() => Promise.resolve(stubLogstashDataView)); +const mockGetDataSourceInfo = jest.fn(); + +jest.mock('../../services', () => ({ + getDataViewsStart: jest.fn(() => mockGetDatasourceValue), +})); + +jest.mock('../lib/convert', () => ({ + convertToDateHistogramColumn: jest.fn(() => mockConvertToDateHistogramColumn()), + excludeMetaFromColumn: jest.fn().mockReturnValue({}), +})); + +jest.mock('../lib/series', () => ({ + getMetricsColumns: jest.fn(() => mockGetMetricsColumns()), + getBucketsColumns: jest.fn(() => mockGetBucketsColumns()), +})); + +jest.mock('../lib/configurations/xy', () => ({ + getConfigurationForTimeseries: jest.fn(() => mockGetConfigurationForTimeseries()), + getLayers: jest.fn().mockReturnValue([]), +})); + +jest.mock('../lib/metrics', () => ({ + isValidMetrics: jest.fn(() => mockIsValidMetrics()), +})); + +jest.mock('../lib/datasource', () => ({ + getDataSourceInfo: jest.fn(() => mockGetDataSourceInfo()), +})); + +describe('convertToLens', () => { + const model = createPanel({ + series: [ + createSeries({ + metrics: [ + { id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }, + { id: 'some-id-1', type: METRIC_TYPES.COUNT }, + ], + }), + ], + }); + + beforeEach(() => { + mockIsValidMetrics.mockReturnValue(true); + mockGetDataSourceInfo.mockReturnValue({ + indexPatternId: 'test-index-pattern', + timeField: 'timeField', + indexPattern: { id: 'test-index-pattern' }, + }); + mockConvertToDateHistogramColumn.mockReturnValue({}); + mockGetMetricsColumns.mockReturnValue([{}]); + mockGetBucketsColumns.mockReturnValue([{}]); + mockGetConfigurationForTimeseries.mockReturnValue({}); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('should return null for invalid metrics', async () => { + mockIsValidMetrics.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockIsValidMetrics).toBeCalledTimes(1); + }); + + test('should return null for empty time field', async () => { + mockGetDataSourceInfo.mockReturnValue({ timeField: null }); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockGetDataSourceInfo).toBeCalledTimes(1); + }); + + test('should return null for invalid date histogram', async () => { + mockConvertToDateHistogramColumn.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockConvertToDateHistogramColumn).toBeCalledTimes(1); + }); + + test('should return null for invalid or unsupported metrics', async () => { + mockGetMetricsColumns.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockGetMetricsColumns).toBeCalledTimes(1); + }); + + test('should return null for invalid or unsupported buckets', async () => { + mockGetBucketsColumns.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockGetBucketsColumns).toBeCalledTimes(1); + }); + + test('should return state for valid model', async () => { + const result = await convertToLens(model); + expect(result).toBeDefined(); + expect(result?.type).toBe('lnsXY'); + expect(mockGetBucketsColumns).toBeCalledTimes(model.series.length); + expect(mockGetConfigurationForTimeseries).toBeCalledTimes(1); + }); + + test('should skip hidden series', async () => { + const result = await convertToLens( + createPanel({ + series: [ + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: true, + }), + ], + }) + ); + expect(result).toBeDefined(); + expect(result?.type).toBe('lnsXY'); + expect(mockIsValidMetrics).toBeCalledTimes(0); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index 3f6e59ed1f0d1..6cda563b6d85a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -72,7 +72,7 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model: Panel } // handle multiple metrics const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum); - if (!metricsColumns) { + if (metricsColumns === null) { return null; } From da895919a559df2fff18fc38dc98fca42a556aaf Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 16:14:39 +0300 Subject: [PATCH 112/129] Added test for top_n. --- .../convert_to_lens/top_n/index.test.ts | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts new file mode 100644 index 0000000000000..7e4776f10ac9f --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.test.ts @@ -0,0 +1,122 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { convertToLens } from '.'; +import { createPanel, createSeries } from '../lib/__mocks__'; + +const mockGetMetricsColumns = jest.fn(); +const mockGetBucketsColumns = jest.fn(); +const mockGetConfigurationForTopN = jest.fn(); +const mockIsValidMetrics = jest.fn(); +const mockGetDatasourceValue = jest + .fn() + .mockImplementation(() => Promise.resolve(stubLogstashDataView)); +const mockGetDataSourceInfo = jest.fn(); + +jest.mock('../../services', () => ({ + getDataViewsStart: jest.fn(() => mockGetDatasourceValue), +})); + +jest.mock('../lib/convert', () => ({ + excludeMetaFromColumn: jest.fn().mockReturnValue({}), +})); + +jest.mock('../lib/series', () => ({ + getMetricsColumns: jest.fn(() => mockGetMetricsColumns()), + getBucketsColumns: jest.fn(() => mockGetBucketsColumns()), +})); + +jest.mock('../lib/configurations/xy', () => ({ + getConfigurationForTopN: jest.fn(() => mockGetConfigurationForTopN()), + getLayers: jest.fn().mockReturnValue([]), +})); + +jest.mock('../lib/metrics', () => ({ + isValidMetrics: jest.fn(() => mockIsValidMetrics()), + getReducedTimeRange: jest.fn().mockReturnValue('10'), +})); + +jest.mock('../lib/datasource', () => ({ + getDataSourceInfo: jest.fn(() => mockGetDataSourceInfo()), +})); + +describe('convertToLens', () => { + const model = createPanel({ + series: [ + createSeries({ + metrics: [ + { id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }, + { id: 'some-id-1', type: METRIC_TYPES.COUNT }, + ], + }), + ], + }); + + beforeEach(() => { + mockIsValidMetrics.mockReturnValue(true); + mockGetDataSourceInfo.mockReturnValue({ + indexPatternId: 'test-index-pattern', + timeField: 'timeField', + indexPattern: { id: 'test-index-pattern' }, + }); + mockGetMetricsColumns.mockReturnValue([{}]); + mockGetBucketsColumns.mockReturnValue([{}]); + mockGetConfigurationForTopN.mockReturnValue({}); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('should return null for invalid metrics', async () => { + mockIsValidMetrics.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockIsValidMetrics).toBeCalledTimes(1); + }); + + test('should return null for invalid or unsupported metrics', async () => { + mockGetMetricsColumns.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockGetMetricsColumns).toBeCalledTimes(1); + }); + + test('should return null for invalid or unsupported buckets', async () => { + mockGetBucketsColumns.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockGetBucketsColumns).toBeCalledTimes(1); + }); + + test('should return state for valid model', async () => { + const result = await convertToLens(model); + expect(result).toBeDefined(); + expect(result?.type).toBe('lnsXY'); + expect(mockGetBucketsColumns).toBeCalledTimes(model.series.length); + expect(mockGetConfigurationForTopN).toBeCalledTimes(1); + }); + + test('should skip hidden series', async () => { + const result = await convertToLens( + createPanel({ + series: [ + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: true, + }), + ], + }) + ); + expect(result).toBeDefined(); + expect(result?.type).toBe('lnsXY'); + expect(mockIsValidMetrics).toBeCalledTimes(0); + }); +}); From 2a04190eb51105b680533090ec5afa93eb3750e7 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 30 Aug 2022 16:54:14 +0300 Subject: [PATCH 113/129] Refactored getSuggestionFromConvertToLensContext at suggestion_helpers. --- .../editor_frame/suggestion_helpers.ts | 34 +++---------------- x-pack/plugins/lens/public/types.ts | 9 +++++ .../visualizations/xy/visualization.tsx | 30 +++++++++++++++- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts index 0b91cf7ec740d..ce041098ab241 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts @@ -170,12 +170,6 @@ export function getSuggestions({ .sort((a, b) => b.score - a.score); } -function isDataSourceWithLayers(datasourceState: object): datasourceState is { - layers: Record; -} { - return 'layers' in datasourceState; -} - export function getVisualizeFieldSuggestions({ datasourceMap, datasourceStates, @@ -205,30 +199,10 @@ export function getVisualizeFieldSuggestions({ const allSuggestions = suggestions.filter( (s) => s.visualizationId === visualizeTriggerFieldContext.type ); - return { - ...allSuggestions[0], - datasourceState: { - ...(typeof allSuggestions[0].datasourceState === 'object' - ? allSuggestions[0].datasourceState - : {}), - layers: allSuggestions.reduce((acc, s) => { - return { - ...acc, - ...(typeof s.datasourceState === 'object' && - s.datasourceState !== null && - isDataSourceWithLayers(s.datasourceState) - ? s.datasourceState.layers - : {}), - }; - }, {}), - }, - visualizationState: { - ...(typeof allSuggestions[0].visualizationState === 'object' - ? allSuggestions[0].visualizationState - : {}), - ...visualizeTriggerFieldContext.configuration, - }, - }; + return activeVisualization?.getSuggestionFromConvertToLensContext?.({ + suggestions: allSuggestions, + context: visualizeTriggerFieldContext, + }); } if (suggestions.length) { diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 8c4f602ae5aaf..d78064fbde087 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -838,6 +838,11 @@ export interface VisualizationDisplayOptions { noPadding?: boolean; } +interface VisualizationStateFromContextChangeProps { + suggestions: Suggestion[]; + context: VisualizeEditorContext; +} + export interface Visualization { /** Plugin ID, such as "lnsXY" */ id: string; @@ -1055,6 +1060,10 @@ export interface Visualization { * Get RenderEventCounters events for telemetry */ getRenderEventCounters?: (state: T) => string[]; + + getSuggestionFromConvertToLensContext?: ( + props: VisualizationStateFromContextChangeProps + ) => Suggestion; } // Use same technique as TriggerContext diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index c9f35b3d1e752..a99cbc371025c 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -23,7 +23,14 @@ import { XyToolbar } from './xy_config_panel'; import { DimensionEditor } from './xy_config_panel/dimension_editor'; import { LayerHeader } from './xy_config_panel/layer_header'; import type { Visualization, AccessorConfig, FramePublicAPI } from '../../types'; -import { State, visualizationTypes, XYLayerConfig, XYDataLayerConfig, SeriesType } from './types'; +import { + State, + visualizationTypes, + XYLayerConfig, + XYDataLayerConfig, + SeriesType, + XYSuggestion, +} from './types'; import { layerTypes } from '../../../common'; import { isHorizontalChart } from './state_helpers'; import { toExpression, toPreviewExpression, getSortedAccessors } from './to_expression'; @@ -628,6 +635,27 @@ export const getXyVisualization = ({ } return null; }, + + getSuggestionFromConvertToLensContext({ suggestions, context }) { + const allSuggestions = suggestions as XYSuggestion[]; + return { + ...allSuggestions[0], + datasourceState: { + ...allSuggestions[0].datasourceState, + layers: allSuggestions.reduce( + (acc, s) => ({ + ...acc, + ...s.datasourceState.layers, + }), + {} + ), + }, + visualizationState: { + ...allSuggestions[0].visualizationState, + ...context.configuration, + }, + }; + }, }); const getMappedAccessors = ({ From 873eac7e0f7299c05a28a79af89a82663ba1fdda Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 1 Sep 2022 12:42:59 +0300 Subject: [PATCH 114/129] Fix format --- .../lib/convert/column.test.ts | 64 ++++++++----------- .../convert_to_lens/lib/convert/column.ts | 46 ++++--------- .../convert_to_lens/lib/convert/formula.ts | 4 +- .../convert_to_lens/lib/convert/last_value.ts | 2 +- .../lib/convert/parent_pipeline.ts | 6 +- .../convert_to_lens/lib/convert/percentile.ts | 2 +- .../lib/convert/percentile_rank.ts | 2 +- .../lib/convert/static_value.ts | 2 +- .../convert_to_lens/lib/convert/terms.ts | 2 +- 9 files changed, 49 insertions(+), 81 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts index cad2fcff9cce6..0520d717c99d5 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -44,48 +44,40 @@ describe('getFormat', () => { jest.resetAllMocks(); }); - test('should return formatter of the field, if formatter is set to default', () => { - expect(getFormat(series, stubLogstashDataView.fields[0].name, stubLogstashDataView)).toEqual({ - format: { id: 'bytes' }, + test('should return formatter value, if formatter is not set to default', () => { + const formatter = 'percent'; + expect(getFormat(createSeries({ formatter }))).toEqual({ + format: { + id: formatter, + params: { + suffix: '', + }, + }, }); }); - test("should return no formatter, if a field with a specified name doesn't exist", () => { - expect(getFormat(series, 'some-other-name', stubLogstashDataView)).toEqual({}); - }); - - test('should return no formatter, if the type of the field is not supported', () => { - expect( - getFormat( - series, - dataViewWithoutSupportedFormatsFields.fields[2].name, - dataViewWithoutSupportedFormatsFields - ) - ).toEqual({}); - }); - - test('should return formatter value, if formatter is not set to default', () => { - const formatter = 'percent'; - expect( - getFormat( - createSeries({ formatter }), - stubLogstashDataView.fields[0].name, - stubLogstashDataView - ) - ).toEqual({ - format: { id: formatter }, + test('should return number formatter, if formatter is set to not supported format', () => { + const formatter = 'custom'; + expect(getFormat(createSeries({ formatter }))).toEqual({ + format: { + id: 'number', + params: { + suffix: '', + }, + }, }); }); - test('should not return formatter value, if formatter is set to not suppported format', () => { - const formatter = 'date'; - expect( - getFormat( - createSeries({ formatter }), - stubLogstashDataView.fields[0].name, - stubLogstashDataView - ) - ).toEqual({}); + test('should return formatter with suffix, if formatter template includes suffix', () => { + const formatter = 'number'; + expect(getFormat(createSeries({ formatter, value_template: '{{value}}d' }))).toEqual({ + format: { + id: 'number', + params: { + suffix: 'd', + }, + }, + }); }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index f68f86cce6e0e..ae91b3608d4be 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; +import type { DataViewField } from '@kbn/data-views-plugin/common'; import { BaseColumn, Operation, @@ -16,6 +16,7 @@ import { } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; +import { DATA_FORMATTERS } from '../../../../common/enums'; import { ConvertToColumnsFn } from '../../types'; import { getTimeScale } from '../metrics'; import { ColumnWithMeta, Meta, Column, CommonColumnsConverterArgs } from './types'; @@ -30,45 +31,22 @@ interface ExtraColumnFields { const isSupportedFormat = (format: string) => ['bytes', 'number', 'percent'].includes(format); -const findField = (series: Series, field?: string): string | undefined => { - const subMetric = series.metrics.find((m) => m.id === field); - if (subMetric) { - return findField(series, subMetric.field); - } - return field; -}; - -export const getFormat = ( - series: Series, - fieldName: string | undefined, - dataView: DataView -): FormatParams => { - if (series.formatter === 'default') { - const correctFieldName = findField(series, fieldName); - - if (!correctFieldName) { - return {}; - } - - const field = dataView.getFieldByName(correctFieldName); - if (!field) { - return {}; - } - - const formatter = dataView.getFormatterForField(field); - const id = formatter.type.id; +export const getFormat = (series: Series): FormatParams => { + let params; - if (!isSupportedFormat(id)) { - return {}; - } - return { format: { id } }; + if (series.value_template) { + const suffix = series.value_template.split('}}')[1]; + params = { + suffix, + }; } + // not supported formatters should be converted to number if (!isSupportedFormat(series.formatter)) { - return {}; + return { format: { id: DATA_FORMATTERS.NUMBER, params } }; } - return { format: { id: series.formatter } }; + return { format: { id: series.formatter, params } }; }; export const createColumn = ( diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 9ade0575054c9..44d659e18fed3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -27,14 +27,14 @@ const convertToFormulaParams = (formula: string): FormulaParams => ({ export const createFormulaColumn = ( formula: string, - { series, metric, dataView }: CommonColumnConverterArgs + { series, metric }: CommonColumnConverterArgs ): FormulaColumn | null => { const params = convertToFormulaParams(formula); return { operationType: 'formula', references: [], ...createColumn(series, metric), - params: { ...params, ...getFormat(series, metric.field, dataView) }, + params: { ...params, ...getFormat(series) }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index e50ab9ff33c68..e488a8d6fbfdb 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -40,7 +40,7 @@ export const convertToLastValueColumn = ( ...createColumn(series, currentMetric, undefined, { reducedTimeRange }), params: { ...convertToLastValueParams(currentMetric), - ...getFormat(series, currentMetric.field, dataView), + ...getFormat(series), }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 687bcb128b330..99d277f6446e6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -132,7 +132,7 @@ export const convertMetricAggregationColumnWithoutSpecialParams = ( operationType: aggregation.name, sourceField, ...createColumn(series, metric, field, { reducedTimeRange }), - params: { ...getFormat(series, field?.name, dataView) }, + params: { ...getFormat(series) }, } as MetricAggregationColumnWithoutSpecialParams; }; @@ -289,9 +289,7 @@ export const createParentPipelineAggregationColumn = ( references: string[] = [] ) => { const params = - aggregation === 'moving_average' - ? convertToMovingAverageParams(metric) - : getFormat(series, metric.field, dataView); + aggregation === 'moving_average' ? convertToMovingAverageParams(metric) : getFormat(series); return { operationType: aggregation, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index 676a5c6907d64..f008c87928194 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -48,7 +48,7 @@ export const convertToPercentileColumn = ( operationType: 'percentile', sourceField: field.name, ...commonColumnParams, - params: { ...params, ...getFormat(series, metric.field, dataView) }, + params: { ...params, ...getFormat(series) }, meta: index !== undefined ? { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index d0a838d8f0fd5..9c2578d3ff0e3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -55,7 +55,7 @@ export const convertToPercentileRankColumn = ( operationType: 'percentile_rank', sourceField: field.name, ...commonColumnParams, - params: { ...params, ...getFormat(series, metric.field, dataView) }, + params: { ...params, ...getFormat(series) }, meta: index !== undefined ? { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index 649198e549687..c4400f72b289b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -33,7 +33,7 @@ export const convertToStaticValueColumn = ( ...createColumn(series, currentMetric, undefined, { reducedTimeRange }), params: { ...convertToStaticValueParams(currentMetric), - ...getFormat(series, currentMetric.field, dataView), + ...getFormat(series), }, }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts index 580094603ed72..3c14efa4f1d6c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts @@ -109,6 +109,6 @@ export const converToTermsColumn = ( sourceField: field.name, isBucketed: true, isSplit, - params: { ...params, ...getFormat(series, field.name, dataView) }, + params: { ...params, ...getFormat(series) }, }; }; From e3b98a242cd17db3f4bf3caed3c3ff8d7640ecda Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 1 Sep 2022 12:58:57 +0300 Subject: [PATCH 115/129] Fix types --- .../visualizations/common/convert_to_lens/types/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/visualizations/common/convert_to_lens/types/common.ts b/src/plugins/visualizations/common/convert_to_lens/types/common.ts index 974326834ce2a..91522da911b02 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/common.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/common.ts @@ -41,7 +41,7 @@ export interface Range { export interface NumberValueFormat { id: string; params?: { - decimals: number; + decimals?: number; suffix?: string; }; } From 144a7a212933989afc393d432a48a9cd0cc9266c Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 1 Sep 2022 13:17:33 +0300 Subject: [PATCH 116/129] Remove unused code --- .../timeseries/public/convert_to_lens/lib/convert/column.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts index 0520d717c99d5..c050bfc7d16de 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -19,7 +19,6 @@ import { createColumn, excludeMetaFromColumn, getFormat, isColumnWithMeta } from import { MaxColumn } from './types'; describe('getFormat', () => { - const series = createSeries(); const dataViewWithoutSupportedFormatsFields = createStubDataView({ spec: { id: 'logstash-*', From c0b43ba2608a615fe0fbfa11303ee64cc38fcfab Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 1 Sep 2022 15:10:31 +0300 Subject: [PATCH 117/129] Fix tests --- .../convert_to_lens/lib/__mocks__/index.ts | 2 +- .../lib/convert/column.test.ts | 6 ---- .../convert_to_lens/lib/convert/column.ts | 15 ++++---- .../lib/convert/counter_rate.test.ts | 3 +- .../lib/convert/filter_ratio.test.ts | 4 +-- .../lib/convert/formula.test.ts | 13 ++----- .../lib/convert/last_value.test.ts | 4 +-- .../lib/convert/parent_pipeline.test.ts | 35 +++++++++---------- .../lib/convert/percentile.test.ts | 10 +++--- .../lib/convert/percentile_rank.test.ts | 10 +++--- .../lib/convert/std_deviation.test.ts | 6 +--- .../convert_to_lens/lib/convert/terms.test.ts | 1 - 12 files changed, 44 insertions(+), 65 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts index aa07ffe34c3d3..d27e8bdd0a2c6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/__mocks__/index.ts @@ -14,7 +14,7 @@ export const createSeries = (partialSeries?: Partial): Series => ({ chart_type: 'line', color: '#68BC00', fill: '0.5', - formatter: 'default', + formatter: '', id: '3bb3c1d2-5af8-44cc-9759-86725e34b157', label: '', line_width: 1, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts index c050bfc7d16de..2194c977ecc4d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -48,9 +48,6 @@ describe('getFormat', () => { expect(getFormat(createSeries({ formatter }))).toEqual({ format: { id: formatter, - params: { - suffix: '', - }, }, }); }); @@ -60,9 +57,6 @@ describe('getFormat', () => { expect(getFormat(createSeries({ formatter }))).toEqual({ format: { id: 'number', - params: { - suffix: '', - }, }, }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index ae91b3608d4be..1c1ed33958971 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -32,21 +32,22 @@ interface ExtraColumnFields { const isSupportedFormat = (format: string) => ['bytes', 'number', 'percent'].includes(format); export const getFormat = (series: Series): FormatParams => { - let params; + let suffix; + + if (!series.formatter) { + return {}; + } if (series.value_template) { - const suffix = series.value_template.split('}}')[1]; - params = { - suffix, - }; + suffix = series.value_template.split('}}')[1]; } // not supported formatters should be converted to number if (!isSupportedFormat(series.formatter)) { - return { format: { id: DATA_FORMATTERS.NUMBER, params } }; + return { format: { id: DATA_FORMATTERS.NUMBER, ...(suffix && { params: { suffix } }) } }; } - return { format: { id: series.formatter, params } }; + return { format: { id: series.formatter, ...(suffix && { params: { suffix } }) } }; }; export const createColumn = ( diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts index dbc06f5eec880..9e605a8fd30c0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts @@ -28,7 +28,7 @@ describe('convertToCounterRateFormulaColumn', () => { { series, metrics: [{ ...metric, field: dataView.fields[0].name }], dataView }, { operationType: 'formula', - params: { formula: 'pick_max(differences(max(bytes)), 0)', format: { id: 'bytes' } }, + params: { formula: 'pick_max(differences(max(bytes)), 0)' }, meta: { metricId: 'some-id' }, }, ], @@ -39,7 +39,6 @@ describe('convertToCounterRateFormulaColumn', () => { operationType: 'formula', params: { formula: 'pick_max(differences(max(bytes), shift=1h), 0)', - format: { id: 'bytes' }, }, meta: { metricId: 'some-id' }, }, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts index febeaed6041f0..b3238f1203da9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.test.ts @@ -50,7 +50,7 @@ describe('convertFilterRatioToFormulaColumn', () => { { meta: { metricId: metricWithMetricAgg.id }, operationType: 'formula', - params: { format: { id: 'bytes' }, formula: "count(kql='*') / count(kql='*')" }, + params: { formula: "count(kql='*') / count(kql='*')" }, }, ], [ @@ -59,7 +59,7 @@ describe('convertFilterRatioToFormulaColumn', () => { { meta: { metricId: metric.id }, operationType: 'formula', - params: { format: { id: 'bytes' }, formula: "count(kql='*') / count(kql='*')" }, + params: { formula: "count(kql='*') / count(kql='*')" }, }, ], ])('should return %s', (_, input, expected) => { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts index 6324d891f3c80..0c2d06e74ec00 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.test.ts @@ -41,7 +41,7 @@ describe('createFormulaColumn', () => { const series = createSeries(); const seriesWithValidFormatter = createSeries({ formatter: 'percent' }); - const seriesWithInvalidFormatter = createSeries({ formatter: 'date' }); + const seriesWithDefaultFormatter = createSeries({ formatter: '' }); const metric: Metric = { id: 'some-id', @@ -71,15 +71,6 @@ describe('createFormulaColumn', () => { params: { formula }, }, ], - [ - 'formula column with format of the field', - [formula, { series, metric: metricWithField, dataView }], - { - meta: { metricId: 'some-id' }, - operationType: 'formula', - params: { format: { id: 'bytes' }, formula }, - }, - ], [ 'formula column with format of series', [formula, { series: seriesWithValidFormatter, metric: metricWithField, dataView }], @@ -91,7 +82,7 @@ describe('createFormulaColumn', () => { ], [ 'formula column without format if custom formatter is not supported', - [formula, { series: seriesWithInvalidFormatter, metric: metricWithField, dataView }], + [formula, { series: seriesWithDefaultFormatter, metric: metricWithField, dataView }], { meta: { metricId: 'some-id' }, operationType: 'formula', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts index 8efc402f028d9..3aefecf61dace 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.test.ts @@ -76,7 +76,7 @@ describe('convertToLastValueColumn', () => { { meta: { metricId: 'some-id-0' }, operationType: 'last_value', - params: { format: { id: 'bytes' }, showArrayValues: false, sortField: '@timestamp' }, + params: { showArrayValues: false, sortField: '@timestamp' }, }, ], [ @@ -85,7 +85,7 @@ describe('convertToLastValueColumn', () => { { meta: { metricId: 'some-id-0' }, operationType: 'last_value', - params: { format: { id: 'bytes' }, showArrayValues: false, sortField: '@timestamp' }, + params: { showArrayValues: false, sortField: '@timestamp' }, reducedTimeRange: '10m', }, ], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index 2db0615d208ce..61f48f4c94149 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -88,7 +88,7 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { { meta: { metricId: 'some-id' }, operationType: 'average', - params: { format: { id: 'bytes' } }, + params: {}, }, ], [ @@ -97,7 +97,7 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { { meta: { metricId: 'some-id' }, operationType: 'unique_count', - params: { format: { id: 'bytes' } }, + params: {}, }, ], [ @@ -106,7 +106,7 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { { meta: { metricId: 'some-id' }, operationType: 'max', - params: { format: { id: 'bytes' } }, + params: {}, }, ], [ @@ -115,7 +115,7 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { { meta: { metricId: 'some-id' }, operationType: 'min', - params: { format: { id: 'bytes' } }, + params: {}, }, ], [ @@ -124,7 +124,7 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { { meta: { metricId: 'some-id' }, operationType: 'sum', - params: { format: { id: 'bytes' } }, + params: {}, }, ], [ @@ -133,7 +133,7 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { { meta: { metricId: 'some-id' }, operationType: 'standard_deviation', - params: { format: { id: 'bytes' } }, + params: {}, }, ], ])('should return column for metric %s with valid field', (_, operation, expected) => { @@ -216,11 +216,11 @@ describe('convertMetricAggregationToColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'percentile', - params: { format: { id: 'bytes' }, percentile: 50 }, + params: { percentile: 50 }, }, ], [ - 'percentile column for percentile if metaValue is set and window is passed', + 'percentile column for percentile if metaValue is set and reducedTimeRange is passed', [ SUPPORTED_METRICS.percentile, { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE }, dataView }, @@ -229,7 +229,7 @@ describe('convertMetricAggregationToColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'percentile', - params: { format: { id: 'bytes' }, percentile: 50 }, + params: { percentile: 50 }, reducedTimeRange: '10m', }, ], @@ -251,11 +251,11 @@ describe('convertMetricAggregationToColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'percentile_rank', - params: { format: { id: 'bytes' }, value: 50 }, + params: { value: 50 }, }, ], [ - 'percentile rank column for percentile rank if metaValue is set and window is passed', + 'percentile rank column for percentile rank if metaValue is set and reducedTimeRange is passed', [ SUPPORTED_METRICS.percentile_rank, { series, metric: { id, field, type: TSVB_METRIC_TYPES.PERCENTILE_RANK }, dataView }, @@ -264,7 +264,7 @@ describe('convertMetricAggregationToColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'percentile_rank', - params: { format: { id: 'bytes' }, value: 50 }, + params: { value: 50 }, reducedTimeRange: '10m', }, ], @@ -285,7 +285,7 @@ describe('convertMetricAggregationToColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'formula', - params: { format: { id: 'bytes' }, formula: 'pick_max(differences(max(bytes)), 0)' }, + params: { formula: 'pick_max(differences(max(bytes)), 0)' }, }, ], [ @@ -361,7 +361,7 @@ describe('computeParentPipelineColumns', () => { { meta: { metricId: 'some-id' }, operationType: 'formula', - params: { format: { id: 'bytes' }, formula: "percentile(count(kql='*') / count(kql='*'))" }, + params: { formula: "percentile(count(kql='*') / count(kql='*'))" }, }, ], [ @@ -391,7 +391,6 @@ describe('computeParentPipelineColumns', () => { meta: { metricId: 'some-id' }, operationType: 'formula', params: { - format: { id: 'bytes' }, formula: "percentile(average('bytes',kql='*') / average('bytes',kql='*'))", }, }, @@ -418,7 +417,7 @@ describe('computeParentPipelineColumns', () => { { meta: { metricId: 'some-id' }, operationType: 'average', - params: { format: { id: 'bytes' } }, + params: {}, sourceField: 'bytes', }, { @@ -625,7 +624,7 @@ describe('createParentPipelineAggregationColumn', () => { { meta: { metricId: 'some-id-0' }, operationType: 'cumulative_sum', - params: { format: { id: 'bytes' } }, + params: {}, }, ], [ @@ -641,7 +640,7 @@ describe('createParentPipelineAggregationColumn', () => { { meta: { metricId: 'some-id-0' }, operationType: 'differences', - params: { format: { id: 'bytes' } }, + params: {}, }, ], ])('should return %s', (_, input, expected) => { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts index f6058556ffe27..7acd6b74231b2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts @@ -89,7 +89,7 @@ describe('convertToPercentileColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'percentile', - params: { format: { id: 'bytes' }, percentile: 50 }, + params: { percentile: 50 }, sourceField: 'bytes', } as Partial, ], @@ -103,7 +103,7 @@ describe('convertToPercentileColumn', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile', - params: { format: { id: 'bytes' }, percentile: 50 }, + params: { percentile: 50 }, sourceField: 'bytes', } as Partial, ], @@ -117,7 +117,7 @@ describe('convertToPercentileColumn', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile', - params: { format: { id: 'bytes' }, percentile: 50 }, + params: { percentile: 50 }, sourceField: 'bytes', reducedTimeRange: '10m', } as Partial, @@ -190,7 +190,7 @@ describe('convertToPercentileColumns', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile', - params: { format: { id: 'bytes' }, percentile: 75 }, + params: { percentile: 75 }, sourceField: 'bytes', }, ], @@ -213,7 +213,7 @@ describe('convertToPercentileColumns', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile', - params: { format: { id: 'bytes' }, percentile: 75 }, + params: { percentile: 75 }, sourceField: 'bytes', reducedTimeRange: '50m', }, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts index 5a70c86303fbc..8f04252376545 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -97,7 +97,7 @@ describe('convertToPercentileRankColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'percentile_rank', - params: { format: { id: 'bytes' }, value: 50 }, + params: { value: 50 }, sourceField: 'bytes', } as Partial, ], @@ -107,7 +107,7 @@ describe('convertToPercentileRankColumn', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile_rank', - params: { format: { id: 'bytes' }, value: 50 }, + params: { value: 50 }, sourceField: 'bytes', } as Partial, ], @@ -123,7 +123,7 @@ describe('convertToPercentileRankColumn', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile_rank', - params: { format: { id: 'bytes' }, value: 50 }, + params: { value: 50 }, sourceField: 'bytes', reducedTimeRange: '10m', } as Partial, @@ -173,7 +173,7 @@ describe('convertToPercentileRankColumns', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile_rank', - params: { format: { id: 'bytes' }, value: 75 }, + params: { value: 75 }, sourceField: 'bytes', }, ], @@ -188,7 +188,7 @@ describe('convertToPercentileRankColumns', () => { { meta: { metricId: 'some-id', reference: 'some-id.0' }, operationType: 'percentile_rank', - params: { format: { id: 'bytes' }, value: 75 }, + params: { value: 75 }, sourceField: 'bytes', reducedTimeRange: '50m', }, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.ts index 2b43372ce7d5d..c866fd155542b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.test.ts @@ -58,7 +58,6 @@ describe('convertToStandartDeviationColumn', () => { meta: { metricId: 'some-id' }, operationType: 'formula', params: { - format: { id: 'bytes' }, formula: 'average(bytes) + 1.5 * standard_deviation(bytes)', }, }, @@ -72,7 +71,6 @@ describe('convertToStandartDeviationColumn', () => { meta: { metricId: 'some-id' }, operationType: 'formula', params: { - format: { id: 'bytes' }, formula: 'average(bytes) - 1.5 * standard_deviation(bytes)', }, }, @@ -86,7 +84,6 @@ describe('convertToStandartDeviationColumn', () => { meta: { metricId: 'some-id' }, operationType: 'formula', params: { - format: { id: 'bytes' }, formula: 'average(bytes) + 1.5 * standard_deviation(bytes)', }, }, @@ -94,7 +91,6 @@ describe('convertToStandartDeviationColumn', () => { meta: { metricId: 'some-id' }, operationType: 'formula', params: { - format: { id: 'bytes' }, formula: 'average(bytes) - 1.5 * standard_deviation(bytes)', }, }, @@ -113,7 +109,7 @@ describe('convertToStandartDeviationColumn', () => { { meta: { metricId: 'some-id' }, operationType: 'standard_deviation', - params: { format: { id: 'bytes' } }, + params: {}, }, ], ], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts index e4436ecc19945..ddf8712de863b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts @@ -254,7 +254,6 @@ describe('converToTermsColumn', () => { excludeIsRegex: true, include: [termsInclude], includeIsRegex: true, - format: { id: 'bytes' }, orderAgg: { columnId: 'some-id-0', dataType: 'number', From 7e28d79daa116f9f819fff47c4f77c7e8601ddf6 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 1 Sep 2022 15:59:03 +0300 Subject: [PATCH 118/129] Fix bucket columns test --- .../public/convert_to_lens/lib/series/buckets_columns.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts index 5d7104cfa8fbb..cb2f02c7f3f70 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts @@ -226,7 +226,6 @@ describe('getBucketsColumns', () => { operationType: 'terms', params: expect.objectContaining({ excludeIsRegex: false, - format: { id: 'bytes' }, includeIsRegex: false, orderAgg: expect.objectContaining({ dataType: 'number', From ac69c8aaa274eaa17065de67609247c76f835bed Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Wed, 7 Sep 2022 13:41:17 +0300 Subject: [PATCH 119/129] Fix counter rate metric and remove unused comments --- .../lib/convert/counter_rate.test.ts | 41 +++++++++---------- .../lib/convert/counter_rate.ts | 28 +++++++++---- .../lib/convert/date_histogram.ts | 8 ---- .../convert_to_lens/lib/convert/index.ts | 2 +- .../lib/convert/parent_pipeline.test.ts | 20 --------- .../lib/convert/parent_pipeline.ts | 7 +--- .../lib/metrics/counter_rate_formula.test.ts | 8 +++- .../lib/metrics/counter_rate_formula.ts | 18 ++------ .../lib/metrics/metrics_helpers.test.ts | 8 ---- .../lib/metrics/metrics_helpers.ts | 2 +- .../lib/series/metrics_columns.test.ts | 8 ++-- .../lib/series/metrics_columns.ts | 4 +- 12 files changed, 61 insertions(+), 93 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts index 9e605a8fd30c0..7bf81fa6e5a1e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.test.ts @@ -10,8 +10,8 @@ import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.st import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric } from '../../../../common/types'; import { createSeries } from '../__mocks__'; -import { convertToCounterRateFormulaColumn } from './counter_rate'; -import { CommonColumnsConverterArgs, FormulaColumn } from './types'; +import { convertToCounterRateColumn } from './counter_rate'; +import { CommonColumnsConverterArgs, CounterRateColumn, MaxColumn } from './types'; describe('convertToCounterRateFormulaColumn', () => { const dataView = stubLogstashDataView; @@ -21,33 +21,32 @@ describe('convertToCounterRateFormulaColumn', () => { type: TSVB_METRIC_TYPES.POSITIVE_RATE, }; - test.each<[string, CommonColumnsConverterArgs, Partial | null]>([ + test.each< + [string, CommonColumnsConverterArgs, [Partial, Partial] | null] + >([ ['null if metric contains empty field param', { series, metrics: [metric], dataView }, null], [ - 'formula column if metric contains field param', + 'max and cpunter rate columns if metric contains field param', { series, metrics: [{ ...metric, field: dataView.fields[0].name }], dataView }, - { - operationType: 'formula', - params: { formula: 'pick_max(differences(max(bytes)), 0)' }, - meta: { metricId: 'some-id' }, - }, - ], - [ - 'differences formula with shift if metric contains unit', - { series, metrics: [{ ...metric, field: dataView.fields[0].name, unit: '1h' }], dataView }, - { - operationType: 'formula', - params: { - formula: 'pick_max(differences(max(bytes), shift=1h), 0)', + [ + { + operationType: 'max', + sourceField: dataView.fields[0].name, + }, + { + operationType: 'counter_rate', }, - meta: { metricId: 'some-id' }, - }, + ], ], ])('should return %s', (_, input, expected) => { if (expected === null) { - expect(convertToCounterRateFormulaColumn(input)).toBeNull(); + expect(convertToCounterRateColumn(input)).toBeNull(); + } else if (Array.isArray(expected)) { + const results = convertToCounterRateColumn(input); + expect(results).toEqual(expected.map(expect.objectContaining)); + expect(results?.[1].references[0]).toEqual(results?.[0].columnId); } else { - expect(convertToCounterRateFormulaColumn(input)).toEqual(expect.objectContaining(expected)); + expect(convertToCounterRateColumn(input)).toEqual(expect.objectContaining(expected)); } }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts index 7030ddef33a60..aa64e478e99e0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts @@ -6,15 +6,15 @@ * Side Public License, v 1. */ -import { buildCounterRateFormula } from '../metrics'; -import { createFormulaColumn } from './formula'; -import { CommonColumnsConverterArgs, FormulaColumn } from './types'; +import { Operations } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { createColumn, getFormat } from './column'; +import { CommonColumnsConverterArgs, CounterRateColumn, MaxColumn } from './types'; -export const convertToCounterRateFormulaColumn = ({ +export const convertToCounterRateColumn = ({ series, metrics, dataView, -}: CommonColumnsConverterArgs): FormulaColumn | null => { +}: CommonColumnsConverterArgs): [MaxColumn, CounterRateColumn] | null => { const metric = metrics[metrics.length - 1]; const field = metric.field ? dataView.getFieldByName(metric.field) : undefined; @@ -22,6 +22,20 @@ export const convertToCounterRateFormulaColumn = ({ return null; } - const formula = buildCounterRateFormula(metric, field.name); - return createFormulaColumn(formula, { series, metric, dataView }); + const maxColumn = { + operationType: Operations.MAX, + sourceField: field.name, + ...createColumn(series, metric, field), + params: { ...getFormat(series) }, + }; + + return [ + maxColumn, + { + operationType: Operations.COUNTER_RATE, + references: [maxColumn.columnId], + ...createColumn(series, metric, field), + params: { ...getFormat(series) }, + }, + ]; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts index da3768ba30ca1..f2173cf56b469 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/date_histogram.ts @@ -6,14 +6,6 @@ * Side Public License, v 1. */ -/* - * 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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - import type { DataView } from '@kbn/data-views-plugin/common'; import uuid from 'uuid'; import { DateHistogramParams, DataType } from '@kbn/visualizations-plugin/common/convert_to_lens'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index f46000727fd3f..4d6135ee3d5b2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -21,7 +21,7 @@ export { convertToStaticValueColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; export { convertToDateHistogramColumn } from './date_histogram'; export { converToTermsColumn } from './terms'; -export { convertToCounterRateFormulaColumn } from './counter_rate'; +export { convertToCounterRateColumn } from './counter_rate'; export { convertToStandartDeviationColumn } from './std_deviation'; export * from './types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index 61f48f4c94149..95f83d48d8258 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -268,26 +268,6 @@ describe('convertMetricAggregationToColumn', () => { reducedTimeRange: '10m', }, ], - [ - 'null for counter rate if field in metric is empty', - [ - SUPPORTED_METRICS.positive_rate, - { series, metric: { id, type: TSVB_METRIC_TYPES.POSITIVE_RATE }, dataView }, - ], - null, - ], - [ - 'formula column for counter rate', - [ - SUPPORTED_METRICS.positive_rate, - { series, metric: { id, field, type: TSVB_METRIC_TYPES.POSITIVE_RATE }, dataView }, - ], - { - meta: { metricId: 'some-id' }, - operationType: 'formula', - params: { formula: 'pick_max(differences(max(bytes)), 0)' }, - }, - ], [ 'null for last value (unsupported)', [ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 99d277f6446e6..3b60fe55572a4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -40,7 +40,6 @@ import { createFormulaColumn } from './formula'; import { convertToMovingAverageParams } from './moving_average'; import { convertToPercentileColumn } from './percentile'; import { convertToPercentileRankColumn } from './percentile_rank'; -import { convertToCounterRateFormulaColumn } from './counter_rate'; type MetricAggregationWithoutParams = | typeof Operations.AVERAGE @@ -92,6 +91,7 @@ const SUPPORTED_METRICS_AGGS_WITHOUT_PARAMS: MetricAggregationWithoutParams[] = Operations.MIN, Operations.SUM, Operations.STANDARD_DEVIATION, + Operations.COUNTER_RATE, ]; const SUPPORTED_METRIC_AGGS: MetricAggregation[] = [ @@ -159,9 +159,6 @@ export const convertMetricAggregationToColumn = ( reducedTimeRange, }); } - if (aggregation.name === Operations.COUNTER_RATE) { - return convertToCounterRateFormulaColumn({ series, metrics: [metric], dataView }); - } if (aggregation.name === Operations.LAST_VALUE) { return null; @@ -237,7 +234,7 @@ const convertMovingAvgOrDerivativeToColumns = ( const [nestedFieldId, _] = subMetricField?.split('[') ?? []; // support nested aggs with formula const additionalSubFunction = metrics.find(({ id }) => id === nestedFieldId); - if (additionalSubFunction) { + if (additionalSubFunction || pipelineAgg.name === 'counter_rate') { const formula = getParentPipelineSeriesFormula( metrics, subFunctionMetric, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts index aa1d367be6c11..a0a995f5d2b45 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts @@ -10,6 +10,7 @@ import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.st import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { Metric } from '../../../../common/types'; import { buildCounterRateFormula } from './counter_rate_formula'; +import { SUPPORTED_METRICS } from './supported_metrics'; describe('buildCounterRateFormula', () => { test('should return correct formula for counter rate', () => { @@ -20,7 +21,10 @@ describe('buildCounterRateFormula', () => { unit: '1h', }; - const formula = buildCounterRateFormula(metric, dataView.fields[0].name); - expect(formula).toStrictEqual('pick_max(differences(max(bytes), shift=1h), 0)'); + const formula = buildCounterRateFormula( + SUPPORTED_METRICS[metric.type]!.name, + dataView.fields[0].name + ); + expect(formula).toStrictEqual('counter_rate(max(bytes))'); }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts index f19daa8225f1b..2d1b744c1eb14 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts @@ -6,27 +6,17 @@ * Side Public License, v 1. */ -import type { Metric } from '../../../../common/types'; -import { TimeScaleValue, isTimeScaleValue } from './metrics_helpers'; - const buildMaxFormula = (selector: string) => { return `max(${selector})`; }; -const buildPickMaxPositiveFormula = (selector: string) => { - return `pick_max(${selector}, 0)`; -}; - -const buildDifferencesFormula = (selector: string, shift?: TimeScaleValue) => { - return `differences(${selector}${shift ? `, shift=${shift}` : ''})`; +const buildСounterRateFormula = (aggFormula: string, selector: string) => { + return `${aggFormula}(${selector})`; }; -export const buildCounterRateFormula = (metric: Metric, fieldName: string) => { +export const buildCounterRateFormula = (aggFormula: string, fieldName: string) => { const maxFormula = buildMaxFormula(fieldName); - const unit = metric.unit && isTimeScaleValue(metric.unit) ? metric.unit : undefined; - const diffOfMaxFormula = buildDifferencesFormula(maxFormula, unit); - - const counterRateFormula = buildPickMaxPositiveFormula(diffOfMaxFormula); + const counterRateFormula = buildСounterRateFormula(aggFormula, maxFormula); return counterRateFormula; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts index 994e1f77c37a0..2b8510d3d348a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts @@ -6,14 +6,6 @@ * Side Public License, v 1. */ -/* - * 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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - import { TimeRange } from '@kbn/data-plugin/common'; import { METRIC_TYPES } from '@kbn/data-plugin/public'; import type { Metric, Series, Panel } from '../../../../common/types'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 7f5e036ef89d3..d6e5c0f8c74b8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -131,7 +131,7 @@ export const getFormulaEquivalent = ( ); } case 'positive_rate': { - return buildCounterRateFormula(currentMetric, currentMetric.field!); + return buildCounterRateFormula(aggFormula, currentMetric.field!); } case 'filter_ratio': { return getFilterRatioFormula(currentMetric, reducedTimeRange); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts index 9df7e23f67b92..76a453e3d9f8a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts @@ -17,7 +17,7 @@ const mockConvertMathToFormulaColumn = jest.fn(); const mockConvertParentPipelineAggToColumns = jest.fn(); const mockConvertToCumulativeSumColumns = jest.fn(); const mockConvertFilterRatioToFormulaColumn = jest.fn(); -const mockConvertToCounterRateFormulaColumn = jest.fn(); +const mockConvertToCounterRateColumn = jest.fn(); const mockConvertOtherAggsToFormulaColumn = jest.fn(); const mockConvertToLastValueColumn = jest.fn(); const mockConvertToStaticValueColumn = jest.fn(); @@ -30,7 +30,7 @@ jest.mock('../convert', () => ({ convertParentPipelineAggToColumns: jest.fn(() => mockConvertParentPipelineAggToColumns()), convertToCumulativeSumColumns: jest.fn(() => mockConvertToCumulativeSumColumns()), convertFilterRatioToFormulaColumn: jest.fn(() => mockConvertFilterRatioToFormulaColumn()), - convertToCounterRateFormulaColumn: jest.fn(() => mockConvertToCounterRateFormulaColumn()), + convertToCounterRateColumn: jest.fn(() => mockConvertToCounterRateColumn()), convertOtherAggsToFormulaColumn: jest.fn(() => mockConvertOtherAggsToFormulaColumn()), convertToLastValueColumn: jest.fn(() => mockConvertToLastValueColumn()), convertToStaticValueColumn: jest.fn(() => mockConvertToStaticValueColumn()), @@ -111,13 +111,13 @@ describe('getMetricsColumns', () => { mockConvertFilterRatioToFormulaColumn, ], [ - 'call convertToCounterRateFormulaColumn if metric type is positive rate', + 'call convertToCounterRateColumn if metric type is positive rate', [ createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.POSITIVE_RATE, id: '1' }] }), dataView, 1, ], - mockConvertToCounterRateFormulaColumn, + mockConvertToCounterRateColumn, ], [ 'call convertOtherAggsToFormulaColumn if metric type is positive only', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 3ac6952b561c4..822e5158effe7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -23,7 +23,7 @@ import { convertToLastValueColumn, convertToStaticValueColumn, convertMetricAggregationColumnWithoutSpecialParams, - convertToCounterRateFormulaColumn, + convertToCounterRateColumn, convertToStandartDeviationColumn, } from '../convert'; import { getValidColumns } from './columns'; @@ -98,7 +98,7 @@ export const getMetricsColumns = ( return getValidColumns(formulaColumn); } case 'positive_rate': { - const formulaColumn = convertToCounterRateFormulaColumn(columnsConverterArgs); + const formulaColumn = convertToCounterRateColumn(columnsConverterArgs); return getValidColumns(formulaColumn); } case 'positive_only': From 3e39342b3e675b087a176e7230d2e32aba2399e2 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 12 Sep 2022 17:11:10 +0300 Subject: [PATCH 120/129] Fixed pipeline and terms aggs. Added timeShift arg. --- .../configurations/xy/configuration.test.ts | 2 + .../lib/configurations/xy/configuration.ts | 2 + .../convert_to_lens/lib/convert/column.ts | 9 +- .../lib/convert/cumulative_sum.ts | 5 +- .../lib/convert/filter_ratio.ts | 5 +- .../convert_to_lens/lib/convert/formula.ts | 46 ++++--- .../convert_to_lens/lib/convert/index.ts | 2 +- .../lib/convert/parent_pipeline.test.ts | 12 +- .../lib/convert/parent_pipeline.ts | 19 +-- .../lib/convert/std_deviation.ts | 5 +- .../convert_to_lens/lib/convert/terms.test.ts | 8 +- .../convert_to_lens/lib/convert/terms.ts | 7 +- .../lib/metrics/counter_rate_formula.test.ts | 3 +- .../lib/metrics/counter_rate_formula.ts | 15 ++- .../lib/metrics/filter_ratio_formula.test.ts | 16 ++- .../lib/metrics/filter_ratio_formula.ts | 32 ++--- .../convert_to_lens/lib/metrics/index.ts | 3 +- .../lib/metrics/metrics_helpers.test.ts | 2 +- .../lib/metrics/metrics_helpers.ts | 102 +++++++++------- .../lib/metrics/parent_pipeline_formula.ts | 68 ----------- ...rmula.test.ts => pipeline_formula.test.ts} | 60 +++++---- .../lib/metrics/pipeline_formula.ts | 58 +++++++++ .../metrics/sibling_pipeline_formula.test.ts | 114 ------------------ .../lib/metrics/sibling_pipeline_formula.ts | 71 ----------- .../lib/series/buckets_columns.ts | 4 +- .../convert_to_lens/timeseries/index.ts | 6 + .../public/convert_to_lens/top_n/index.ts | 6 + .../public/convert_to_lens/types.ts | 5 + .../common/convert_to_lens/types/common.ts | 2 +- .../indexpattern_suggestions.ts | 37 ++++-- .../operations/definitions/terms/index.tsx | 1 + .../operations/layer_helpers.ts | 6 +- 32 files changed, 322 insertions(+), 411 deletions(-) delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts rename src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/{parent_pipeline_formula.test.ts => pipeline_formula.test.ts} (74%) create mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts delete mode 100644 src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts index ae3f75bf5905d..485dc6a84fc3e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.test.ts @@ -28,6 +28,8 @@ describe('getConfigurationForTimeseries', () => { }, yLeftExtent: { mode: 'full' }, yRightExtent: { mode: 'full' }, + yLeftScale: 'linear', + yRightScale: 'linear', }); }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts index b28e3767135c4..3108d373fe747 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/xy/configuration.ts @@ -33,6 +33,8 @@ export const getConfigurationForTimeseries = ( }, yLeftExtent: extents.yLeftExtent, yRightExtent: extents.yRightExtent, + yLeftScale: model.axis_scale === 'log' ? 'log' : 'linear', + yRightScale: model.axis_scale === 'log' ? 'log' : 'linear', }; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index 1c1ed33958971..f836b28f5c605 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -34,7 +34,7 @@ const isSupportedFormat = (format: string) => ['bytes', 'number', 'percent'].inc export const getFormat = (series: Series): FormatParams => { let suffix; - if (!series.formatter) { + if (!series.formatter || series.formatter === 'default') { return {}; } @@ -44,10 +44,12 @@ export const getFormat = (series: Series): FormatParams => { // not supported formatters should be converted to number if (!isSupportedFormat(series.formatter)) { - return { format: { id: DATA_FORMATTERS.NUMBER, ...(suffix && { params: { suffix } }) } }; + return { + format: { id: DATA_FORMATTERS.NUMBER, ...(suffix && { params: { suffix, decimals: 2 } }) }, + }; } - return { format: { id: series.formatter, ...(suffix && { params: { suffix } }) } }; + return { format: { id: series.formatter, ...(suffix && { params: { suffix, decimals: 2 } }) } }; }; export const createColumn = ( @@ -63,6 +65,7 @@ export const createColumn = ( isSplit, reducedTimeRange, filter: series.filter, + timeShift: series.offset_time, timeScale: getTimeScale(metric), meta: { metricId: metric.id }, }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index 8da6730b17c1c..8733b100f9a95 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -7,7 +7,7 @@ */ import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import { SUPPORTED_METRICS, getParentPipelineSeriesFormula } from '../metrics'; +import { SUPPORTED_METRICS, getPipelineSeriesFormula } from '../metrics'; import { createFormulaColumn } from './formula'; import { computeParentPipelineColumns } from './parent_pipeline'; import { CommonColumnsConverterArgs } from './types'; @@ -33,9 +33,10 @@ export const convertToCumulativeSumColumns = ( // and everything else as formula if (pipelineAgg.name !== 'count' && pipelineAgg.name !== 'sum') { const metaValue = Number(meta?.replace(']', '')); - formula = getParentPipelineSeriesFormula(metrics, subFunctionMetric, pipelineAgg, metric.type, { + formula = getPipelineSeriesFormula(metric, metrics, subFunctionMetric, { metaValue, reducedTimeRange, + timeShift: series.offset_time, }); if (!formula) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts index 0b4f591d92503..9ed19035697fe 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/filter_ratio.ts @@ -15,7 +15,10 @@ export const convertFilterRatioToFormulaColumn = ( reducedTimeRange?: string ): FormulaColumn | null => { const metric = metrics[metrics.length - 1]; - const formula = getFilterRatioFormula(metric, reducedTimeRange); + const formula = getFilterRatioFormula(metric, { + reducedTimeRange, + timeShift: series.offset_time, + }); if (!formula) { return null; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index 44d659e18fed3..d3f1f6e2640e6 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -11,8 +11,9 @@ import { FormulaParams } from '@kbn/visualizations-plugin/common/convert_to_lens import { CommonColumnConverterArgs, CommonColumnsConverterArgs, FormulaColumn } from './types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric } from '../../../../common/types'; -import { getFormulaEquivalent, getSiblingPipelineSeriesFormula } from '../metrics'; +import { getFormulaEquivalent, getPipelineSeriesFormula } from '../metrics'; import { createColumn, getFormat } from './column'; +import { AdditionalFormulaArgs } from '../../types'; type OtherFormulaAggregations = | typeof TSVB_METRIC_TYPES.POSITIVE_ONLY @@ -43,7 +44,7 @@ const convertFormulaScriptForPercentileAggs = ( variables: Exclude, metric: Metric, allAggMetrics: Metric[], - reducedTimeRange?: string + additionalArgs: AdditionalFormulaArgs ) => { variables.forEach((variable) => { const [_, meta] = variable?.field?.split('[') ?? []; @@ -51,7 +52,7 @@ const convertFormulaScriptForPercentileAggs = ( if (!metaValue) { return; } - const script = getFormulaEquivalent(metric, allAggMetrics, { metaValue, reducedTimeRange }); + const script = getFormulaEquivalent(metric, allAggMetrics, { metaValue, ...additionalArgs }); if (!script) { return; } @@ -65,9 +66,9 @@ const convertFormulaScriptForAggs = ( variables: Exclude, metric: Metric, allAggMetrics: Metric[], - reducedTimeRange?: string + additionalArgs: AdditionalFormulaArgs ) => { - const script = getFormulaEquivalent(metric, allAggMetrics, { reducedTimeRange }); + const script = getFormulaEquivalent(metric, allAggMetrics, { ...additionalArgs }); if (!script) { return null; } @@ -107,21 +108,15 @@ export const convertMathToFormulaColumn = ( // should treat percentiles differently if (notMathMetric.type === 'percentile' || notMathMetric.type === 'percentile_rank') { - script = convertFormulaScriptForPercentileAggs( - script!, - variables, - notMathMetric, - metrics, - reducedTimeRange - ); + script = convertFormulaScriptForPercentileAggs(script!, variables, notMathMetric, metrics, { + reducedTimeRange, + timeShift: series.offset_time, + }); } else { - script = convertFormulaScriptForAggs( - script!, - variables, - notMathMetric, - metrics, - reducedTimeRange - ); + script = convertFormulaScriptForAggs(script!, variables, notMathMetric, metrics, { + reducedTimeRange, + timeShift: series.offset_time, + }); } } @@ -143,8 +138,19 @@ export const convertOtherAggsToFormulaColumn = ( reducedTimeRange?: string ): FormulaColumn | null => { const metric = metrics[metrics.length - 1]; + const [fieldId, meta] = metric?.field?.split('[') ?? []; + const subFunctionMetric = metrics.find(({ id }) => id === fieldId); + const metaValue = meta ? Number(meta?.replace(']', '')) : undefined; + + if (!subFunctionMetric) { + return null; + } - const formula = getSiblingPipelineSeriesFormula(aggregation, metric, metrics, reducedTimeRange); + const formula = getPipelineSeriesFormula(metric, metrics, subFunctionMetric, { + metaValue, + reducedTimeRange, + timeShift: series.offset_time, + }); if (!formula) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 4d6135ee3d5b2..84c7b32e10763 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -20,7 +20,7 @@ export { convertToLastValueColumn } from './last_value'; export { convertToStaticValueColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; export { convertToDateHistogramColumn } from './date_histogram'; -export { converToTermsColumn } from './terms'; +export { convertToTermsColumn } from './terms'; export { convertToCounterRateColumn } from './counter_rate'; export { convertToStandartDeviationColumn } from './std_deviation'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index 95f83d48d8258..6defaba409741 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -467,8 +467,8 @@ describe('convertParentPipelineAggToColumns', () => { series, metrics: [ { id, field, type: METRIC_TYPES.MAX }, - { id: id1, field: `${id}[75]`, type: METRIC_TYPES.AVG }, - { id: id2, field: `${id1}[50]`, type: TSVB_METRIC_TYPES.MOVING_AVERAGE }, + { id: id1, field: `${id}`, type: METRIC_TYPES.DERIVATIVE }, + { id: id2, field: `${id1}`, type: TSVB_METRIC_TYPES.MOVING_AVERAGE }, ], dataView, }, @@ -476,7 +476,7 @@ describe('convertParentPipelineAggToColumns', () => { { meta: { metricId: 'some-id-2' }, operationType: 'formula', - params: { formula: 'moving_average(average(max(bytes)))' }, + params: { formula: 'moving_average(differences(max(bytes)), window=5)' }, }, ], [ @@ -486,8 +486,8 @@ describe('convertParentPipelineAggToColumns', () => { series, metrics: [ { id, field, type: METRIC_TYPES.MAX }, - { id: id1, field: `${id}[75]`, type: METRIC_TYPES.AVG }, - { id: id2, field: `${id1}[50]`, type: METRIC_TYPES.DERIVATIVE }, + { id: id1, field: `${id}`, type: TSVB_METRIC_TYPES.MOVING_AVERAGE }, + { id: id2, field: `${id1}`, type: METRIC_TYPES.DERIVATIVE }, ], dataView, }, @@ -495,7 +495,7 @@ describe('convertParentPipelineAggToColumns', () => { { meta: { metricId: 'some-id-2' }, operationType: 'formula', - params: { formula: 'differences(average(max(bytes)))' }, + params: { formula: 'differences(moving_average(max(bytes), window=5))' }, }, ], [ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 3b60fe55572a4..3ba9dfcfb6763 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -31,9 +31,9 @@ import { Metric } from '../../../../common/types'; import { getFilterRatioFormula, getFormulaFromMetric, - getParentPipelineSeriesFormula, SupportedMetric, SUPPORTED_METRICS, + getPipelineSeriesFormula } from '../metrics'; import { createColumn, getFormat } from './column'; import { createFormulaColumn } from './formula'; @@ -186,7 +186,10 @@ export const computeParentPipelineColumns = ( const aggFormula = getFormulaFromMetric(agg); if (subFunctionMetric.type === 'filter_ratio') { - const script = getFilterRatioFormula(subFunctionMetric, reducedTimeRange); + const script = getFilterRatioFormula(subFunctionMetric, { + reducedTimeRange, + timeShift: series.offset_time, + }); if (!script) { return null; } @@ -235,13 +238,11 @@ const convertMovingAvgOrDerivativeToColumns = ( // support nested aggs with formula const additionalSubFunction = metrics.find(({ id }) => id === nestedFieldId); if (additionalSubFunction || pipelineAgg.name === 'counter_rate') { - const formula = getParentPipelineSeriesFormula( - metrics, - subFunctionMetric, - pipelineAgg, - metric.type, - { metaValue, reducedTimeRange } - ); + const formula = getPipelineSeriesFormula(metric, metrics, subFunctionMetric, { + metaValue, + reducedTimeRange, + timeShift: series.offset_time, + }); if (!formula) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts index 73e1b614869b2..d2a18a5dee596 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts @@ -17,7 +17,10 @@ const createStandartDeviationFormulaColumn = ( metrics: Metric[], reducedTimeRange?: string ) => { - const script = getFormulaEquivalent(metric, metrics, { reducedTimeRange }); + const script = getFormulaEquivalent(metric, metrics, { + reducedTimeRange, + timeShift: series.offset_time, + }); if (!script) return null; return createFormulaColumn(script, { series, metric, dataView }); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts index ddf8712de863b..69bfa2a8969a8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.test.ts @@ -13,7 +13,7 @@ import { TermsParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { createSeries } from '../__mocks__'; -import { converToTermsColumn, convertToTermsParams } from './terms'; +import { convertToTermsColumn, convertToTermsParams } from './terms'; import { Column } from './types'; describe('convertToTermsParams', () => { @@ -208,7 +208,7 @@ describe('converToTermsColumn', () => { test.each< [ string, - Parameters, + Parameters, Partial< Omit & { params: Partial> & { @@ -275,9 +275,9 @@ describe('converToTermsColumn', () => { ], ])('should return %s', (_, input, expected) => { if (expected === null) { - expect(converToTermsColumn(...input)).toBeNull(); + expect(convertToTermsColumn(...input)).toBeNull(); } else { - expect(converToTermsColumn(...input)).toEqual( + expect(convertToTermsColumn(...input)).toEqual( expect.objectContaining({ ...expected, params: expect.objectContaining({ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts index 3c14efa4f1d6c..977de1947d4f8 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/terms.ts @@ -24,13 +24,12 @@ const getOrderByWithAgg = (series: Series, columns: Column[]): OrderByWithAgg | } if (series.terms_order_by === '_count' || !series.terms_order_by) { - const columnId = uuid(); return { - orderBy: { type: 'column', columnId }, + orderBy: { type: 'custom' }, orderAgg: { operationType: 'count', sourceField: 'document', - columnId, + columnId: uuid(), isBucketed: true, isSplit: false, dataType: 'number', @@ -83,7 +82,7 @@ export const convertToTermsParams = ( }; }; -export const converToTermsColumn = ( +export const convertToTermsColumn = ( termFields: [string, ...string[]], series: Series, columns: Column[], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts index a0a995f5d2b45..07f10b472b045 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.test.ts @@ -23,7 +23,8 @@ describe('buildCounterRateFormula', () => { const formula = buildCounterRateFormula( SUPPORTED_METRICS[metric.type]!.name, - dataView.fields[0].name + dataView.fields[0].name, + {} ); expect(formula).toStrictEqual('counter_rate(max(bytes))'); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts index 2d1b744c1eb14..78ca3981e4096 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts @@ -6,16 +6,23 @@ * Side Public License, v 1. */ -const buildMaxFormula = (selector: string) => { - return `max(${selector})`; +import { addAdditionalArgs } from '.'; +import { AdditionalFormulaArgs } from '../../types'; + +const buildMaxFormula = (selector: string, additionalArgs: AdditionalFormulaArgs) => { + return `max(${selector}${addAdditionalArgs(additionalArgs)})`; }; const buildСounterRateFormula = (aggFormula: string, selector: string) => { return `${aggFormula}(${selector})`; }; -export const buildCounterRateFormula = (aggFormula: string, fieldName: string) => { - const maxFormula = buildMaxFormula(fieldName); +export const buildCounterRateFormula = ( + aggFormula: string, + fieldName: string, + additionalArgs: AdditionalFormulaArgs +) => { + const maxFormula = buildMaxFormula(fieldName, additionalArgs); const counterRateFormula = buildСounterRateFormula(aggFormula, maxFormula); return counterRateFormula; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts index a18de5cdeba13..652e6ecc22c26 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts @@ -10,6 +10,7 @@ import { METRIC_TYPES } from '@kbn/data-plugin/public'; import type { Metric } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { getFilterRatioFormula } from './filter_ratio_formula'; +import { AdditionalFormulaArgs } from '../../types'; describe('getFilterRatioFormula', () => { const metric: Metric = { @@ -32,23 +33,28 @@ describe('getFilterRatioFormula', () => { metric_agg: METRIC_TYPES.MEDIAN, }; - test.each<[string, [Metric, string | undefined], string | null]>([ - ['null if metric_agg is not supported', [metricWithNotSupportedMetricAgg, undefined], null], + test.each<[string, [Metric, AdditionalFormulaArgs], string | null]>([ + ['null if metric_agg is not supported', [metricWithNotSupportedMetricAgg, {}], null], [ 'filter ratio formula if metric_agg is not specified', - [metric, undefined], + [metric, {}], "count(kql='*') / count(kql='*')", ], [ 'filter ratio formula if metric_agg is specified', - [metricWithMetricAgg, undefined], + [metricWithMetricAgg, {}], "average('test-1',kql='*') / average('test-1',kql='*')", ], [ 'filter ratio formula if reducedTimeRange is provided', - [metricWithMetricAgg, '1h'], + [metricWithMetricAgg, { reducedTimeRange: '1h' }], "average('test-1',kql='*', reducedTimeRange='1h') / average('test-1',kql='*', reducedTimeRange='1h')", ], + [ + 'filter ratio formula if time shift is provided', + [metricWithMetricAgg, { reducedTimeRange: '1h', timeShift: '3h' }], + "average('test-1',kql='*', shift='3h', reducedTimeRange='1h') / average('test-1',kql='*', shift='3h', reducedTimeRange='1h')", + ], ])('should return %s', (_, input, expected) => { if (expected === null) { expect(getFilterRatioFormula(...input)).toBeNull(); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index ef16ee9ee2ace..689ba3ca16d1e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -9,7 +9,8 @@ import type { Query } from '@kbn/es-query'; import type { Metric, MetricType } from '../../../../common/types'; import { getFormulaFromMetric, SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; -import { addTimeRangeToFormula } from '.'; +import { addAdditionalArgs } from '.'; +import { AdditionalFormulaArgs } from '../../types'; const escapeQuotes = (str: string) => { return str?.replace(/'/g, "\\'"); @@ -18,16 +19,19 @@ const escapeQuotes = (str: string) => { const constructFilterRationFormula = ( operation: string, metric?: Query, - reducedTimeRange?: string + additionalArgs?: AdditionalFormulaArgs ) => { return `${operation}${metric?.language === 'lucene' ? 'lucene' : 'kql'}='${ metric?.query && typeof metric?.query === 'string' ? escapeQuotes(metric?.query) : metric?.query ?? '*' - }'${addTimeRangeToFormula(reducedTimeRange)})`; + }'${additionalArgs ? addAdditionalArgs(additionalArgs) : ''})`; }; -export const getFilterRatioFormula = (currentMetric: Metric, reducedTimeRange?: string) => { +export const getFilterRatioFormula = ( + currentMetric: Metric, + additionalArgs: AdditionalFormulaArgs +) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; let aggregation: SupportedMetric | null | undefined = SUPPORTED_METRICS.count; @@ -42,24 +46,20 @@ export const getFilterRatioFormula = (currentMetric: Metric, reducedTimeRange?: const operation = metric_agg && metric_agg !== 'count' ? `${aggFormula}('${field}',` : 'count('; if (aggregation.name === 'counter_rate') { - const numeratorFormula = `max(${constructFilterRationFormula( - `differences(max('${field}',`, + const numeratorFormula = `counter_rate(${constructFilterRationFormula( + `(max('${field}',`, numerator, - reducedTimeRange + additionalArgs )})`; - const denominatorFormula = `max(${constructFilterRationFormula( - `differences(max('${field}',`, + const denominatorFormula = `counter_rate(${constructFilterRationFormula( + `(max('${field}',`, denominator, - reducedTimeRange + additionalArgs )})`; return `${numeratorFormula}) / ${denominatorFormula})`; } else { - const numeratorFormula = constructFilterRationFormula(operation, numerator, reducedTimeRange); - const denominatorFormula = constructFilterRationFormula( - operation, - denominator, - reducedTimeRange - ); + const numeratorFormula = constructFilterRationFormula(operation, numerator, additionalArgs); + const denominatorFormula = constructFilterRationFormula(operation, denominator, additionalArgs); return `${numeratorFormula} / ${denominatorFormula}`; } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts index d03df28f4814e..390154ed98f76 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/index.ts @@ -8,8 +8,7 @@ export * from './supported_metrics'; export * from './metrics_helpers'; -export * from './parent_pipeline_formula'; -export * from './sibling_pipeline_formula'; +export * from './pipeline_formula'; export * from './filter_ratio_formula'; export * from './counter_rate_formula'; export * from './validate_metrics'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts index 2b8510d3d348a..c793c9857bdee 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts @@ -123,7 +123,7 @@ describe('getFormulaEquivalent', () => { [ 'correct formula if metric is parent pipeline agg', [parentPipelineMetric[1], parentPipelineMetric, {}], - 'moving_average(average(test-field-1))', + 'moving_average(average(test-field-1), window=5)', ], ['correct formula if metric is count agg', [countMetric, [countMetric], {}], 'count()'], ['correct formula if metric is static value', [staticValue, [staticValue], {}], '100'], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index d6e5c0f8c74b8..374661609b86e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -15,10 +15,10 @@ import { getUISettings } from '../../../services'; import type { Metric, Panel, Series } from '../../../../common/types'; import { TIME_RANGE_DATA_MODES } from '../../../../common/enums'; import { getFilterRatioFormula } from './filter_ratio_formula'; -import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; -import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; import { buildCounterRateFormula } from './counter_rate_formula'; +import { getPipelineSeriesFormula } from './pipeline_formula'; +import { AdditionalFormulaArgs } from '../../types'; const shouldCalculateReducedTimeRange = (timeRangeMode?: string) => { return timeRangeMode === TIME_RANGE_DATA_MODES.LAST_VALUE; @@ -68,15 +68,27 @@ export const getTimeScale = (metric: Metric): TimeScaleUnit | undefined => { return timeScale; }; -export const addTimeRangeToFormula = (reducedTimeRange?: string) => { +const addTimeRangeToFormula = (reducedTimeRange?: string) => { return reducedTimeRange ? `, reducedTimeRange='${reducedTimeRange}'` : ''; }; +const addTimeShiftToFormula = (timeShift?: string) => { + return timeShift ? `, shift='${timeShift}'` : ''; +}; + +export const addAdditionalArgs = ({ reducedTimeRange, timeShift }: AdditionalFormulaArgs) => { + return `${addTimeShiftToFormula(timeShift)}${addTimeRangeToFormula(reducedTimeRange)}`; +}; + export const getFormulaEquivalent = ( currentMetric: Metric, metrics: Metric[], - { metaValue, reducedTimeRange }: { metaValue?: number; reducedTimeRange?: string } = {} -) => { + { + metaValue, + reducedTimeRange, + timeShift, + }: { metaValue?: number; reducedTimeRange?: string; timeShift?: string } = {} +): string | null => { const aggregation = SUPPORTED_METRICS[currentMetric.type]; if (!aggregation) { return null; @@ -85,77 +97,77 @@ export const getFormulaEquivalent = ( const aggFormula = getFormulaFromMetric(aggregation); switch (currentMetric.type) { + case 'cumulative_sum': + case 'derivative': + case 'moving_average': case 'avg_bucket': case 'max_bucket': case 'min_bucket': case 'sum_bucket': case 'positive_only': { - return getSiblingPipelineSeriesFormula( - currentMetric.type, - currentMetric, - metrics, - reducedTimeRange - ); + const [subMetricId, nestedMetaValue] = currentMetric?.field?.split('[') ?? []; + const subFunctionMetric = metrics.find((metric) => metric.id === subMetricId); + if (!subFunctionMetric || !SUPPORTED_METRICS[subFunctionMetric.type]) { + return null; + } + + return getPipelineSeriesFormula(currentMetric, metrics, subFunctionMetric, { + metaValue: nestedMetaValue ? Number(nestedMetaValue?.replace(']', '')) : undefined, + reducedTimeRange, + timeShift, + }); } case 'count': { - return `${aggFormula}()`; + return `${aggFormula}(${timeShift ? `shift='${timeShift}'` : ''}${ + timeShift && reducedTimeRange ? ', ' : '' + }${reducedTimeRange ? `reducedTimeRange='${reducedTimeRange}'` : ''})`; } case 'percentile': { return `${aggFormula}(${currentMetric.field}${ metaValue ? `, percentile=${metaValue}` : '' - }${addTimeRangeToFormula(reducedTimeRange)})`; + }${addAdditionalArgs({ reducedTimeRange, timeShift })})`; } case 'percentile_rank': { return `${aggFormula}(${currentMetric.field}${ metaValue ? `, value=${metaValue}` : '' - }${addTimeRangeToFormula(reducedTimeRange)})`; - } - case 'cumulative_sum': - case 'derivative': - case 'moving_average': { - const [fieldId, _] = currentMetric?.field?.split('[') ?? []; - const subFunctionMetric = metrics.find((metric) => metric.id === fieldId); - if (!subFunctionMetric) { - return null; - } - const pipelineAgg = SUPPORTED_METRICS[subFunctionMetric.type]; - if (!pipelineAgg) { - return null; - } - return getParentPipelineSeriesFormula( - metrics, - subFunctionMetric, - pipelineAgg, - currentMetric.type, - { metaValue, reducedTimeRange } - ); + }${addAdditionalArgs({ reducedTimeRange, timeShift })})`; } case 'positive_rate': { - return buildCounterRateFormula(aggFormula, currentMetric.field!); + return buildCounterRateFormula(aggFormula, currentMetric.field!, { + reducedTimeRange, + timeShift, + }); } case 'filter_ratio': { - return getFilterRatioFormula(currentMetric, reducedTimeRange); + return getFilterRatioFormula(currentMetric, { reducedTimeRange, timeShift }); } case 'static': { return `${currentMetric.value}`; } case 'std_deviation': { if (currentMetric.mode === 'lower') { - return `average(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)}) - ${ - currentMetric.sigma || 1.5 - } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)})`; + return `average(${currentMetric.field}${addAdditionalArgs({ + reducedTimeRange, + timeShift, + })}) - ${currentMetric.sigma || 1.5} * ${aggFormula}(${ + currentMetric.field + }${addAdditionalArgs({ reducedTimeRange, timeShift })})`; } if (currentMetric.mode === 'upper') { - return `average(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)}) + ${ - currentMetric.sigma || 1.5 - } * ${aggFormula}(${currentMetric.field}${addTimeRangeToFormula(reducedTimeRange)})`; + return `average(${currentMetric.field}${addAdditionalArgs({ + reducedTimeRange, + timeShift, + })}) + ${currentMetric.sigma || 1.5} * ${aggFormula}(${ + currentMetric.field + }${addAdditionalArgs({ reducedTimeRange, timeShift })})`; } return `${aggFormula}(${currentMetric.field})`; } default: { - return `${aggFormula}(${currentMetric.field ?? ''}${addTimeRangeToFormula( - reducedTimeRange - )})`; + return `${aggFormula}(${currentMetric.field ?? ''}${addAdditionalArgs({ + reducedTimeRange, + timeShift, + })})`; } } }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts deleted file mode 100644 index c74ce9713184a..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.ts +++ /dev/null @@ -1,68 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { Metric, MetricType } from '../../../../common/types'; -import { SUPPORTED_METRICS, getFormulaFromMetric, SupportedMetric } from './supported_metrics'; -import { getFormulaEquivalent } from './metrics_helpers'; - -export const getParentPipelineSeriesFormula = ( - metrics: Metric[], - subFunctionMetric: Metric, - pipelineAgg: SupportedMetric, - aggregation: MetricType, - { metaValue, reducedTimeRange }: { metaValue?: number; reducedTimeRange?: string } = {} -) => { - let formula = ''; - const aggregationMap = SUPPORTED_METRICS[aggregation]; - if (!aggregationMap) { - return null; - } - if (subFunctionMetric.type === 'static') { - return null; - } - - const aggFormula = getFormulaFromMetric(aggregationMap); - const pipelineFormula = getFormulaFromMetric(pipelineAgg); - - const subMetricField = subFunctionMetric.field; - const [nestedFieldId, nestedMeta] = subMetricField?.split('[') ?? []; - // support nested aggs - const additionalSubFunction = metrics.find((metric) => metric.id === nestedFieldId); - if (additionalSubFunction) { - // support nested aggs with formula - const additionalPipelineAggMap = SUPPORTED_METRICS[additionalSubFunction.type]; - if (!additionalPipelineAggMap) { - return null; - } - const additionalPipelineAggFormula = getFormulaFromMetric(additionalPipelineAggMap); - - const nestedMetaValue = Number(nestedMeta?.replace(']', '')); - let additionalFunctionArgs; - if (additionalPipelineAggMap.name === 'percentile' && nestedMetaValue) { - additionalFunctionArgs = `, percentile=${nestedMetaValue}`; - } - if (additionalPipelineAggMap.name === 'percentile_rank' && nestedMetaValue) { - additionalFunctionArgs = `, value=${nestedMetaValue}`; - } - formula = `${aggFormula}(${pipelineFormula}(${additionalPipelineAggFormula}(${ - additionalSubFunction.field ?? '' - }${additionalFunctionArgs ?? ''})))`; - } else { - const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, { - metaValue, - reducedTimeRange, - }); - - if (!subFormula) { - return null; - } - - formula = `${aggregationMap.name}(${subFormula})`; - } - return formula; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.test.ts similarity index 74% rename from src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.test.ts rename to src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.test.ts index 5949a60fa76a6..07af0740d648b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/parent_pipeline_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.test.ts @@ -7,10 +7,9 @@ */ import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import type { Metric, MetricType } from '../../../../common/types'; +import type { Metric } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; -import { getParentPipelineSeriesFormula } from './parent_pipeline_formula'; -import { SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; +import { getPipelineSeriesFormula } from './pipeline_formula'; describe('getParentPipelineSeriesFormula', () => { const metrics: Metric[] = [ @@ -98,20 +97,37 @@ describe('getParentPipelineSeriesFormula', () => { }, ]; + const positiveOnlyMetrics: Metric[] = [ + { + id: 'test-1', + type: METRIC_TYPES.AVG, + field: 'test-field-1', + }, + { + id: 'some-random-value', + type: TSVB_METRIC_TYPES.POSITIVE_ONLY, + field: 'test-1', + }, + ]; + test.each< [ string, - [Metric[], Metric, SupportedMetric, MetricType, { metaValue?: number; window?: string }], + [ + Metric, + Metric[], + Metric, + { metaValue?: number; reducedTimeRange?: string; timeShift?: string } + ], string | null ] >([ [ 'null if metric is not supported', [ + metricsWithNotSupportedSubFunction[0], metrics, metrics[0], - SUPPORTED_METRICS[metrics[0].type]!, - TSVB_METRIC_TYPES.SUM_OF_SQUARES_BUCKET, {}, ], null, @@ -119,10 +135,9 @@ describe('getParentPipelineSeriesFormula', () => { [ 'null if metric have not supported additional sub function', [ + metricsWithNotSupportedSubFunction[2], metricsWithNotSupportedSubFunction, metricsWithNotSupportedSubFunction[1], - SUPPORTED_METRICS[metricsWithNotSupportedSubFunction[1].type]!, - TSVB_METRIC_TYPES.MOVING_AVERAGE, {}, ], null, @@ -130,51 +145,52 @@ describe('getParentPipelineSeriesFormula', () => { [ 'correct formula if metric is supported', [ + metrics[1], metrics, metrics[0], - SUPPORTED_METRICS[metrics[0].type]!, - TSVB_METRIC_TYPES.MOVING_AVERAGE, {}, ], - 'moving_average(average(test-field-1))', + 'moving_average(average(test-field-1), window=5)', ], [ 'correct formula if metric have additional sub function', [ + metricsWithSubFunction[2], metricsWithSubFunction, metricsWithSubFunction[1], - SUPPORTED_METRICS[metricsWithSubFunction[1].type]!, - TSVB_METRIC_TYPES.MOVING_AVERAGE, {}, ], - 'moving_average(differences(average(test-field-1)))', + 'moving_average(differences(average(test-field-1)), window=5)', ], [ 'correct formula if metric have percentile additional sub function', [ + metricsWithPercentileSubFunction[2], metricsWithPercentileSubFunction, metricsWithPercentileSubFunction[1], - SUPPORTED_METRICS[metricsWithPercentileSubFunction[1].type]!, - TSVB_METRIC_TYPES.MOVING_AVERAGE, {}, ], - 'moving_average(differences(percentile(test-field-1, percentile=50)))', + 'moving_average(differences(percentile(test-field-1, percentile=50)), window=5)', ], [ 'correct formula if metric have percentile rank additional sub function', [ + metricsWithPercentileRankSubFunction[2], metricsWithPercentileRankSubFunction, metricsWithPercentileRankSubFunction[1], - SUPPORTED_METRICS[metricsWithPercentileRankSubFunction[1].type]!, - TSVB_METRIC_TYPES.MOVING_AVERAGE, {}, ], - 'moving_average(differences(percentile_rank(test-field-1, value=5)))', + 'moving_average(differences(percentile_rank(test-field-1, value=5)), window=5)', + ], + [ + 'correct formula if metric is positive only', + [positiveOnlyMetrics[1], positiveOnlyMetrics, positiveOnlyMetrics[0], {}], + 'pick_max(average(test-field-1), 0)', ], ])('should return %s', (_, input, expected) => { if (expected === null) { - expect(getParentPipelineSeriesFormula(...input)).toBeNull(); + expect(getPipelineSeriesFormula(...input)).toBeNull(); } - expect(getParentPipelineSeriesFormula(...input)).toEqual(expected); + expect(getPipelineSeriesFormula(...input)).toEqual(expected); }); }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.ts new file mode 100644 index 0000000000000..d357d886ff5bd --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.ts @@ -0,0 +1,58 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { TSVB_METRIC_TYPES } from '../../../../common/enums'; +import type { Metric } from '../../../../common/types'; +import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; +import { getFormulaEquivalent } from './metrics_helpers'; + +const getAdditionalArgs = (metric: Metric) => { + if (metric.type === TSVB_METRIC_TYPES.POSITIVE_ONLY) { + return `, 0`; + } + + if (metric.type === TSVB_METRIC_TYPES.MOVING_AVERAGE) { + return `, window=${metric.window || 5}`; + } + + return ''; +}; + +export const getPipelineSeriesFormula = ( + metric: Metric, + metrics: Metric[], + subFunctionMetric: Metric, + { + metaValue, + reducedTimeRange, + timeShift, + }: { metaValue?: number; reducedTimeRange?: string; timeShift?: string } = {} +) => { + const aggregationMap = SUPPORTED_METRICS[metric.type]; + if (!aggregationMap) { + return null; + } + if (!subFunctionMetric || subFunctionMetric.type === 'static') { + return null; + } + + const aggFormula = getFormulaFromMetric(aggregationMap); + + const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, { + metaValue, + reducedTimeRange, + timeShift, + }); + + if (!subFormula) { + return null; + } + const additionalArgs = getAdditionalArgs(metric); + + return `${aggFormula}(${subFormula}${additionalArgs})`; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts deleted file mode 100644 index 15c1df306c05a..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.test.ts +++ /dev/null @@ -1,114 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { METRIC_TYPES } from '@kbn/data-plugin/public'; -import type { Metric, MetricType } from '../../../../common/types'; -import { TSVB_METRIC_TYPES } from '../../../../common/enums'; -import { getSiblingPipelineSeriesFormula } from './sibling_pipeline_formula'; - -describe('getSiblingPipelineSeriesFormula', () => { - const metrics: Metric[] = [ - { - id: 'test-1', - type: METRIC_TYPES.AVG, - field: 'test-field-1', - }, - { - id: 'some-random-value', - type: METRIC_TYPES.AVG_BUCKET, - field: 'test-1', - }, - ]; - - const positiveOnlyMetrics: Metric[] = [ - { - id: 'test-1', - type: METRIC_TYPES.AVG, - field: 'test-field-1', - }, - { - id: 'some-random-value', - type: TSVB_METRIC_TYPES.POSITIVE_ONLY, - field: 'test-1', - }, - ]; - - const metricsWithNotSupportedSubFunction: Metric[] = [ - { - id: 'test-2', - type: METRIC_TYPES.MEDIAN, - field: 'test-field-1', - }, - { - id: 'test-1', - type: METRIC_TYPES.SUM_BUCKET, - field: 'test-2', - }, - { - id: 'some-random-value', - type: METRIC_TYPES.AVG_BUCKET, - field: 'test-1', - }, - ]; - - const metricsWithSubFunction: Metric[] = [ - { - id: 'test-2', - type: METRIC_TYPES.AVG, - field: 'test-field-1', - }, - { - id: 'test-1', - type: METRIC_TYPES.SUM_BUCKET, - field: 'test-2', - }, - { - id: 'some-random-value', - type: METRIC_TYPES.AVG_BUCKET, - field: 'test-1', - }, - ]; - - test.each<[string, [MetricType, Metric, Metric[], string | undefined], string | null]>([ - [ - 'null if metric is not supported', - [TSVB_METRIC_TYPES.SUM_OF_SQUARES_BUCKET, metrics[1], metrics, undefined], - null, - ], - [ - 'null if metric have not supported additional sub function', - [ - METRIC_TYPES.AVG_BUCKET, - metricsWithNotSupportedSubFunction[2], - metricsWithNotSupportedSubFunction, - undefined, - ], - null, - ], - [ - 'correct formula if metric is supported', - [METRIC_TYPES.AVG_BUCKET, metrics[1], metrics, undefined], - 'overall_average(average(test-field-1))', - ], - [ - 'correct formula if metric is positive only', - [TSVB_METRIC_TYPES.POSITIVE_ONLY, positiveOnlyMetrics[1], positiveOnlyMetrics, undefined], - 'pick_max(average(test-field-1), 0)', - ], - [ - 'correct formula if metric have additional sub function', - [METRIC_TYPES.AVG_BUCKET, metricsWithSubFunction[2], metricsWithSubFunction, undefined], - 'overall_average(overall_sum(average(test-field-1)))', - ], - ])('should return %s', (_, input, expected) => { - if (expected === null) { - expect(getSiblingPipelineSeriesFormula(...input)).toBeNull(); - } - expect(getSiblingPipelineSeriesFormula(...input)).toEqual(expected); - }); -}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts deleted file mode 100644 index 83730071f7baa..0000000000000 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/sibling_pipeline_formula.ts +++ /dev/null @@ -1,71 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { Metric, MetricType } from '../../../../common/types'; -import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; -import { getFormulaEquivalent } from './metrics_helpers'; - -export const getSiblingPipelineSeriesFormula = ( - aggregation: MetricType, - currentMetric: Metric, - metrics: Metric[], - reducedTimeRange?: string -) => { - const [nestedFieldId, nestedMeta] = currentMetric.field?.split('[') ?? []; - const subFunctionMetric = metrics.find((metric) => metric.id === nestedFieldId); - if (!subFunctionMetric || subFunctionMetric.type === 'static') { - return null; - } - const pipelineAggMap = SUPPORTED_METRICS[subFunctionMetric.type]; - if (!pipelineAggMap) { - return null; - } - const pipelineAggFormula = getFormulaFromMetric(pipelineAggMap); - - const aggregationMap = SUPPORTED_METRICS[aggregation]; - if (!aggregationMap) { - return null; - } - const aggFormula = getFormulaFromMetric(aggregationMap); - - const subMetricField = subFunctionMetric.type !== 'count' ? subFunctionMetric.field : ''; - // support nested aggs with formula - const additionalSubFunction = metrics.find((metric) => metric.id === subMetricField); - let formula = `${aggFormula}(`; - let minimumValue = ''; - if (currentMetric.type === 'positive_only') { - minimumValue = `, 0`; - } - if (additionalSubFunction) { - const additionalPipelineAggMap = SUPPORTED_METRICS[additionalSubFunction.type]; - if (!additionalPipelineAggMap) { - return null; - } - const additionalPipelineAggFormula = getFormulaFromMetric(additionalPipelineAggMap); - - const additionalSubFunctionField = - additionalSubFunction.type !== 'count' ? additionalSubFunction.field : ''; - formula += `${pipelineAggFormula}(${additionalPipelineAggFormula}(${ - additionalSubFunctionField ?? '' - }))${minimumValue})`; - } else { - const nestedMetaValue = Number(nestedMeta?.replace(']', '')); - - const subFormula = getFormulaEquivalent(subFunctionMetric, metrics, { - metaValue: nestedMetaValue, - reducedTimeRange, - }); - - if (!subFormula) { - return null; - } - - formula += `${subFormula}${minimumValue})`; - } - return formula; -}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts index 967702abbd88a..c0aa201de6837 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.ts @@ -13,7 +13,7 @@ import { Column, convertToFiltersColumn, convertToDateHistogramColumn, - converToTermsColumn, + convertToTermsColumn, } from '../convert'; import { getValidColumns } from './columns'; @@ -68,7 +68,7 @@ export const getBucketsColumns = ( return null; } - const termsColumn = converToTermsColumn( + const termsColumn = convertToTermsColumn( splitFields as [string, ...string[]], series, columns, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index 6cda563b6d85a..c3f5900b35eb3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { parseTimeShift } from '@kbn/data-plugin/common'; import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; import uuid from 'uuid'; import { Panel } from '../../../common/types'; @@ -46,6 +47,11 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model: Panel continue; } + // not valid time shift + if (series.offset_time && parseTimeShift(series.offset_time) === 'invalid') { + return null; + } + if (!isValidMetrics(series.metrics, PANEL_TYPES.TIMESERIES)) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts index 137f457bad307..1afbd89e7027f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -7,6 +7,7 @@ */ import uuid from 'uuid'; +import { parseTimeShift } from '@kbn/data-plugin/common'; import { Layer } from '@kbn/visualizations-plugin/common/convert_to_lens'; import { PANEL_TYPES } from '../../../common/enums'; import { getDataViewsStart } from '../../services'; @@ -38,6 +39,11 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR continue; } + // not valid time shift + if (series.offset_time && parseTimeShift(series.offset_time) === 'invalid') { + return null; + } + if (!isValidMetrics(series.metrics, PANEL_TYPES.TOP_N, series.time_range_mode)) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index bdafc6999772d..d91e801aec9d7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -25,3 +25,8 @@ export type ConvertToColumnsFn = ( { series: Series, metric: Metric, dataView: DataView }: CommonColumnConverterArgs, reducedTimeRange?: string ) => Array | null; + +export interface AdditionalFormulaArgs { + reducedTimeRange?: string; + timeShift?: string; +} diff --git a/src/plugins/visualizations/common/convert_to_lens/types/common.ts b/src/plugins/visualizations/common/convert_to_lens/types/common.ts index 91522da911b02..974326834ce2a 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/common.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/common.ts @@ -41,7 +41,7 @@ export interface Range { export interface NumberValueFormat { id: string; params?: { - decimals?: number; + decimals: number; suffix?: string; }; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index b7a41b1a3ad1f..64ae3e3b59d43 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -233,7 +233,8 @@ function getParams(column: Column) { function getIncompleteParams(column: Column) { return { filter: column.filter, - shift: column.timeShift, + timeShift: column.timeShift, + timeScale: column.timeScale, dataType: column.dataType, ...(column.reducedTimeRange && { reducedTimeRange: column.reducedTimeRange }), }; @@ -274,13 +275,29 @@ function convertToColumnChange(columns: Layer['columns'], indexPattern: IndexPat if ( isTermsColumn(column) && column.params.orderAgg && + newColumn.columnParams && !columns.some((c) => c.columnId === column.params.orderAgg?.columnId) ) { - const orderAggColumn: ColumnChange = createColumnChange( - column.params.orderAgg, - indexPattern + const orderColumn = column.params.orderAgg; + const operationDefinition = operationDefinitionMap[orderColumn.operationType]; + const layer: IndexPatternLayer = { + indexPatternId: indexPattern.id, + columns: {}, + columnOrder: [], + }; + newColumn.columnParams.orderAgg = operationDefinition.buildColumn( + { + previousColumn: { + ...column.params.orderAgg, + label: column.params.orderAgg?.label || '', + }, + indexPattern, + layer, + referenceIds: [], + field: getFieldWithLabel(column.params.orderAgg, indexPattern)!, + }, + column.params ); - acc.push(orderAggColumn); } acc.push(newColumn); } @@ -310,7 +327,7 @@ function createNewLayerWithMetricAggregationFromVizEditor( { previousColumn: { ...previousColumn, - label: previousColumn?.label || '', + label: previousColumn?.label || (column.columnParams?.formula as string) || '', }, indexPattern, layer: newLayer, @@ -329,7 +346,13 @@ function createNewLayerWithMetricAggregationFromVizEditor( }); let updatedLayer = newLayer; layer.columns.forEach(({ columnId, label: customLabel }) => { - updatedLayer = updateColumnLabel({ layer: updatedLayer, columnId, customLabel }); + if (customLabel) { + updatedLayer = updateColumnLabel({ + layer: updatedLayer, + columnId, + customLabel: isReferenced(updatedLayer, columnId) ? '' : customLabel, + }); + } }); return updatedLayer; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx index eec39bd530944..0427e40f24ac6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx @@ -235,6 +235,7 @@ export const termsOperation: OperationDefinition< columnId: existingMetricColumn, } : { type: 'alphabetical', fallback: true }), + orderAgg: columnParams?.orderBy.type === 'custom' ? columnParams?.orderAgg : undefined, orderDirection: columnParams?.orderDirection ?? (existingMetricColumn ? 'desc' : 'asc'), otherBucket: (columnParams?.otherBucket ?? true) && !indexPattern.hasRestrictions, missingBucket: columnParams?.missingBucket ?? false, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts index 8ff993da47474..30e3b89f8b6d3 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts @@ -214,6 +214,8 @@ const insertReferences = ({ op: operation.type, indexPattern, columnParams: { ...reference.columnParams }, + incompleteParams: reference.incompleteParams, + initialParams: reference.initialParams, ...(reference.references ? { references: reference.references } : {}), visualizationGroups, targetGroup, @@ -238,6 +240,8 @@ const insertReferences = ({ op: operation.type, indexPattern, field, + incompleteParams: reference.incompleteParams, + initialParams: reference.initialParams, columnParams: { ...reference.columnParams }, visualizationGroups, targetGroup, @@ -1282,7 +1286,7 @@ export function updateColumnLabel({ ...layer.columns, [columnId]: { ...oldColumn, - label: customLabel ? customLabel : oldColumn.label, + label: customLabel !== undefined ? customLabel : oldColumn.label, customLabel: Boolean(customLabel), }, } as Record, From 1e8ef4be42395a68ed14aa21139942cc9fed3a8e Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:17:28 +0000 Subject: [PATCH 121/129] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- .../lib/convert/parent_pipeline.ts | 2 +- .../lib/metrics/pipeline_formula.test.ts | 21 +++---------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index 3ba9dfcfb6763..eb2da2c229e22 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -33,7 +33,7 @@ import { getFormulaFromMetric, SupportedMetric, SUPPORTED_METRICS, - getPipelineSeriesFormula + getPipelineSeriesFormula, } from '../metrics'; import { createColumn, getFormat } from './column'; import { createFormulaColumn } from './formula'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.test.ts index 07af0740d648b..937523b13a5dc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/pipeline_formula.test.ts @@ -124,12 +124,7 @@ describe('getParentPipelineSeriesFormula', () => { >([ [ 'null if metric is not supported', - [ - metricsWithNotSupportedSubFunction[0], - metrics, - metrics[0], - {}, - ], + [metricsWithNotSupportedSubFunction[0], metrics, metrics[0], {}], null, ], [ @@ -144,22 +139,12 @@ describe('getParentPipelineSeriesFormula', () => { ], [ 'correct formula if metric is supported', - [ - metrics[1], - metrics, - metrics[0], - {}, - ], + [metrics[1], metrics, metrics[0], {}], 'moving_average(average(test-field-1), window=5)', ], [ 'correct formula if metric have additional sub function', - [ - metricsWithSubFunction[2], - metricsWithSubFunction, - metricsWithSubFunction[1], - {}, - ], + [metricsWithSubFunction[2], metricsWithSubFunction, metricsWithSubFunction[1], {}], 'moving_average(differences(average(test-field-1)), window=5)', ], [ From 9ca095bf33070dcb46728f86d0c911addda49dd0 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 12 Sep 2022 18:06:40 +0300 Subject: [PATCH 122/129] Fixed tests --- .../public/convert_to_lens/lib/convert/column.test.ts | 1 + .../convert_to_lens/lib/series/buckets_columns.test.ts | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts index 2194c977ecc4d..cd955b1702d9b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.test.ts @@ -68,6 +68,7 @@ describe('getFormat', () => { id: 'number', params: { suffix: 'd', + decimals: 2, }, }, }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts index cb2f02c7f3f70..edded777953af 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/buckets_columns.test.ts @@ -235,7 +235,7 @@ describe('getBucketsColumns', () => { params: {}, sourceField: 'document', }), - orderBy: expect.objectContaining({ type: 'column' }), + orderBy: expect.objectContaining({ type: 'custom' }), orderDirection: 'desc', otherBucket: false, parentFormat: { id: 'terms' }, @@ -248,8 +248,5 @@ describe('getBucketsColumns', () => { const params = result?.[0].params as TermsParams; expect(params.orderAgg).not.toBeNull(); expect(typeof params.orderAgg === 'object').toBeTruthy(); - expect(params.orderAgg?.columnId).toEqual( - (params.orderBy as { columnId: string; type: 'column' }).columnId - ); }); }); From c3a443cd3e41057da8b5cd662c09900683cf66c5 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 13 Sep 2022 12:00:54 +0300 Subject: [PATCH 123/129] Fixed cumulative sum by value count. --- .../public/convert_to_lens/lib/convert/cumulative_sum.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index 8733b100f9a95..dfa10d6c2b0af 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -31,7 +31,10 @@ export const convertToCumulativeSumColumns = ( let formula; // lens supports cumulative sum for count and sum as quick function // and everything else as formula - if (pipelineAgg.name !== 'count' && pipelineAgg.name !== 'sum') { + if ( + ((pipelineAgg.name === 'count' && subFunctionMetric.field) || pipelineAgg.name !== 'count') && + pipelineAgg.name !== 'sum' + ) { const metaValue = Number(meta?.replace(']', '')); formula = getPipelineSeriesFormula(metric, metrics, subFunctionMetric, { metaValue, From 89f694529dd7196088b3da09f0b7b607959982b6 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 13 Sep 2022 12:13:59 +0300 Subject: [PATCH 124/129] Fixed percentile and percentile ranks. --- .../public/convert_to_lens/lib/convert/column.ts | 9 +-------- .../public/convert_to_lens/lib/convert/index.ts | 2 +- .../lib/series/metrics_columns.test.ts | 16 ---------------- .../lib/series/metrics_columns.ts | 13 ++++++------- .../timeseries/public/convert_to_lens/types.ts | 6 ------ 5 files changed, 8 insertions(+), 38 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index f836b28f5c605..cdca75c24766c 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -17,9 +17,8 @@ import { import uuid from 'uuid'; import type { Metric, Series } from '../../../../common/types'; import { DATA_FORMATTERS } from '../../../../common/enums'; -import { ConvertToColumnsFn } from '../../types'; import { getTimeScale } from '../metrics'; -import { ColumnWithMeta, Meta, Column, CommonColumnsConverterArgs } from './types'; +import { ColumnWithMeta, Meta, Column } from './types'; type GeneralColumn = Omit, 'operationType' | 'params'>; type GeneralColumnWithMeta = GenericColumnWithMeta; @@ -70,12 +69,6 @@ export const createColumn = ( meta: { metricId: metric.id }, }); -export const convertMetricsToColumns = ( - { series, metrics, dataView }: CommonColumnsConverterArgs, - convertToFn: ConvertToColumnsFn, - reducedTimeRange?: string -) => metrics.flatMap((metric) => convertToFn({ series, metric, dataView }, reducedTimeRange)); - export const isColumnWithMeta = (column: Column): column is ColumnWithMeta => { if ((column as ColumnWithMeta).meta) { return true; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 84c7b32e10763..36f05c440bdc2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -export { convertMetricsToColumns, isColumnWithMeta, excludeMetaFromColumn } from './column'; +export { isColumnWithMeta, excludeMetaFromColumn } from './column'; export { convertToPercentileColumns, isPercentileColumnWithMeta } from './percentile'; export { convertToPercentileRankColumns, isPercentileRanksColumnWithMeta } from './percentile_rank'; export { convertMathToFormulaColumn, convertOtherAggsToFormulaColumn } from './formula'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts index 76a453e3d9f8a..5ca1fe71a0ada 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts @@ -12,7 +12,6 @@ import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { createSeries } from '../__mocks__'; import { getMetricsColumns } from './metrics_columns'; -const mockConvertMetricsToColumns = jest.fn(); const mockConvertMathToFormulaColumn = jest.fn(); const mockConvertParentPipelineAggToColumns = jest.fn(); const mockConvertToCumulativeSumColumns = jest.fn(); @@ -25,7 +24,6 @@ const mockConvertToStandartDeviationColumn = jest.fn(); const mockConvertMetricAggregationColumnWithoutSpecialParams = jest.fn(); jest.mock('../convert', () => ({ - convertMetricsToColumns: jest.fn(() => mockConvertMetricsToColumns()), convertMathToFormulaColumn: jest.fn(() => mockConvertMathToFormulaColumn()), convertParentPipelineAggToColumns: jest.fn(() => mockConvertParentPipelineAggToColumns()), convertToCumulativeSumColumns: jest.fn(() => mockConvertToCumulativeSumColumns()), @@ -67,20 +65,6 @@ describe('getMetricsColumns', () => { ], null, ], - [ - 'call convertMetricsToColumns if metric type is percentile', - [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.PERCENTILE, id: '1' }] }), dataView, 1], - mockConvertMetricsToColumns, - ], - [ - 'call convertMetricsToColumns if metric type is percentile rank', - [ - createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.PERCENTILE_RANK, id: '1' }] }), - dataView, - 1, - ], - mockConvertMetricsToColumns, - ], [ 'call convertMathToFormulaColumn if metric type is math', [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.MATH, id: '1' }] }), dataView, 1], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 822e5158effe7..eb33493bf78ba 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -12,7 +12,6 @@ import { getSeriesAgg } from './series_agg'; import { SUPPORTED_METRICS } from '../metrics'; import { Column, - convertMetricsToColumns, convertToPercentileColumns, convertToPercentileRankColumns, convertMathToFormulaColumn, @@ -56,19 +55,19 @@ export const getMetricsColumns = ( const columnsConverterArgs = { series, metrics, dataView }; switch (aggregation) { case 'percentile': { - const percentileColumns = convertMetricsToColumns( - columnsConverterArgs, - convertToPercentileColumns, + const percentileColumns = convertToPercentileColumns( + { series, metric: metrics[metricIdx], dataView }, reducedTimeRange ); + return getValidColumns(percentileColumns); } case 'percentile_rank': { - const percentileRankColumns = convertMetricsToColumns( - columnsConverterArgs, - convertToPercentileRankColumns, + const percentileRankColumns = convertToPercentileRankColumns( + { series, metric: metrics[metricIdx], dataView }, reducedTimeRange ); + return getValidColumns(percentileRankColumns); } case 'math': { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index d91e801aec9d7..d48c6d01a20dd 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -9,7 +9,6 @@ import { NavigateToLensContext, XYConfiguration } from '@kbn/visualizations-plugin/common'; import { TimeRange } from '@kbn/data-plugin/common'; import type { Panel } from '../../common/types'; -import { Column, CommonColumnConverterArgs } from './lib/convert'; export type ConvertTsvbToLensVisualization = ( model: Panel, @@ -21,11 +20,6 @@ export interface Filter { lucene?: string | { [key: string]: any } | undefined; } -export type ConvertToColumnsFn = ( - { series: Series, metric: Metric, dataView: DataView }: CommonColumnConverterArgs, - reducedTimeRange?: string -) => Array | null; - export interface AdditionalFormulaArgs { reducedTimeRange?: string; timeShift?: string; From cc3fcd8949024f0db951f689fa0e14336540a4a0 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 13 Sep 2022 12:43:46 +0300 Subject: [PATCH 125/129] Fixed tests. --- .../lib/convert/cumulative_sum.test.ts | 26 +++++++++++++++++-- .../lib/metrics/metrics_helpers.test.ts | 1 - .../lib/metrics/metrics_helpers.ts | 8 +++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts index 127d45d18c153..074827c97410f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts @@ -25,6 +25,12 @@ const subAggMetric: Metric = { type: METRIC_TYPES.AVG, field: dataView.fields[0].name, }; + +const countMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.COUNT, +}; + const notSupportedSubAggMetric: Metric = { id: 'some-random-value', type: METRIC_TYPES.MEDIAN, @@ -97,17 +103,33 @@ describe('convertToCumulativeSumColumns', () => { }, ], [ - 'columns with parent aggregation if submetric is count', + 'formula if submetric is count with field', [ { series, metrics: [ - { ...subAggMetric, type: METRIC_TYPES.COUNT }, + { ...countMetric, field: subAggMetric.field }, { ...metric, field: `${subAggMetric.id}[50]` }, ], dataView, }, ], + { + meta: { metricId: 'some-id' }, + operationType: 'formula', + params: { formula: 'cumulative_sum(count(bytes))' }, + }, + ], + + [ + 'columns with parent aggregation if submetric is count', + [ + { + series, + metrics: [countMetric, { ...metric, field: `${subAggMetric.id}[50]` }], + dataView, + }, + ], [ { operationType: 'count', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts index c793c9857bdee..447312786ee02 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.test.ts @@ -33,7 +33,6 @@ describe('getFormulaEquivalent', () => { const countMetric: Metric = { id: 'some-random-value', type: METRIC_TYPES.COUNT, - field: 'test-1', }; const staticValue: Metric = { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 374661609b86e..9df2a3004db90 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -118,7 +118,13 @@ export const getFormulaEquivalent = ( }); } case 'count': { - return `${aggFormula}(${timeShift ? `shift='${timeShift}'` : ''}${ + const field = currentMetric.field + ? timeShift || reducedTimeRange + ? `${currentMetric.field} ,` + : currentMetric.field + : ''; + + return `${aggFormula}(${field}${timeShift ? `shift='${timeShift}'` : ''}${ timeShift && reducedTimeRange ? ', ' : '' }${reducedTimeRange ? `reducedTimeRange='${reducedTimeRange}'` : ''})`; } From 018ea3cd709ffa4cff6bcfeb6b1f6f2620a5ed4d Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 13 Sep 2022 12:58:23 +0300 Subject: [PATCH 126/129] One more fix. --- .../lib/convert/cumulative_sum.test.ts | 12 ++++++++---- .../convert_to_lens/lib/convert/cumulative_sum.ts | 5 +---- .../convert_to_lens/lib/metrics/metrics_helpers.ts | 8 +------- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts index 074827c97410f..c578b2d4a2b48 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.test.ts @@ -26,9 +26,16 @@ const subAggMetric: Metric = { field: dataView.fields[0].name, }; +const countValueMetric: Metric = { + id: 'some-random-value', + type: METRIC_TYPES.VALUE_COUNT, + field: dataView.fields[0].name, +}; + const countMetric: Metric = { id: 'some-random-value', type: METRIC_TYPES.COUNT, + field: dataView.fields[0].name, }; const notSupportedSubAggMetric: Metric = { @@ -107,10 +114,7 @@ describe('convertToCumulativeSumColumns', () => { [ { series, - metrics: [ - { ...countMetric, field: subAggMetric.field }, - { ...metric, field: `${subAggMetric.id}[50]` }, - ], + metrics: [countValueMetric, { ...metric, field: `${subAggMetric.id}[50]` }], dataView, }, ], diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts index dfa10d6c2b0af..9a119016353a9 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/cumulative_sum.ts @@ -31,10 +31,7 @@ export const convertToCumulativeSumColumns = ( let formula; // lens supports cumulative sum for count and sum as quick function // and everything else as formula - if ( - ((pipelineAgg.name === 'count' && subFunctionMetric.field) || pipelineAgg.name !== 'count') && - pipelineAgg.name !== 'sum' - ) { + if (subFunctionMetric.type !== 'count' && pipelineAgg.name !== 'sum') { const metaValue = Number(meta?.replace(']', '')); formula = getPipelineSeriesFormula(metric, metrics, subFunctionMetric, { metaValue, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 9df2a3004db90..374661609b86e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -118,13 +118,7 @@ export const getFormulaEquivalent = ( }); } case 'count': { - const field = currentMetric.field - ? timeShift || reducedTimeRange - ? `${currentMetric.field} ,` - : currentMetric.field - : ''; - - return `${aggFormula}(${field}${timeShift ? `shift='${timeShift}'` : ''}${ + return `${aggFormula}(${timeShift ? `shift='${timeShift}'` : ''}${ timeShift && reducedTimeRange ? ', ' : '' }${reducedTimeRange ? `reducedTimeRange='${reducedTimeRange}'` : ''})`; } From 3743c4dc65dbfbeb206f274bc8a7eaf666a14b11 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 13 Sep 2022 13:16:54 +0300 Subject: [PATCH 127/129] Fixed timeShift --- .../convert_to_lens/lib/convert/column.ts | 5 +- .../lib/convert/counter_rate.ts | 2 +- .../convert_to_lens/lib/convert/formula.ts | 6 +- .../convert_to_lens/lib/convert/last_value.ts | 5 +- .../lib/convert/moving_average.test.ts | 2 +- .../lib/convert/moving_average.ts | 2 +- .../lib/convert/parent_pipeline.test.ts | 64 ++++++++++++------- .../lib/convert/parent_pipeline.ts | 8 +-- .../lib/convert/percentile.test.ts | 7 +- .../convert_to_lens/lib/convert/percentile.ts | 13 ++-- .../lib/convert/percentile_rank.test.ts | 13 ++-- .../lib/convert/percentile_rank.ts | 13 ++-- .../lib/convert/std_deviation.ts | 2 +- .../lib/metrics/counter_rate_formula.ts | 6 +- .../lib/metrics/filter_ratio_formula.test.ts | 4 +- .../lib/metrics/filter_ratio_formula.ts | 6 +- .../lib/metrics/metrics_helpers.ts | 4 +- .../lib/series/metrics_columns.ts | 6 +- .../public/convert_to_lens/types.ts | 2 +- 19 files changed, 103 insertions(+), 67 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts index cdca75c24766c..3bcd219f22676 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/column.ts @@ -26,6 +26,7 @@ interface ExtraColumnFields { isBucketed?: boolean; isSplit?: boolean; reducedTimeRange?: string; + timeShift?: string; } const isSupportedFormat = (format: string) => ['bytes', 'number', 'percent'].includes(format); @@ -55,7 +56,7 @@ export const createColumn = ( series: Series, metric: Metric, field?: DataViewField, - { isBucketed = false, isSplit = false, reducedTimeRange }: ExtraColumnFields = {} + { isBucketed = false, isSplit = false, reducedTimeRange, timeShift }: ExtraColumnFields = {} ): GeneralColumnWithMeta => ({ columnId: uuid(), dataType: (field?.type as DataType) ?? undefined, @@ -64,7 +65,7 @@ export const createColumn = ( isSplit, reducedTimeRange, filter: series.filter, - timeShift: series.offset_time, + timeShift, timeScale: getTimeScale(metric), meta: { metricId: metric.id }, }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts index aa64e478e99e0..b3035363a2e67 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/counter_rate.ts @@ -34,7 +34,7 @@ export const convertToCounterRateColumn = ({ { operationType: Operations.COUNTER_RATE, references: [maxColumn.columnId], - ...createColumn(series, metric, field), + ...createColumn(series, metric, field, { timeShift: series.offset_time }), params: { ...getFormat(series) }, }, ]; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts index d3f1f6e2640e6..730e770160ecd 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/formula.ts @@ -13,7 +13,7 @@ import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import type { Metric } from '../../../../common/types'; import { getFormulaEquivalent, getPipelineSeriesFormula } from '../metrics'; import { createColumn, getFormat } from './column'; -import { AdditionalFormulaArgs } from '../../types'; +import { AdditionalArgs } from '../../types'; type OtherFormulaAggregations = | typeof TSVB_METRIC_TYPES.POSITIVE_ONLY @@ -44,7 +44,7 @@ const convertFormulaScriptForPercentileAggs = ( variables: Exclude, metric: Metric, allAggMetrics: Metric[], - additionalArgs: AdditionalFormulaArgs + additionalArgs: AdditionalArgs ) => { variables.forEach((variable) => { const [_, meta] = variable?.field?.split('[') ?? []; @@ -66,7 +66,7 @@ const convertFormulaScriptForAggs = ( variables: Exclude, metric: Metric, allAggMetrics: Metric[], - additionalArgs: AdditionalFormulaArgs + additionalArgs: AdditionalArgs ) => { const script = getFormulaEquivalent(metric, allAggMetrics, { ...additionalArgs }); if (!script) { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts index e488a8d6fbfdb..74fa736f911d1 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/last_value.ts @@ -37,7 +37,10 @@ export const convertToLastValueColumn = ( return { operationType: 'last_value', sourceField: field.name ?? 'document', - ...createColumn(series, currentMetric, undefined, { reducedTimeRange }), + ...createColumn(series, currentMetric, undefined, { + reducedTimeRange, + timeShift: series.offset_time, + }), params: { ...convertToLastValueParams(currentMetric), ...getFormat(series), diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts index 8b4747175c553..36476ad8f8c3d 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.test.ts @@ -19,7 +19,7 @@ describe('convertToMovingAverageParams', () => { const window = 10; test.each<[string, Parameters, MovingAverageParams]>([ - ['params with default window if no window is specified in metric', [metric], { window: 0 }], + ['params with default window if no window is specified in metric', [metric], { window: 5 }], ['params with window', [{ ...metric, window }], { window }], ])('should return %s', (_, input, expected) => { expect(convertToMovingAverageParams(...input)).toEqual(expect.objectContaining(expected)); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts index 3b6491ac475ca..06fcc13e9d9d2 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/moving_average.ts @@ -10,5 +10,5 @@ import { MovingAverageParams } from '@kbn/visualizations-plugin/common/convert_t import { Metric } from '../../../../common/types'; export const convertToMovingAverageParams = ({ window }: Metric): MovingAverageParams => ({ - window: window ?? 0, + window: window ?? 5, }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts index 6defaba409741..e5a9561ceb81f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.test.ts @@ -35,11 +35,15 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { [SUPPORTED_METRICS.positive_rate.name, SUPPORTED_METRICS.positive_rate], ])('should return null for metric %s', (_, operation) => { expect( - convertMetricAggregationColumnWithoutSpecialParams(operation, { - series, - dataView, - metrics: [{ type: operation.name as MetricType, id: 'some-id' }], - }) + convertMetricAggregationColumnWithoutSpecialParams( + operation, + { + series, + dataView, + metrics: [{ type: operation.name as MetricType, id: 'some-id' }], + }, + {} + ) ).toBeNull(); }); @@ -52,11 +56,15 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { [SUPPORTED_METRICS.std_deviation.name, SUPPORTED_METRICS.std_deviation], ])('should return null for metric %s without valid field', (_, operation) => { expect( - convertMetricAggregationColumnWithoutSpecialParams(operation, { - series, - dataView, - metrics: [{ type: operation.name as MetricType, id: 'some-id' }], - }) + convertMetricAggregationColumnWithoutSpecialParams( + operation, + { + series, + dataView, + metrics: [{ type: operation.name as MetricType, id: 'some-id' }], + }, + {} + ) ).toBeNull(); }); @@ -73,11 +81,15 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { ], ])('should return column for metric %s without valid field', (_, operation, expected) => { expect( - convertMetricAggregationColumnWithoutSpecialParams(operation, { - series, - dataView, - metrics: [{ type: operation.name as MetricType, id: 'some-id' }], - }) + convertMetricAggregationColumnWithoutSpecialParams( + operation, + { + series, + dataView, + metrics: [{ type: operation.name as MetricType, id: 'some-id' }], + }, + {} + ) ).toEqual(expect.objectContaining(expected)); }); @@ -138,13 +150,17 @@ describe('convertMetricAggregationColumnWithoutSpecialParams', () => { ], ])('should return column for metric %s with valid field', (_, operation, expected) => { expect( - convertMetricAggregationColumnWithoutSpecialParams(operation, { - series, - dataView, - metrics: [ - { type: operation.name as MetricType, id: 'some-id', field: dataView.fields[0].name }, - ], - }) + convertMetricAggregationColumnWithoutSpecialParams( + operation, + { + series, + dataView, + metrics: [ + { type: operation.name as MetricType, id: 'some-id', field: dataView.fields[0].name }, + ], + }, + {} + ) ).toEqual(expect.objectContaining(expected)); }); }); @@ -403,7 +419,7 @@ describe('computeParentPipelineColumns', () => { { meta: { metricId: 'some-id' }, operationType: 'moving_average', - params: { window: 0 }, + params: { window: 5 }, }, ], ], @@ -569,7 +585,7 @@ describe('createParentPipelineAggregationColumn', () => { { meta: { metricId: 'some-id-0' }, operationType: 'moving_average', - params: { window: 0 }, + params: { window: 5 }, }, ], [ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts index eb2da2c229e22..522585c5c568a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/parent_pipeline.ts @@ -115,7 +115,7 @@ const isSupportedAggregationWithoutParams = ( export const convertMetricAggregationColumnWithoutSpecialParams = ( aggregation: SupportedMetric, { series, metrics, dataView }: CommonColumnsConverterArgs, - reducedTimeRange?: string + additionalArgs: { reducedTimeRange?: string; timeShift?: string } ): MetricAggregationColumnWithoutSpecialParams | null => { if (!isSupportedAggregationWithoutParams(aggregation.name)) { return null; @@ -131,7 +131,7 @@ export const convertMetricAggregationColumnWithoutSpecialParams = ( return { operationType: aggregation.name, sourceField, - ...createColumn(series, metric, field, { reducedTimeRange }), + ...createColumn(series, metric, field, additionalArgs), params: { ...getFormat(series) }, } as MetricAggregationColumnWithoutSpecialParams; }; @@ -167,7 +167,7 @@ export const convertMetricAggregationToColumn = ( return convertMetricAggregationColumnWithoutSpecialParams( aggregation, { series, metrics: [metric], dataView }, - reducedTimeRange + { reducedTimeRange } ); }; @@ -292,7 +292,7 @@ export const createParentPipelineAggregationColumn = ( return { operationType: aggregation, references, - ...createColumn(series, metric), + ...createColumn(series, metric, undefined, { timeShift: series.offset_time }), params, } as ParentPipelineAggColumn; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts index 7acd6b74231b2..885a2b16b44cc 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.test.ts @@ -147,7 +147,7 @@ describe('convertToPercentileColumns', () => { Array | null> | null ] >([ - ['null if values arr is empty', [{ series, metric, dataView }], null], + ['null if values arr is empty', [{ series, metric, dataView }, {}], null], [ 'array with null if values arr contains empty value', [ @@ -156,6 +156,7 @@ describe('convertToPercentileColumns', () => { metric: { ...metric, percentiles: [{ id: 'some-id', mode: 'line', value: undefined }] }, dataView, }, + {}, ], [null], ], @@ -170,6 +171,7 @@ describe('convertToPercentileColumns', () => { }, dataView, }, + {}, ], [null], ], @@ -185,6 +187,7 @@ describe('convertToPercentileColumns', () => { }, dataView, }, + {}, ], [ { @@ -207,7 +210,7 @@ describe('convertToPercentileColumns', () => { }, dataView, }, - '50m', + { reducedTimeRange: '50m' }, ], [ { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts index f008c87928194..163d42b976b3a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile.ts @@ -8,6 +8,7 @@ import { Operations, PercentileParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Percentile } from '../../../../common/types'; +import { AdditionalArgs } from '../../types'; import { createColumn, getFormat } from './column'; import { PercentileColumnWithExtendedMeta, @@ -32,7 +33,11 @@ export const convertToPercentileParams = (value?: string | number): PercentilePa export const convertToPercentileColumn = ( percentile: Percentile['value'], { series, metric, dataView }: CommonColumnConverterArgs, - { index, reducedTimeRange }: { index?: number; reducedTimeRange?: string } = {} + { + index, + reducedTimeRange, + timeShift, + }: { index?: number; reducedTimeRange?: string; timeShift?: string } = {} ): PercentileColumn | null => { const params = convertToPercentileParams(percentile); if (!params) { @@ -43,7 +48,7 @@ export const convertToPercentileColumn = ( if (!field) { return null; } - const commonColumnParams = createColumn(series, metric, field, { reducedTimeRange }); + const commonColumnParams = createColumn(series, metric, field, { reducedTimeRange, timeShift }); return { operationType: 'percentile', sourceField: field.name, @@ -61,7 +66,7 @@ export const convertToPercentileColumn = ( export const convertToPercentileColumns = ( columnConverterArgs: CommonColumnConverterArgs, - reducedTimeRange?: string + additionalArgs: AdditionalArgs ): Array | null => { const { percentiles } = columnConverterArgs.metric; @@ -70,6 +75,6 @@ export const convertToPercentileColumns = ( } return percentiles.map((p, index) => - convertToPercentileColumn(p.value, columnConverterArgs, { index, reducedTimeRange }) + convertToPercentileColumn(p.value, columnConverterArgs, { index, ...additionalArgs }) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts index 8f04252376545..25c047f8a19be 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.test.ts @@ -155,20 +155,23 @@ describe('convertToPercentileRankColumns', () => { Array | null> | null ] >([ - ['null if values arr is empty', [{ series, metric, dataView }], null], + ['null if values arr is empty', [{ series, metric, dataView }, {}], null], [ 'array with null if values arr contains empty value', - [{ series, metric: { ...metric, values: [undefined as unknown as string] }, dataView }], + [{ series, metric: { ...metric, values: [undefined as unknown as string] }, dataView }, {}], [null], ], [ 'array with null if values arr contains NaN value', - [{ series, metric: { ...metric, values: ['unvalid value'] }, dataView }], + [{ series, metric: { ...metric, values: ['unvalid value'] }, dataView }, {}], [null], ], [ 'percentile rank columns', - [{ series, metric: { ...metric, field: dataView.fields[0].name, values: ['75'] }, dataView }], + [ + { series, metric: { ...metric, field: dataView.fields[0].name, values: ['75'] }, dataView }, + {}, + ], [ { meta: { metricId: 'some-id', reference: 'some-id.0' }, @@ -182,7 +185,7 @@ describe('convertToPercentileRankColumns', () => { 'percentile rank columns with reducedTimeRange', [ { series, metric: { ...metric, field: dataView.fields[0].name, values: ['75'] }, dataView }, - '50m', + { reducedTimeRange: '50m' }, ], [ { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts index 9c2578d3ff0e3..31374067be7c0 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/percentile_rank.ts @@ -12,6 +12,7 @@ import { PercentileRanksParams, } from '@kbn/visualizations-plugin/common/convert_to_lens'; import type { Metric, Series } from '../../../../common/types'; +import { AdditionalArgs } from '../../types'; import { createColumn, getFormat } from './column'; import { PercentileRanksColumn, @@ -38,7 +39,11 @@ export const convertToPercentileRankColumn = ( series: Series, metric: Metric, dataView: DataView, - { index, reducedTimeRange }: { index?: number; reducedTimeRange?: string } = {} + { + index, + reducedTimeRange, + timeShift, + }: { index?: number; reducedTimeRange?: string; timeShift?: string } = {} ): PercentileRanksColumn | null => { const params = convertToPercentileRankParams(value); if (!params) { @@ -50,7 +55,7 @@ export const convertToPercentileRankColumn = ( return null; } - const commonColumnParams = createColumn(series, metric, field, { reducedTimeRange }); + const commonColumnParams = createColumn(series, metric, field, { reducedTimeRange, timeShift }); return { operationType: 'percentile_rank', sourceField: field.name, @@ -68,7 +73,7 @@ export const convertToPercentileRankColumn = ( export const convertToPercentileRankColumns = ( { series, metric, dataView }: CommonColumnConverterArgs, - reducedTimeRange?: string + additionalArgs: AdditionalArgs ): Array | null => { const { values } = metric; @@ -77,6 +82,6 @@ export const convertToPercentileRankColumns = ( } return values.map((p, index) => - convertToPercentileRankColumn(p, series, metric, dataView, { index, reducedTimeRange }) + convertToPercentileRankColumn(p, series, metric, dataView, { index, ...additionalArgs }) ); }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts index d2a18a5dee596..0882afcd7e3b4 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/std_deviation.ts @@ -60,7 +60,7 @@ export const convertToStandartDeviationColumn = ( convertMetricAggregationColumnWithoutSpecialParams( SUPPORTED_METRICS.std_deviation, { series, metrics: [metric], dataView }, - reducedTimeRange + { reducedTimeRange, timeShift: series.offset_time } ) ); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts index 78ca3981e4096..36be18592bfb7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/counter_rate_formula.ts @@ -7,9 +7,9 @@ */ import { addAdditionalArgs } from '.'; -import { AdditionalFormulaArgs } from '../../types'; +import { AdditionalArgs } from '../../types'; -const buildMaxFormula = (selector: string, additionalArgs: AdditionalFormulaArgs) => { +const buildMaxFormula = (selector: string, additionalArgs: AdditionalArgs) => { return `max(${selector}${addAdditionalArgs(additionalArgs)})`; }; @@ -20,7 +20,7 @@ const buildСounterRateFormula = (aggFormula: string, selector: string) => { export const buildCounterRateFormula = ( aggFormula: string, fieldName: string, - additionalArgs: AdditionalFormulaArgs + additionalArgs: AdditionalArgs ) => { const maxFormula = buildMaxFormula(fieldName, additionalArgs); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts index 652e6ecc22c26..ce00a09cc7c12 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.test.ts @@ -10,7 +10,7 @@ import { METRIC_TYPES } from '@kbn/data-plugin/public'; import type { Metric } from '../../../../common/types'; import { TSVB_METRIC_TYPES } from '../../../../common/enums'; import { getFilterRatioFormula } from './filter_ratio_formula'; -import { AdditionalFormulaArgs } from '../../types'; +import { AdditionalArgs } from '../../types'; describe('getFilterRatioFormula', () => { const metric: Metric = { @@ -33,7 +33,7 @@ describe('getFilterRatioFormula', () => { metric_agg: METRIC_TYPES.MEDIAN, }; - test.each<[string, [Metric, AdditionalFormulaArgs], string | null]>([ + test.each<[string, [Metric, AdditionalArgs], string | null]>([ ['null if metric_agg is not supported', [metricWithNotSupportedMetricAgg, {}], null], [ 'filter ratio formula if metric_agg is not specified', diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index 689ba3ca16d1e..4c9ec876089e7 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -10,7 +10,7 @@ import type { Query } from '@kbn/es-query'; import type { Metric, MetricType } from '../../../../common/types'; import { getFormulaFromMetric, SupportedMetric, SUPPORTED_METRICS } from './supported_metrics'; import { addAdditionalArgs } from '.'; -import { AdditionalFormulaArgs } from '../../types'; +import { AdditionalArgs } from '../../types'; const escapeQuotes = (str: string) => { return str?.replace(/'/g, "\\'"); @@ -19,7 +19,7 @@ const escapeQuotes = (str: string) => { const constructFilterRationFormula = ( operation: string, metric?: Query, - additionalArgs?: AdditionalFormulaArgs + additionalArgs?: AdditionalArgs ) => { return `${operation}${metric?.language === 'lucene' ? 'lucene' : 'kql'}='${ metric?.query && typeof metric?.query === 'string' @@ -30,7 +30,7 @@ const constructFilterRationFormula = ( export const getFilterRatioFormula = ( currentMetric: Metric, - additionalArgs: AdditionalFormulaArgs + additionalArgs: AdditionalArgs ) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts index 374661609b86e..eda3ec437fc8a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/metrics_helpers.ts @@ -18,7 +18,7 @@ import { getFilterRatioFormula } from './filter_ratio_formula'; import { getFormulaFromMetric, SUPPORTED_METRICS } from './supported_metrics'; import { buildCounterRateFormula } from './counter_rate_formula'; import { getPipelineSeriesFormula } from './pipeline_formula'; -import { AdditionalFormulaArgs } from '../../types'; +import { AdditionalArgs } from '../../types'; const shouldCalculateReducedTimeRange = (timeRangeMode?: string) => { return timeRangeMode === TIME_RANGE_DATA_MODES.LAST_VALUE; @@ -76,7 +76,7 @@ const addTimeShiftToFormula = (timeShift?: string) => { return timeShift ? `, shift='${timeShift}'` : ''; }; -export const addAdditionalArgs = ({ reducedTimeRange, timeShift }: AdditionalFormulaArgs) => { +export const addAdditionalArgs = ({ reducedTimeRange, timeShift }: AdditionalArgs) => { return `${addTimeShiftToFormula(timeShift)}${addTimeRangeToFormula(reducedTimeRange)}`; }; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index eb33493bf78ba..07294a3a61aaa 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -57,7 +57,7 @@ export const getMetricsColumns = ( case 'percentile': { const percentileColumns = convertToPercentileColumns( { series, metric: metrics[metricIdx], dataView }, - reducedTimeRange + { reducedTimeRange, timeShift: series.offset_time } ); return getValidColumns(percentileColumns); @@ -65,7 +65,7 @@ export const getMetricsColumns = ( case 'percentile_rank': { const percentileRankColumns = convertToPercentileRankColumns( { series, metric: metrics[metricIdx], dataView }, - reducedTimeRange + { reducedTimeRange, timeShift: series.offset_time } ); return getValidColumns(percentileRankColumns); @@ -131,7 +131,7 @@ export const getMetricsColumns = ( const column = convertMetricAggregationColumnWithoutSpecialParams( aggregationMap, columnsConverterArgs, - reducedTimeRange + { reducedTimeRange, timeShift: series.offset_time } ); return getValidColumns(column); } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index d48c6d01a20dd..acee3c2a1e83a 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -20,7 +20,7 @@ export interface Filter { lucene?: string | { [key: string]: any } | undefined; } -export interface AdditionalFormulaArgs { +export interface AdditionalArgs { reducedTimeRange?: string; timeShift?: string; } From a23795c8bc9c2c2927cfeb7a223b1d8c524155aa Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 13 Sep 2022 10:24:20 +0000 Subject: [PATCH 128/129] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- .../convert_to_lens/lib/metrics/filter_ratio_formula.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts index 4c9ec876089e7..bcbd80fc1a26b 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/filter_ratio_formula.ts @@ -28,10 +28,7 @@ const constructFilterRationFormula = ( }'${additionalArgs ? addAdditionalArgs(additionalArgs) : ''})`; }; -export const getFilterRatioFormula = ( - currentMetric: Metric, - additionalArgs: AdditionalArgs -) => { +export const getFilterRatioFormula = (currentMetric: Metric, additionalArgs: AdditionalArgs) => { // eslint-disable-next-line @typescript-eslint/naming-convention const { numerator, denominator, metric_agg, field } = currentMetric; let aggregation: SupportedMetric | null | undefined = SUPPORTED_METRICS.count; From 1625b3049539303cedf9fbfc37b06bebd76e021d Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 13 Sep 2022 16:17:22 +0300 Subject: [PATCH 129/129] Fixed getDataSourceInfo method --- .../convert_to_lens/lib/datasource/get_datasource_info.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts index 5e8bcb0416caa..8f7fbd3670f4e 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/datasource/get_datasource_info.ts @@ -40,10 +40,11 @@ export const getDataSourceInfo = async ( indexPattern = await dataViews.getDefault(); indexPatternId = indexPattern?.id ?? ''; timeField = indexPattern?.timeFieldName; - } - if (!timeField) { + } else { indexPattern = await dataViews.get(indexPatternId); - timeField = indexPattern.timeFieldName; + if (!timeField) { + timeField = indexPattern.timeFieldName; + } } return {